Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
d7a63ff9
Commit
d7a63ff9
authored
Nov 27, 2010
by
Dries
Browse files
- Patch
#851136
by Damien Tournoud, Crell, chx: make the database autoloading more robust.
parent
84c72d06
Changes
8
Hide whitespace changes
Inline
Side-by-side
includes/bootstrap.inc
View file @
d7a63ff9
...
...
@@ -2244,7 +2244,6 @@ function _drupal_bootstrap_database() {
// 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'
);
}
...
...
includes/database/database.inc
View file @
d7a63ff9
...
...
@@ -648,13 +648,20 @@ protected function expandArguments(&$query, &$args) {
*
* @param string $class
* The class for which we want the potentially driver-specific class.
* @param array $files
* The name of the files in which the driver-specific class can be.
* @param $use_autoload
* If TRUE, attempt to load classes using PHP's autoload capability
* as well as the manual approach here.
* @return string
* The name of the class that should be used for this driver.
*/
public
function
getDriverClass
(
$class
)
{
public
function
getDriverClass
(
$class
,
array
$files
=
array
(),
$use_autoload
=
FALSE
)
{
if
(
empty
(
$this
->
driverClasses
[
$class
]))
{
$this
->
driverClasses
[
$class
]
=
$class
.
'_'
.
$this
->
driver
();
if
(
!
class_exists
(
$this
->
driverClasses
[
$class
]))
{
$driver
=
$this
->
driver
();
$this
->
driverClasses
[
$class
]
=
$class
.
'_'
.
$driver
;
Database
::
loadDriverFile
(
$driver
,
$files
);
if
(
!
class_exists
(
$this
->
driverClasses
[
$class
],
$use_autoload
))
{
$this
->
driverClasses
[
$class
]
=
$class
;
}
}
...
...
@@ -681,7 +688,7 @@ public function getDriverClass($class) {
* @see SelectQuery
*/
public
function
select
(
$table
,
$alias
=
NULL
,
array
$options
=
array
())
{
$class
=
$this
->
getDriverClass
(
'SelectQuery'
);
$class
=
$this
->
getDriverClass
(
'SelectQuery'
,
array
(
'query.inc'
,
'select.inc'
)
);
return
new
$class
(
$table
,
$alias
,
$this
,
$options
);
}
...
...
@@ -697,7 +704,7 @@ public function select($table, $alias = NULL, array $options = array()) {
* @see InsertQuery
*/
public
function
insert
(
$table
,
array
$options
=
array
())
{
$class
=
$this
->
getDriverClass
(
'InsertQuery'
);
$class
=
$this
->
getDriverClass
(
'InsertQuery'
,
array
(
'query.inc'
)
);
return
new
$class
(
$this
,
$table
,
$options
);
}
...
...
@@ -713,7 +720,7 @@ public function insert($table, array $options = array()) {
* @see MergeQuery
*/
public
function
merge
(
$table
,
array
$options
=
array
())
{
$class
=
$this
->
getDriverClass
(
'MergeQuery'
);
$class
=
$this
->
getDriverClass
(
'MergeQuery'
,
array
(
'query.inc'
)
);
return
new
$class
(
$this
,
$table
,
$options
);
}
...
...
@@ -730,7 +737,7 @@ public function merge($table, array $options = array()) {
* @see UpdateQuery
*/
public
function
update
(
$table
,
array
$options
=
array
())
{
$class
=
$this
->
getDriverClass
(
'UpdateQuery'
);
$class
=
$this
->
getDriverClass
(
'UpdateQuery'
,
array
(
'query.inc'
)
);
return
new
$class
(
$this
,
$table
,
$options
);
}
...
...
@@ -746,7 +753,7 @@ public function update($table, array $options = array()) {
* @see DeleteQuery
*/
public
function
delete
(
$table
,
array
$options
=
array
())
{
$class
=
$this
->
getDriverClass
(
'DeleteQuery'
);
$class
=
$this
->
getDriverClass
(
'DeleteQuery'
,
array
(
'query.inc'
)
);
return
new
$class
(
$this
,
$table
,
$options
);
}
...
...
@@ -762,7 +769,7 @@ public function delete($table, array $options = array()) {
* @see TruncateQuery
*/
public
function
truncate
(
$table
,
array
$options
=
array
())
{
$class
=
$this
->
getDriverClass
(
'TruncateQuery'
);
$class
=
$this
->
getDriverClass
(
'TruncateQuery'
,
array
(
'query.inc'
)
);
return
new
$class
(
$this
,
$table
,
$options
);
}
...
...
@@ -776,7 +783,7 @@ public function truncate($table, array $options = array()) {
*/
public
function
schema
()
{
if
(
empty
(
$this
->
schema
))
{
$class
=
$this
->
getDriverClass
(
'DatabaseSchema'
);
$class
=
$this
->
getDriverClass
(
'DatabaseSchema'
,
array
(
'schema.inc'
)
);
if
(
class_exists
(
$class
))
{
$this
->
schema
=
new
$class
(
$this
);
}
...
...
@@ -1581,6 +1588,34 @@ public static function ignoreTarget($key, $target) {
self
::
$ignoreTargets
[
$key
][
$target
]
=
TRUE
;
}
/**
* Load a file for the database that might hold a class.
*
* @param $driver
* The name of the driver.
* @param array $files
* The name of the files the driver specific class can be.
*/
public
static
function
loadDriverFile
(
$driver
,
array
$files
=
array
())
{
static
$base_path
;
if
(
empty
(
$base_path
))
{
$base_path
=
dirname
(
realpath
(
__FILE__
));
}
$driver_base_path
=
"
$base_path
/
$driver
"
;
foreach
(
$files
as
$file
)
{
// Load the base file first so that classes extending base classes will
// have the base class loaded.
foreach
(
array
(
"
$base_path
/
$file
"
,
"
$driver_base_path
/
$file
"
)
as
$filename
)
{
// The OS caches file_exists() and PHP caches require_once(), so
// we'll let both of those take care of performance here.
if
(
file_exists
(
$filename
))
{
require_once
$filename
;
}
}
}
}
}
/**
...
...
@@ -2108,82 +2143,6 @@ public function valid() {
}
}
/**
* 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
))
{
$filename
=
"
{
$base_path
}
/
{
$driver
}
/
{
$file
}
"
;
// We might end up looking in a file that doesn't exist, so check that.
if
(
file_exists
(
$filename
))
{
require_once
$filename
;
// If the class now exists, we're done. Otherwise keep searching in
// additional files.
if
(
class_exists
(
$class
,
FALSE
)
||
interface_exists
(
$class
,
FALSE
))
{
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.
*
...
...
@@ -2915,4 +2874,3 @@ function db_ignore_slave() {
$_SESSION
[
'ignore_slave_server'
]
=
REQUEST_TIME
+
$duration
;
}
}
includes/database/schema.inc
View file @
d7a63ff9
...
...
@@ -6,6 +6,8 @@
* Generic Database schema code.
*/
require_once
dirname
(
__FILE__
)
.
'/query.inc'
;
/**
* @defgroup schemaapi Schema API
* @{
...
...
includes/database/select.inc
View file @
d7a63ff9
...
...
@@ -6,6 +6,8 @@
* @{
*/
require_once
dirname
(
__FILE__
)
.
'/query.inc'
;
/**
* Interface for extendable query objects.
*
...
...
@@ -642,7 +644,9 @@ public function havingCompile(DatabaseConnection $connection) {
/* Implementations of QueryExtendableInterface. */
public
function
extend
(
$extender_name
)
{
$class
=
$this
->
connection
->
getDriverClass
(
$extender_name
);
// The extender can be anywhere so this needs to go to the registry, which
// is surely loaded by now.
$class
=
$this
->
connection
->
getDriverClass
(
$extender_name
,
array
(),
TRUE
);
return
new
$class
(
$this
,
$this
->
connection
);
}
...
...
includes/install.core.inc
View file @
d7a63ff9
...
...
@@ -289,7 +289,6 @@ 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
();
...
...
includes/install.inc
View file @
d7a63ff9
...
...
@@ -238,7 +238,6 @@ function drupal_detect_database_types() {
// 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
)
{
if
(
file_exists
(
$file
->
uri
.
'/database.inc'
)
&&
file_exists
(
$file
->
uri
.
'/install.inc'
))
{
$drivers
[
$file
->
filename
]
=
$file
->
uri
;
...
...
@@ -246,8 +245,7 @@ function drupal_detect_database_types() {
}
foreach
(
$drivers
as
$driver
=>
$file
)
{
$class
=
'DatabaseTasks_'
.
$driver
;
$installer
=
new
$class
();
$installer
=
db_installer_object
(
$driver
);
if
(
$installer
->
installable
())
{
$databases
[
$driver
]
=
$installer
->
name
();
}
...
...
@@ -1123,8 +1121,18 @@ function install_profile_info($profile, $locale = 'en') {
* encoding.
*/
function
db_run_tasks
(
$driver
)
{
$task_class
=
'DatabaseTasks_'
.
$driver
;
$DatabaseTasks
=
new
$task_class
();
$DatabaseTasks
->
runTasks
();
db_installer_object
(
$driver
)
->
runTasks
();
return
TRUE
;
}
/**
* Returns a database installer object.
*
* @param $driver
* The name of the driver.
*/
function
db_installer_object
(
$driver
)
{
Database
::
loadDriverFile
(
$driver
,
array
(
'install.inc'
));
$task_class
=
'DatabaseTasks_'
.
$driver
;
return
new
$task_class
();
}
includes/theme.maintenance.inc
View file @
d7a63ff9
...
...
@@ -41,7 +41,6 @@ function _drupal_maintenance_theme() {
// to work. See _drupal_log_error().
if
(
!
class_exists
(
'Database'
,
FALSE
))
{
require_once
DRUPAL_ROOT
.
'/includes/database/database.inc'
;
spl_autoload_register
(
'db_autoload'
);
}
// We use the default theme as the maintenance theme. If a default theme
...
...
modules/simpletest/drupal_web_test_case.php
View file @
d7a63ff9
...
...
@@ -611,8 +611,6 @@ protected function setUp() {
// Store necessary current values before switching to the test environment.
$this
->
originalFileDirectory
=
variable_get
(
'file_public_path'
,
conf_path
()
.
'/files'
);
spl_autoload_register
(
'db_autoload'
);
// Reset all statics so that test is performed with a clean environment.
drupal_static_reset
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment