[drupal-devel] [bug] db_set_active problems

adrian drupal-devel at drupal.org
Sun Mar 27 04:21:46 UTC 2005


Issue status update for http://drupal.org/node/13115

 Project:      Drupal
 Version:      4.5.0
 Component:    database system
 Category:     bug reports
 Priority:     normal
-Assigned to:  Anonymous
+Assigned to:  adrian
 Reported by:  Anonymous
 Updated by:   adrian
 Status:       active

I've clarified the documentation in this patch :
http://drupal.org/node/19522
That's pretty much all that can be done in this case.


adrian



Previous comments:
------------------------------------------------------------------------

November 18, 2004 - 15:20 : Anonymous

If you use the db_set_active function to change to another database, and
then run a query that contains invalid syntax, watchdog module tries to
insert the error, but uses the currently active database, instead of
the drupal database.
The errors in error_log are along the lines of: 
[Thu Nov 18 09:30:51 2004] [error] PHP Fatal error:  Table
'someotherdb.watchdog' doesn't exist
query: INSERT INTO watchdog (uid, type, message, link, location,
hostname, timestamp) VALUES (2, 'error', 'user error: Unknown column
\'favourite\' in \'field list\'
query: --SNIP BAD QUERY-- in /var/www/httpd/includes/database.mysql.inc
on line 125.', '', '/addespy?awitem=26', '192.168.0.1', 1100770251) in
/var/www/httpd/includes/database.mysql.inc on line 125
[Thu Nov 18 09:30:51 2004] [error] PHP Fatal error:  Table
'someotherdb.sessions' doesn't exist
query: UPDATE sessions SET uid = 2, hostname = '192.168.0.1', session =
'messages|a:0:{}', timestamp = 1100770251 WHERE sid =
'428af456a2ec4610951275d551ab6f6a' in
/var/www/httpd/includes/database.mysql.inc on line 125
[Thu Nov 18 09:30:51 2004] [error] PHP Warning:  Unknown(): A session
is active. You cannot change the session module's ini settings at this
time. in Unknown on line 0


------------------------------------------------------------------------

November 18, 2004 - 15:35 : Anonymous

not sure if this is the way to fix it or if there are deeper issues
which need to be considered.
something along the lines of
database.inc add a function called db_get_active
then in the watchdog call the function before any logging to the drupal
database if the returned name != 'default' then remember what it was set
to, call db_get_active('default') then after the watchdog has logged
anything set the active database back to it's previous value.
Thanks,
Sil


------------------------------------------------------------------------

February 21, 2005 - 20:10 : yogadex

The problem is not exactly as you describe.  If you add some prints to
db_set_active, you'll see that the watchdog code is being called after
you've called db_set_active a second time, returning to the default
database.  (At least, you had better be doing that.  But you'll still
have the problem)
My thinking is the problem has to do with PHP references.  When you
call db_set_active('your_db'), it calls
// Set the active connection.
  $active_db = $db_conns[$name];
But at this point $active_db is a reference to the default database
connection.  Because of some nasty reference stuff, you''ve actually
changed the default database connection to connect to your_db!
Later, when you call db_set_active(), you don't really change anything!
For me, the quickest fix was to simply change the if statement near the
top of db_set_active...
// if (!isset($db_conns[$name])) {
  if (true) {
	// Initiate a new connection, using the named DB URL specified.
This way the code to create a new connection is always called, and
active_db always points where it should.  Of course you no longer are
cacheing connections, but the doc for mysql_connect states that it does
that for you.  And I'm using mysql so I'm not worried about it.
I tried an alternate fix, namely calling unset($active_db) before the
line that sets it.  That's supposed to get around the reference
funkyness, but then the db connections failed every time.  So for now
I'm sticking with the fix above.


------------------------------------------------------------------------

February 21, 2005 - 20:35 : yogadex

When I posted before I did not realize this was the bug report.  I
thought it was simply a forum post.  I'll add a little more info.  Also
I'd like to see the priority higher than 'minor'  doesn't anyone else
use more than one database?  (I'd submit a fix if I had one.  I tried
for a while but didn't come up with the right solution).
My version info is Drupal 4.5.2, php 4.3.10.
Here's my set_active_db with prints that helped me figure out what's
going on.  (Also I turned debugging on by default in db_query).
function db_set_active($name = 'default') {
  global $db_url, $db_type, $active_db;
  static $db_conns;
  print "<p>Setting active DB: $name</p>\n";
  if (!isset($db_conns[$name])) {
	// Initiate a new connection, using the named DB URL specified.
    if (is_array($db_url)) {
      $connect_url = array_key_exists($name, $db_url) ? $db_url[$name]
: $db_url['default'];
    }
    else {
      $connect_url = $db_url;
    }
    $db_type = substr($connect_url, 0, strpos($connect_url, '://'));
    // TODO: Allow more than one database API to be present.
    if ($db_type == 'mysql') {
      include_once 'includes/database.mysql.inc';
    }
    else {
      include_once 'includes/database.pgsql.inc';
    }
	print "<p>Connecting active DB: $connect_url</p>\n";
    $db_conns[$name] = db_connect($connect_url);
  }
  // Set the active connection.
  $active_db = $db_conns[$name];
  print "<p>Setting active DB: $active_db</p>\n";
  print "<p>db_cons[default]: {$db_conns['default']}</p>\n";
}
And by the way, thanks for what seems like a great product.  I have not
used it long.  I'm trying to figure out if I can convert my existing
site (www.yogadex.org) to Drupal.


------------------------------------------------------------------------

February 22, 2005 - 00:38 : yogadex

Ok, one more post...
There may be two problems here.  There may be a problem as described in
the first post.  That is, during a call to db_query on a secondary
database the watchdog code may be called.  That is, if there is an
error in the first sql statement, that problem may occur.
However, if there is no problem with the sql, the problem I describe
occurs.  Basically, it makes db_set_active unusable.  And therefore the
whole multiple database feature is broken, as far as I can tell.
-Dave


------------------------------------------------------------------------

March 27, 2005 - 01:45 : adrian

I use multiple database connections extensively. 
I set the default error handler to something else whenever I access my
other database.





More information about the drupal-devel mailing list