diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-04-11 17:16:45 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-04-11 17:16:45 +0000 |
commit | de33f74b4040cc3f7880269152b277d90b081cc8 (patch) | |
tree | 63bb72c64d10cb48d549df7f0d9b817df0c0c8eb /includes | |
parent | b647348fa93e7915d9a19dc2f1fd598422dca999 (diff) | |
download | brdo-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.inc | 5 | ||||
-rw-r--r-- | includes/cache-install.inc | 3 | ||||
-rw-r--r-- | includes/database/database.inc | 71 | ||||
-rw-r--r-- | includes/install.core.inc | 3 | ||||
-rw-r--r-- | includes/install.inc | 31 | ||||
-rw-r--r-- | includes/theme.maintenance.inc | 1 | ||||
-rw-r--r-- | includes/update.inc | 3 |
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 |