29 November 2011

Drupal Bootstrap Database

This is the 3rd article in the series covering DRUPAL v6 bootstrap process. As the bootstrap name implies, this phase covers initializing a connection to a database.

The phase begins by including 'database.inc', which is a database abstraction layer allowing developers to use different database servers with the same code base. One of the functions defined by this library is the db_set_active() function, which is invoked by the bootstrap database phase. This function is used to activate a database used by queries in later phases or during page building and rendering. The function begins by checking if the global variable $db_url is empty. Recall that in the phase #1 - DRUPAL_BOOTSTRAP_CONFIGURATION, this variable is set to the value specified in settings.php unless it is still set to the default string of 'mysql://username:password@localhost/databasename'. In that case, $db_url is simply set to empty string ''. This would indicate a first time installation, and as a result the 'install.inc' file would be included and user redirected to install.php.

Assuming installation had been previously completed, the function proceeds to set $db_conns associative array and initializes a connection to the database specified by the URL. It first determines the connection URL based on the named connection provided to the function as an argument. For the bootstrap phase, no argument is provided and consequently the named connection is set to 'default'. It is interesting to note that an array of connections can be defined in settings.php by defining $db_url as an associative array of key values where the keys are the named connections and the values are the connection URL's. This would be the case where multiple database servers are used to manage content for a site. Drupal expects one of the key values to be named 'default', however. The database type is then extracted from the URL and stored in $db_type global variable. For this example, you can assume that MYSQL is the specified type and therefore 'mysql' would be stored in the variable. Based on the type, the appropriate handler code is then included (again, for this example it would be 'database.mysql.inc'). This file contains the actual code to interface to the specified database.

A connection to the database is then initialized using the handler's db_connect() function using the URL as an argument. This function parses the URL into an array of components (i.e., scheme, host, username, password, and path). It then validates that the specified database type is supported by PHP. Finally, if the given URL contains URL-encoded info, it is then decoded.

A new connection is then opened using the parsed information previously extracted from the URL. If connection to the database was not successful, or if database name not present then Drupal redirects to an error page and terminates.

If everything was successful up until this point, utf8 character encoding support is enabled for this database connection. The connection resource type is then returned to db_set_active() to be assigned to $db_conns static associative array for the specified named connection ('default' for bootstrap phase). The $previous_name variable is set to the name of the previously active connection. In our case this is set to false as there is no previously active connection at this stage of the bootstrap process. The static $active_name is then set to the name of the current connection. Next the global $active_db variable is set with the current connection resource type identifier, which can then be used to execute various DB queries to handle the page request. Finally, the $previous_name variable is returned to the bootstrap function. This return value would be useful for situations where there was a pre-existing DB connection and one wanted to switch to another connection to perform certain actions and then restore the original one once completed. For the bootstrap phase, there shouldn't be a pre-existing connection and the return value is simply discarded.

Until next time.. Stay tuned!