CodeIgniter Forums

Full Version: Bug in DSN connection.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]Claudiu CISMARU[/eluser]
I have reported a bug, regarding DSN, but seems that in the new version (1.5.4) there is no update. The problem still persists. Here is my message:
Quote:There is a bug in CI.
From DB.php:
Code:
if (is_string($params) AND strpos($params, '://') === FALSE)
        {
                include(APPPATH.'config/database'.EXT);
                
                $group = ($params == '') ? $active_group : $params;
                
                if ( ! isset($db[$group]))
                {
                        show_error('You have specified an invalid database connection group: '.$group);
                }                                                                                      

                $params = $db[$group];
        }
If there is no DSN, then $params will be loaded with the configuration of the database passed in database.php.

So, after this if, we have $params as a DSN string only, NOT AN ARRAY!. Next code:
Code:
if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
        {
                show_error('You have not selected a database type to connect to.');
        }
gives error if there is no dbdriver set! It's normal to NOT HAVE this index in $params, because $params it's an STRING! Anyway, PHP evaluates $params['dbdriver'] to $params[0], so we have $params['dbdriver'] to "p" (in case of postgre driver)! So, there is no error, yet.

I don't have active records activated, so the active records parts of code will be skipped. Anyway, setting AR to TRUE doesn't fix our error!

Next, the DB.php includes DB_driver.php, and there is the DSN parsed into the proper values, but it's just an include, so no code from it is executed!

Next, comes the line that generates our error (Message: require_once(/srv/www/vhosts/admitere/system/database/drivers/p/p_driver.php) [function.require-once]: failed to open stream: No such file or directory)
Code:
require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);

This, because as I said before, $params['dbdriver'] it's evaluated to "p", because $params it's a string!

The CI_DB_driver contains DSN parsing (there is a bug there, too: not retrieving scheme index from parse_url ()), but I don't know when it is called.

Quick FIX: Add the following code immediately after } close of the first if (the DSN check) (in DB.php):
Code:
/*
          HACK: Add proper DSN support
          By: Claudiu Cismaru (claudiu AT cnixs DOT com)
        */
        else {
                $parsedURL = parse_url ($params);
                
                $params = array ();
                $params["dbdriver"] = $parsedURL["scheme"];
                $params["hostname"] = (! isset ($parsedURL['host'])) ? '' : rawurldecode ($parsedURL['host']);
                $params["username"] = (! isset ($parsedURL['user'])) ? '' : rawurldecode ($parsedURL['user']);
                $params["password"] = (! isset ($parsedURL['pass'])) ? '' : rawurldecode ($parsedURL['pass']);
                $params["database"] = (! isset ($parsedURL['path'])) ? '' : rawurldecode (substr ($parsedURL['path'], 1));
        }

and VOILA! We have DSN working!

El Forum

[eluser]Henrik Pejer[/eluser]
Hmm... reading the user guide, it states that you can use dsn, but it should then be a parameter when you use $this->load->database ( check http://ellislab.com/codeigniter/user-gui...cting.html ). And the db-config is supposed to be an array.

My suggestion would be: either use the database config as an array, or supply your dsn when you load the database manually.

I would not consider this a bug, check the user guide. One could, however, argue if it should be possible to have a dsn in the config.

Why not extend the database class to accept a dsn from the config?

Good luck!

El Forum

[eluser]Claudiu CISMARU[/eluser]
[quote author="Henrik Pejer" date="1187090471"]My suggestion would be: either use the database config as an array, or supply your dsn when you load the database manually.[/quote]
Why don't you try and see what is happening, when you use DSN in manually database load...

The code that gave me error first time when I wrote it, and I started to checkout why is happening is:
Code:
/* Connect to the database */
      $currentFac = $this->data["session"]["current"];
      $dbFac = $this->data["config"]["$currentFac"]["db"];

      $dsn = sprintf ($this->admConfig["dsnTemplate"], $dbFac);

      $res = $this->load->database ($dsn);
Where, dsnTemplate is:
Code:
$admConfig["dsnTemplate"] = "postgre://user:[email protected]/%s";

Well? Why don't you try by yourself and reply again...

El Forum

[eluser]Henrik Pejer[/eluser]
Thats very strange! I was sure that I'd use DSN-type strings with CI and it worked perfectly!

I owe you an apology.

El Forum

[eluser]Claudiu CISMARU[/eluser]
NP Smile

Anyway, CI RULEZ! Smile

El Forum

[eluser]Claudiu CISMARU[/eluser]
Bug fixed in 1.6.1