summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2010-04-11 17:16:45 +0000
committerDries Buytaert <dries@buytaert.net>2010-04-11 17:16:45 +0000
commitde33f74b4040cc3f7880269152b277d90b081cc8 (patch)
tree63bb72c64d10cb48d549df7f0d9b817df0c0c8eb /includes
parentb647348fa93e7915d9a19dc2f1fd598422dca999 (diff)
downloadbrdo-de33f74b4040cc3f7880269152b277d90b081cc8.tar.gz
brdo-de33f74b4040cc3f7880269152b277d90b081cc8.tar.bz2
- Patch #688704 by Crell, boombatower, noahb: give DB its own autoload function.
Diffstat (limited to 'includes')
-rw-r--r--includes/bootstrap.inc5
-rw-r--r--includes/cache-install.inc3
-rw-r--r--includes/database/database.inc71
-rw-r--r--includes/install.core.inc3
-rw-r--r--includes/install.inc31
-rw-r--r--includes/theme.maintenance.inc1
-rw-r--r--includes/update.inc3
7 files changed, 78 insertions, 39 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index d2c739aab..b64febca3 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -1947,6 +1947,10 @@ function _drupal_bootstrap_database() {
Database::setLoggingCallback('watchdog', WATCHDOG_NOTICE, WATCHDOG_ERROR);
// Register autoload functions so that we can access classes and interfaces.
+ // The database autoload routine comes first so that we can load the database
+ // system without hitting the database. That is especially important during
+ // the install or upgrade process.
+ spl_autoload_register('db_autoload');
spl_autoload_register('drupal_autoload_class');
spl_autoload_register('drupal_autoload_interface');
}
@@ -2381,7 +2385,6 @@ function drupal_autoload_class($class) {
*/
function _registry_check_code($type, $name = NULL) {
static $lookup_cache, $cache_update_needed;
-
if ($type == 'class' && class_exists($name) || $type == 'interface' && interface_exists($name)) {
return TRUE;
}
diff --git a/includes/cache-install.inc b/includes/cache-install.inc
index e0772bea7..3a754e55f 100644
--- a/includes/cache-install.inc
+++ b/includes/cache-install.inc
@@ -41,8 +41,7 @@ class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterfac
// subtle bugs, some of which would not be fixed unless the site
// administrator cleared the cache manually.
try {
- if (function_exists('drupal_install_initialize_database')) {
- drupal_install_initialize_database();
+ if (class_exists('Database')) {
parent::clear($cid, $wildcard);
}
}
diff --git a/includes/database/database.inc b/includes/database/database.inc
index 933a52819..20a312886 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -761,7 +761,9 @@ abstract class DatabaseConnection extends PDO {
public function schema() {
if (empty($this->schema)) {
$class = $this->getDriverClass('DatabaseSchema');
- $this->schema = new $class($this);
+ if (class_exists($class)) {
+ $this->schema = new $class($this);
+ }
}
return $this->schema;
}
@@ -2109,6 +2111,73 @@ class DatabaseStatementEmpty implements Iterator, DatabaseStatementInterface {
}
}
+/**
+ * Autoload callback for the database system.
+ */
+function db_autoload($class) {
+ static $base_path = '';
+ static $checked = array();
+
+ static $files = array(
+ 'query.inc' => array(
+ 'QueryPlaceholderInterface',
+ 'QueryConditionInterface', 'DatabaseCondition',
+ 'Query', 'DeleteQuery', 'InsertQuery', 'UpdateQuery', 'MergeQuery', 'TruncateQuery',
+ 'QueryAlterableInterface',
+ ),
+ 'select.inc' => array('QueryAlterableInterface', 'SelectQueryInterface', 'SelectQuery', 'SelectQueryExtender'),
+ 'database.inc' => array('DatabaseConnection'),
+ 'log.inc' => array('DatabaseLog'),
+ 'prefetch.inc' => array('DatabaseStatementPrefetch'),
+ 'schema.inc' => array('DatabaseSchema'),
+ );
+
+ // If a class doesn't exist, it may get checked a second time
+ // by class_exists(). If so, just bail out now.
+ if (isset($checked[$class])) {
+ return;
+ }
+ $checked[$class] = TRUE;
+
+ if (empty($base_path)) {
+ $base_path = dirname(realpath(__FILE__));
+ }
+
+ // If there is an underscore in the class name, we know it's a
+ // driver-specific file so check for those. If not, it's a generic.
+ // Note that we use require_once here instead of require because of a
+ // quirk in class_exists(). By default, class_exists() will try to
+ // autoload a class if it's not found. However, we cannot tell
+ // at this point whether or not the class is going to exist, only
+ // the file that it would be in if it does exist. That means we may
+ // try to include a file that was already included by another
+ // autoload call, which would break. Using require_once() neatly
+ // avoids that issue.
+ if (strpos($class, '_') !== FALSE) {
+ list($base, $driver) = explode('_', $class);
+
+ // Drivers have an extra file, and may put their SelectQuery implementation
+ // in the main query file since it's so small.
+ $driver_files = $files;
+ $driver_files['query.inc'][] = 'SelectQuery';
+ $driver_files['install.inc'] = array('DatabaseTasks');
+
+ foreach ($driver_files as $file => $classes) {
+ if (in_array($base, $classes)) {
+ require_once "{$base_path}/{$driver}/{$file}";
+ return;
+ }
+ }
+ }
+ else {
+ foreach ($files as $file => $classes) {
+ if (in_array($class, $classes)) {
+ require_once $base_path . '/' . $file;
+ return;
+ }
+ }
+ }
+}
/**
* The following utility functions are simply convenience wrappers.
diff --git a/includes/install.core.inc b/includes/install.core.inc
index 8f626f677..2ddcac495 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -278,6 +278,7 @@ function install_begin_request(&$install_state) {
// Initialize the database system. Note that the connection
// won't be initialized until it is actually requested.
require_once DRUPAL_ROOT . '/includes/database/database.inc';
+ spl_autoload_register('db_autoload');
// Verify the last completed task in the database, if there is one.
$task = install_verify_completed_task();
@@ -350,7 +351,6 @@ function install_run_tasks(&$install_state) {
$install_state['tasks_performed'][] = $task_name;
$install_state['installation_finished'] = empty($tasks_to_perform);
if ($install_state['database_tables_exist'] && ($task['run'] == INSTALL_TASK_RUN_IF_NOT_COMPLETED || $install_state['installation_finished'])) {
- drupal_install_initialize_database();
variable_set('install_task', $install_state['installation_finished'] ? 'done' : $task_name);
}
}
@@ -1325,7 +1325,6 @@ function install_load_profile(&$install_state) {
function install_bootstrap_full(&$install_state) {
// Bootstrap newly installed Drupal, while preserving existing messages.
$messages = isset($_SESSION['messages']) ? $_SESSION['messages'] : '';
- drupal_install_initialize_database();
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$_SESSION['messages'] = $messages;
diff --git a/includes/install.inc b/includes/install.inc
index 9af6644e0..c134e676a 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -219,20 +219,14 @@ function drupal_detect_baseurl($file = 'install.php') {
function drupal_detect_database_types() {
$databases = array();
- // Initialize the database system if it has not been
- // initialized yet. We do not initialize it earlier to make
- // requirements check during the installation.
- require_once DRUPAL_ROOT . '/includes/database/database.inc';
-
// We define a driver as a directory in /includes/database that in turn
// contains a database.inc file. That allows us to drop in additional drivers
// without modifying the installer.
// Because we have no registry yet, we need to also include the install.inc
// file for the driver explicitly.
require_once DRUPAL_ROOT . '/includes/database/database.inc';
+ spl_autoload_register('db_autoload');
foreach (file_scan_directory(DRUPAL_ROOT . '/includes/database', '/^[a-z]*$/i', array('recurse' => FALSE)) as $file) {
- include_once "{$file->uri}/install.inc";
- include_once "{$file->uri}/database.inc";
$drivers[$file->filename] = $file->uri;
}
@@ -547,28 +541,6 @@ function drupal_verify_profile($install_state) {
}
/**
- * Manually include all files for the active database.
- *
- * Because we have no registry yet, we need to manually include the
- * necessary database include files.
- */
-function drupal_install_initialize_database() {
- static $included = FALSE;
-
- if (!$included) {
- $connection_info = Database::getConnectionInfo();
- $driver = $connection_info['default']['driver'];
- require_once DRUPAL_ROOT . '/includes/database/query.inc';
- require_once DRUPAL_ROOT . '/includes/database/select.inc';
- require_once DRUPAL_ROOT . '/includes/database/schema.inc';
- foreach (glob(DRUPAL_ROOT . '/includes/database/' . $driver . '/*.inc') as $include_file) {
- require_once $include_file;
- }
- $included = TRUE;
- }
-}
-
-/**
* Callback to install the system module.
*
* Separated from the installation of other modules so core system
@@ -577,7 +549,6 @@ function drupal_install_initialize_database() {
function drupal_install_system() {
$system_path = dirname(drupal_get_filename('module', 'system', NULL));
require_once DRUPAL_ROOT . '/' . $system_path . '/system.install';
- drupal_install_initialize_database();
module_invoke('system', 'install');
$system_versions = drupal_get_schema_versions('system');
diff --git a/includes/theme.maintenance.inc b/includes/theme.maintenance.inc
index 1bfffa7ad..c19dd05db 100644
--- a/includes/theme.maintenance.inc
+++ b/includes/theme.maintenance.inc
@@ -39,6 +39,7 @@ function _drupal_maintenance_theme() {
// Because we are operating in a crippled environment, we need to
// bootstrap just enough to allow hook invocations to work.
require_once DRUPAL_ROOT . '/includes/database/database.inc';
+ spl_autoload_register('db_autoload');
$module_list['system']['filename'] = 'modules/system/system.module';
module_list(TRUE, FALSE, FALSE, $module_list);
drupal_load('module', 'system');
diff --git a/includes/update.inc b/includes/update.inc
index 794710513..51806a3d1 100644
--- a/includes/update.inc
+++ b/includes/update.inc
@@ -102,9 +102,6 @@ function update_prepare_d7_bootstrap() {
// Allow the database system to work even if the registry has not been
// created yet.
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
- drupal_install_initialize_database();
- spl_autoload_unregister('drupal_autoload_class');
- spl_autoload_unregister('drupal_autoload_interface');
// The new cache_bootstrap bin is required to bootstrap to
// DRUPAL_BOOTSTRAP_SESSION, so create it here rather than in