summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2009-06-01 11:23:27 +0000
committerDries Buytaert <dries@buytaert.net>2009-06-01 11:23:27 +0000
commit984f27efc9ea5e579d1394292d8d2bb2f9123055 (patch)
treee689a13295f076b0563b0943d6f9cd783e13cd9a
parent706ce87579e8c29953583a5bfd417aa7e1fbe4b5 (diff)
downloadbrdo-984f27efc9ea5e579d1394292d8d2bb2f9123055.tar.gz
brdo-984f27efc9ea5e579d1394292d8d2bb2f9123055.tar.bz2
- Patch #106559 by kbahey, catch, DamZ, chx et al: more drupal_lookup_path() optimizations.
-rw-r--r--includes/database/sqlite/database.inc15
-rw-r--r--includes/database/sqlite/schema.inc11
-rw-r--r--includes/path.inc45
-rw-r--r--modules/system/system.install24
4 files changed, 85 insertions, 10 deletions
diff --git a/includes/database/sqlite/database.inc b/includes/database/sqlite/database.inc
index f4ee1704c..dc79b128d 100644
--- a/includes/database/sqlite/database.inc
+++ b/includes/database/sqlite/database.inc
@@ -39,6 +39,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
$this->sqliteCreateFunction('length', 'strlen', 1);
$this->sqliteCreateFunction('concat', array($this, 'sqlFunctionConcat'));
$this->sqliteCreateFunction('substring', array($this, 'sqlFunctionSubstring'), 3);
+ $this->sqliteCreateFunction('substring_index', array($this, 'sqlFunctionSubstringIndex'), 3);
$this->sqliteCreateFunction('rand', array($this, 'sqlFunctionRand'));
}
@@ -83,6 +84,20 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
}
/**
+ * SQLite compatibility implementation for the SUBSTRING_INDEX() SQL function.
+ */
+ public function sqlFunctionSubstringIndex($string, $delimiter, $count) {
+ $end = 0;
+ for ($i = 0; $i < $count; $i++) {
+ $end = strpos($string, $delimiter, $end + 1);
+ if ($end === FALSE) {
+ $end = strlen($string);
+ }
+ }
+ return substr($string, 0, $end);
+ }
+
+ /**
* SQLite compatibility implementation for the RAND() SQL function.
*/
public function sqlFunctionRand($seed = NULL) {
diff --git a/includes/database/sqlite/schema.inc b/includes/database/sqlite/schema.inc
index 834a93037..25c07d6c2 100644
--- a/includes/database/sqlite/schema.inc
+++ b/includes/database/sqlite/schema.inc
@@ -430,7 +430,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
*/
public function addIndex(&$ret, $table, $name, $fields) {
$schema['indexes'][$name] = $fields;
- $ret[] = update_sql($this->createIndexSql($table, $schema));
+ $statements = $this->createIndexSql($table, $schema);
+ foreach ($statements as $statement) {
+ $ret[] = update_sql($statement);
+ }
}
/**
@@ -461,8 +464,10 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
*/
public function addUniqueKey(&$ret, $table, $name, $fields) {
$schema['unique keys'][$name] = $fields;
- $ret[] = update_sql($this->createIndexSql($table, $schema));
-
+ $statements = $this->createIndexSql($table, $schema);
+ foreach ($statements as $statement) {
+ $ret[] = update_sql($statement);
+ }
}
/**
diff --git a/includes/path.inc b/includes/path.inc
index 6ea9db901..fa066aac3 100644
--- a/includes/path.inc
+++ b/includes/path.inc
@@ -48,31 +48,37 @@ function drupal_lookup_path($action, $path = '', $path_language = '') {
// $map is an array with language keys, holding arrays of Drupal paths to alias relations
$map = &drupal_static(__FUNCTION__, array());
$no_src = &drupal_static(__FUNCTION__ . ':no_src', array());
- $count = &drupal_static(__FUNCTION__ . ':count');
+ $whitelist = &drupal_static(__FUNCTION__ . ':whitelist');
$system_paths = &drupal_static(__FUNCTION__ . ':system_paths');
$no_aliases = &drupal_static(__FUNCTION__ . ':no_alias', array());
$first_call = &drupal_static(__FUNCTION__ . ':first_call', TRUE);
- $path_language = $path_language ? $path_language : $language->language;
-
- // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
- if (!isset($count)) {
- $count = db_query('SELECT COUNT(pid) FROM {url_alias}')->fetchField();
+ // Retrieve the path alias whitelist.
+ if (!isset($whitelist)) {
+ $whitelist = variable_get('path_alias_whitelist', NULL);
+ if (!isset($whitelist)) {
+ $whitelist = drupal_path_alias_whitelist_rebuild();
+ }
}
+ $path_language = $path_language ? $path_language : $language->language;
+
if ($action == 'wipe') {
$map = array();
$no_src = array();
$count = NULL;
$system_paths = array();
$no_aliases = array();
+
+ $whitelist = drupal_path_alias_whitelist_rebuild();
}
- elseif ($count > 0 && $path != '') {
+ elseif ($whitelist && $path != '') {
if ($action == 'alias') {
// During the first call to drupal_lookup_path() per language, load the
// expected system paths for the page from cache.
if ($first_call) {
$first_call = FALSE;
+
$map[$path_language] = array();
// Load system paths from cache.
$cid = current_path();
@@ -93,6 +99,12 @@ function drupal_lookup_path($action, $path = '', $path_language = '') {
if (isset($map[$path_language][$path])) {
return $map[$path_language][$path];
}
+ // Check the path whitelist, if the top_level part before the first /
+ // is not in the list, then there is no need to do anything further,
+ // it is not in the database.
+ elseif (!isset($whitelist[strtok($path, '/')])) {
+ return FALSE;
+ }
// For system paths which were not cached, query aliases individually.
else if (!isset($no_aliases[$path_language][$path])) {
// Get the most fitting result falling back with alias without language
@@ -347,3 +359,22 @@ function drupal_match_path($path, $patterns) {
function current_path() {
return $_GET['q'];
}
+
+/**
+ * Rebuild the path alias white list.
+ *
+ * @return
+ * An array containing a white list of path aliases.
+ */
+function drupal_path_alias_whitelist_rebuild() {
+ // For each alias in the database, get the top level component of the system
+ // path it corresponds to. This is the portion of the path before the first /
+ // if present, otherwise the whole path itself.
+ $whitelist = array();
+ $result = db_query("SELECT SUBSTRING_INDEX(src, '/', 1) AS path FROM {url_alias} GROUP BY path");
+ foreach ($result as $row) {
+ $whitelist[$row->path] = TRUE;
+ }
+ variable_set('path_alias_whitelist', $whitelist);
+ return $whitelist;
+}
diff --git a/modules/system/system.install b/modules/system/system.install
index 15db982ca..4f94fb27e 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -339,6 +339,11 @@ function system_install() {
\'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
LANGUAGE \'sql\''
);
+
+ db_query('CREATE OR REPLACE FUNCTION "substr_index"(text, text, integer) RETURNS text AS
+ \'SELECT array_to_string((string_to_array($1, $2)) [1:$3], $2);\'
+ LANGUAGE \'sql\''
+ );
}
// Create tables.
@@ -3496,6 +3501,25 @@ function system_update_7023() {
}
/**
+ * Add the substr_index() function to PostgreSQL.
+ *
+ * Note: this should go into the driver itself, but we have no support
+ * for driver-specific updates yet.
+ */
+function system_update_7024() {
+ $ret = array();
+
+ if (db_driver() == 'pgsql') {
+ $ret[] = update_sql('CREATE OR REPLACE FUNCTION "substr_index"(text, text, integer) RETURNS text AS
+ \'SELECT array_to_string((string_to_array($1, $2)) [1:$3], $2);\'
+ LANGUAGE \'sql\''
+ );
+ }
+
+ return $ret;
+}
+
+/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.
*/