Welcome Guest, Not a member yet? Register   Sign In
First time loading problems with dynamic database group
#1

I am developing a dymanic system for a client with multiple environments working with different stand-alone databases.

I have built a basic system where environments are stored in the database including database login information.
As soon as someone opens the website with a subdomain that matches an environment a filter is called via the routes that sets up the database data and stores it in the session of the database group.

In principle this works fine except when the page is loaded for the first time. Then you get the error:

"Unable to connect to the database.
Main connection [MySQLi]: Access denied for user ''@localhost' (using password: NO)"


So it seems that the filter that sets the sessions is executed only after the first database queries are run.

I have tried all sorts of things to solve this but so far have been unsuccessful.

Does anyone have an idea how I can make sure the session is set first before any query is run?
Once the database data is known to CodeIgniter.
Or is there a better way to build a system like this with dynamic database group?


This is the code from the database.php file in the app/config folder:
PHP Code:
/**
    * The environment database connection.
    *
    * @var array
    */
    public $environment = [];

    public function __construct()
    {
        parent::__construct();

        // Set environment DB
        $this->setEnvironmentDB();

        // Ensure that we always set the database group to 'tests' if
        // we are currently running an automated test suite, so that
        // we don't overwrite live data on accident.
        if (ENVIRONMENT === 'testing') {
            $this->defaultGroup 'tests';
        }
    }

    /**
    * Set the environment DB connection based on subdomain
    */
    public function setEnvironmentDB() {
        $this->environment = [
            'DSN'      => 'mysql:dbname=' session('dbN') . ';host=localhost',
            'hostname' => 'localhost',
            'username' => session('dbU'),
            'password' => session('dbP'),
            'database' => session('dbN'),
            'DBDriver' => 'MySQLi',
            'DBPrefix' => 'ck_',
            'pConnect' => false,
            'DBDebug'  => (ENVIRONMENT !== 'production'),
            'cacheOn'  => false,
            'cacheDir' => '',
            'charset'  => 'utf8',
            'DBCollat' => 'utf8_general_ci',
            'swapPre'  => '',
            'encrypt'  => false,
            'compress' => false,
            'strictOn' => false,
            'failover' => [],
            'port'    => 3306,
        ];
    

So the construct calls the function setEnvironmentDB that creates a database group environment with database data from the session.
That session data is put into a filter based on subdomain
Reply
#2

(11-01-2022, 09:50 AM)creativeking Wrote: Does anyone have an idea how I can make sure the session is set first before any query is run?
Once the database data is known to CodeIgniter.
Or is there a better way to build a system like this with dynamic database group?

Just make your system do call db query after initializing the session.

You don't need to set the DB config in the Config file.
https://codeigniter4.github.io/CodeIgnit...m-settings
Reply
#3

(This post was last modified: 11-10-2022, 12:56 AM by aprilgallegos.)

After your system has started up, all you have to do is initiate a call to the database and perform a query.
Reply
#4

(11-07-2022, 06:50 PM)kenjis Wrote:
(11-01-2022, 09:50 AM)creativeking Wrote: Does anyone have an idea how I can make sure the session is set first before any query is run?
Once the database data is known to CodeIgniter.
Or is there a better way to build a system like this with dynamic database group?

Just make your system do call db query after initializing the session.

You don't need to set the DB config in the Config file.
https://codeigniter4.github.io/CodeIgnit...m-settings

Very late response sorry. I had found some kind of temporary work-around using the .env file but came to the conclusion last days that it is not the long-term solution.

I am working on it again and what I have found so far is that as first the config/database.php file is called.

If the correct environment data is not readily available there it does not work. If you work from session data then it is not available the first request but the second request is available which makes it work fine.

I now work everywhere with:
PHP Code:
$model = new ReservationsModel(); 

and in the model I set the DBgroup:
PHP Code:
protected $DBGroup 'environment'


Requests I now do through the model capabilities such as:
PHP Code:
$model->findAll(); 


Then the dBgroup environment is used but so it is not set at the first request.

I have tried to change this in a number of ways:
- Using a filter on the route to populate the config/database.php environment group with the correct login credentials
- With a __construct() in the ReservationsModel() where I fill the environment group with the correct login data
- By overwriting the database connection in the __construct() of the ReservationsModel() with:

PHP Code:
$db Database::connect($custom);
                $this->db $db


But none of it works unfortunately.

Is there any way to set this up properly and still be able to use "$model = new ReservationsModel();"?

I know there is a possibility with:
PHP Code:
$model model('MembersModel'true$db); 

But I personally find that very tedious to work with.

So is there a possibility to fill the database group with login data after the config/database.php file has been called?
Or to create a custom database connection from the ReservationsModel() that will then be used?
Reply
#5

(03-13-2024, 08:16 AM)creativeking Wrote: - By overwriting the database connection in the __construct() of the ReservationsModel() with:

PHP Code:
$db Database::connect($custom);
                $this->db $db

That should work if the $custom is correct value. What was wrong with it?
Reply
#6

(03-13-2024, 04:50 PM)kenjis Wrote:
(03-13-2024, 08:16 AM)creativeking Wrote: - By overwriting the database connection in the __construct() of the ReservationsModel() with:

PHP Code:
$db Database::connect($custom);
                $this->db $db

That should work if the $custom is correct value. What was wrong with it?

The custom was correct and when I did a dump from db I saw that it contacted the database.

Only somehow the connection was not overwritten in the model.

If I call the variable "protected $DBGroup = 'environment';" in the model it still uses the "environment" database group from the config/database.php.

But if I remove the above variable then the default "default" database group is used.

So even if I put in the construct the $this->db variable with a custom connection it is completely ignored in the query below:
$model = new ReservationsModel();
$model->findAll();

As if any other way than the db variable is used to call the database.
Reply
#7

In my understanding, if you set $this->db in the constructor, the DB connection is used in the model.
I don't know why you cannot use the connection.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB