Closed FoTo50 closed 2 years ago
@laoneo It seems this comes from refactoring and db injection. Could you have a look? Thanks in advance.
How did you set the specific database in 4.1 in the jOpenSim model?
During __construct() I set it through a helper with
$this->gridDB = $this->opensim->getGridDB()
later in the method getListQuery() I fetch the query object as
$query = $this->gridDB->getQuery(true);
but without the previous mentioned line before it, in 4.2.0 the query object still is trying to find the table in the Joomla database, while in 4.1.5 and previous it worked fine that way.
Do you have some kind of stack trace, because when you work on the query it should not have any kind of reference to the model which has the other database.
Maybe I should also mention, that same model also needs to deal with some component tables in the Joomla DB.
But these methods all use the "regular" way with
$db = Factory::getDBO();
$query = $db->getQuery(true);
and are not called at the moment when the view wants to initially display the external data for an overview
We need to figure out where the access to the default table is done in the model to identify the root cause of the issue. For that I need to see where exactly the error happens. Do you have the source of the model publicly available?
Well, more or less (semi public hehe). The latest RC of my component is https://jopensim.com/jopensim4/nightly/com_opensim.0.4.0.4_RC6.2022-08-10-13-55-21.zip where the 2 admin models for this case can be found in \administrator\components\com_opensim\src\Model\ (UsersModel.php and RegionsModel.php) ... in there still unchanged and working only in <= 4.1.5
FYI: I temporary changed the method getDatabase() from the basic abstract class DatabaseDriver for debugging and it surprisingly still returned the correct external database name right before and after calling getListQuery().
I suspect something with the actual ->getQuery() where it returns to parent when created with some - maybe now required - missing parameter ( ... maybe is this $options['factory'] ?)
BTW: the object for the external db is found in \administrator\components\com_opensim\src\Extension\jOpenSimGridDB.php
Had a look on the code and you don't pass your own db object into the base class, either through the config array or setDbo. How should the base class, in your case ListModel, know what for a database to use? Relying only on overriding getDbo is error prone as the base class works on a different variable, before it was _db and now the one from the trait.
Not sure how to understand (but sure willing to do so)
jOpenSimGridDB.php is created with the config ($options) array that way ... the object contains the external connection and works, even in 4.2.0
The model does not use the static Factory::getDbo method for getListQuery, but it's own to get the external object from jOpenSimGridDB.php to create the query object for it.
This even now in 4.2.0 works in models extended from e.g. AdminModel, but not from ListModel ... and there only in the method getListQuery()
Can you please test the pr #https://github.com/joomla/joomla-cms/pull/38506. I'v illustrated there how you can do it better without storing the db in your own variable.
Closing this now that we have a pull request.
Steps to reproduce the issue
I'm having a model in my component (jOpenSim) extended from ListModel but with an external database as db object (in my case extended from MysqliDriver).
After upgrading to 4.2.0 the method getListQuery() wants to find the (obviously not existing) tables in the Joomla DB for listing
Expected result
List of items of external database table
Actual result
Error message like "42S02, 1146, Table 'nameofJoomlaDB.externalTableName' doesn't exist"
System information (as much as possible)
running both (Joomla and external) on MariaDB 10.5.16 Switching Joomla DB from Mysqli to MySQL PDO didnt have any affect.
Additional comments
A "quickfix" for me was currently to add directly as first line in the method getListQuery():
if(method_exists($this,"setDatabase")) $this->setDatabase($externalDatabaseObject);
right before getting the query object.The
if(method_exists($this,"setDatabase"))...
was required to avoid the error "Call to undefined method ..::setDatabase()" in 4.1.5