Commit 27d7455e authored by Dries's avatar Dries

- Patch #333054 by c960657: page cache should be case sensitive.

parent c403b160
......@@ -60,7 +60,8 @@ protected function buildTableNameCondition($table_name, $operator = '=') {
*/
protected function createTableSql($name, $table) {
if (empty($table['mysql_suffix'])) {
$table['mysql_suffix'] = 'DEFAULT CHARACTER SET UTF8';
// Store strings as UTF-8 and do case-sensitive comparision.
$table['mysql_suffix'] = 'DEFAULT CHARACTER SET UTF8 COLLATE utf8_bin';
}
$sql = "CREATE TABLE {" . $name . "} (\n";
......
......@@ -97,13 +97,8 @@ public function databaseType() {
}
public function mapConditionOperator($operator) {
static $specials = array(
// In PostgreSQL, 'LIKE' is case-sensitive. For case-insensitive LIKE
// statements, we need to use ILIKE instead.
'LIKE' => array('operator' => 'ILIKE'),
);
return isset($specials[$operator]) ? $specials[$operator] : NULL;
// We don't want to override any of the defaults.
return NULL;
}
/**
......
......@@ -31,6 +31,7 @@ public function __construct(array $connection_options = array()) {
));
$this->exec('PRAGMA encoding="UTF-8"');
$this->exec('PRAGMA case_sensitive_like=1');
// Create functions needed by SQLite.
$this->sqliteCreateFunction('if', array($this, 'sqlFunctionIf'));
......
......@@ -5,10 +5,6 @@
* Implementation of hook_install().
*/
function locale_install() {
// locales_source.source and locales_target.target are not used as binary
// fields; non-MySQL database servers need to ensure the field type is text
// and that LIKE produces a case-sensitive comparison.
// Create tables.
drupal_install_schema('locale');
......@@ -354,7 +350,6 @@ function locale_schema() {
),
'source' => array(
'type' => 'text',
'mysql_type' => 'blob',
'not null' => TRUE,
'description' => 'The original string in English.',
),
......@@ -383,7 +378,6 @@ function locale_schema() {
),
'translation' => array(
'type' => 'text',
'mysql_type' => 'blob',
'not null' => TRUE,
'description' => 'Translation string value in this language.',
),
......
......@@ -391,8 +391,9 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
// This is the language indicator on the translation search screen for
// untranslated strings. Copied straight from locale.inc.
$language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
// This will be the translation of $name.
$translation = $this->randomName(16);
// This will be the translation of $name. Make sure it contains at least
// one lower-case character in order to check case-sensitive search.
$translation = $this->randomName(16) . 'x';
// Add custom language.
$this->drupalLogin($admin_user);
......@@ -469,6 +470,16 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
$this->drupalPost('admin/international/translate/translate', $search, t('Filter'));
$this->assertNoText(t('No strings found for your search.'), t('Search found the translation.'));
// Ensure string search is case-sensitive.
$search = array(
'string' => drupal_strtoupper($translation),
'language' => 'all',
'translation' => 'translated',
'group' => 'all',
);
$this->drupalPost('admin/international/translate/translate', $search, t('Filter'));
$this->assertText(t('No strings found for your search.'), t("Search didn't find the translation."));
// Ensure translated source string doesn't appear if searching on 'only
// untranslated strings'.
$search = array(
......
......@@ -1995,6 +1995,34 @@ class DatabaseRegressionTestCase extends DatabaseTestCase {
$this->assertTrue(db_table_exists('node'), t('Returns true for existent table.'));
$this->assertFalse(db_table_exists('nosuchtable'), t('Returns false for nonexistent table.'));
}
/**
* Test that string comparison is case-sensitive.
*/
function testCaseSensitiviteCompare() {
$num_matches = db_query("SELECT COUNT(*) FROM {test} WHERE name = :name", array(':name' => 'George'))->fetchField();
$this->assertEqual($num_matches, 1, t('Correct number of records found with proper case.'));
$num_matches = db_query("SELECT COUNT(*) FROM {test} WHERE name = :name", array(':name' => 'GEORGE'))->fetchField();
$this->assertEqual($num_matches, 0, t('Correct number of records found with wrong case.'));
$num_matches = db_query("SELECT COUNT(*) FROM {test} WHERE name LIKE :name", array(':name' => 'Geo%'))->fetchField();
$this->assertEqual($num_matches, 1, t('Correct number of records found with proper case.'));
$num_matches = db_query("SELECT COUNT(*) FROM {test} WHERE name LIKE :name", array(':name' => 'GEO%'))->fetchField();
$this->assertEqual($num_matches, 0, t('Correct number of records found with wrong case.'));
$num_matches = db_select('test')
->condition('name', 'Geo%', 'LIKE')
->countQuery()
->execute()
->fetchField();
$this->assertEqual($num_matches, 1, t('Correct number of records found with proper case.'));
$num_matches = db_select('test')
->condition('name', 'GEO%', 'LIKE')
->countQuery()
->execute()
->fetchField();
$this->assertEqual($num_matches, 0, t('Correct number of records found with wrong case.'));
}
}
/**
......
......@@ -107,8 +107,8 @@ function statistics_top_visitors() {
* Menu callback; presents the "referrer" page.
*/
function statistics_top_referrers() {
$query = "SELECT url, COUNT(url) AS hits, MAX(timestamp) AS last FROM {accesslog} WHERE url NOT LIKE :host AND url <> '' GROUP BY url";
$query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> '' AND url NOT LIKE :host";
$query = "SELECT url, COUNT(url) AS hits, MAX(timestamp) AS last FROM {accesslog} WHERE LOWER(url) NOT LIKE :host AND url <> '' GROUP BY url";
$query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> '' AND LOWER(url) NOT LIKE :host";
drupal_set_title(t('Top referrers in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))), PASS_THROUGH);
$header = array(
......
......@@ -3067,11 +3067,30 @@ function system_update_7011() {
return $ret;
}
/**
* Make tables case-sensitive on MySQL.
*/
function system_update_7012() {
$ret = array();
if (db_driver() == 'mysql') {
// Table names as used in D6. Some have changed and are no longer reported
// by hook_schema(). The list is generated using the following command:
// grep -r "^ \+\$schema\['[a-z_]\+'\] =" modules | cut -d\' -f2 | sort -u | xargs -I '*' echo -n "'*', "
$tables = array('access', 'accesslog', 'actions', 'actions_aid', 'aggregator_category', 'aggregator_category_feed', 'aggregator_category_item', 'aggregator_feed', 'aggregator_item', 'authmap', 'batch', 'blocks', 'blocks_roles', 'blogapi_files', 'book', 'book_temp', 'boxes', 'cache', 'cache_block', 'cache_filter', 'cache_form', 'cache_menu', 'cache_page', 'cache_update', 'comments', 'contact', 'files', 'filter_formats', 'filters', 'flood', 'forum', 'history', 'languages', 'locales_source', 'locales_target', 'menu_custom', 'menu_links', 'menu_router', 'node', 'node_access', 'node_comment_statistics', 'node_counter', 'node_revisions', 'node_type', 'openid_association', 'permission', 'poll', 'poll_choices', 'poll_votes', 'profile_fields', 'profile_values', 'role', 'search_dataset', 'search_index', 'search_node_links', 'search_total', 'sessions', 'system', 'term_data', 'term_hierarchy', 'term_node', 'term_relation', 'term_synonym', 'trigger_assignments', 'upload', 'url_alias', 'users', 'users_roles', 'variable', 'vocabulary', 'vocabulary_node_types', 'watchdog');
foreach ($tables as $table) {
if (db_table_exists($table)) {
$ret[] = update_sql('ALTER TABLE {' . $table . '} CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin');
}
}
}
return $ret;
}
/**
* Rename {blocks} table to {block}, {blocks_roles} to {block_role} and
* {boxes} to {box}.
*/
function system_update_7012() {
function system_update_7013() {
$ret = array();
db_rename_table($ret, 'blocks', 'block');
db_rename_table($ret, 'blocks_roles', 'block_role');
......@@ -3082,7 +3101,7 @@ function system_update_7012() {
/**
* Convert default time zone offset to default time zone name.
*/
function system_update_7013() {
function system_update_7014() {
$ret = array();
$timezone = NULL;
$timezones = system_time_zones();
......@@ -3123,7 +3142,7 @@ function system_update_7013() {
/**
* Drop the bootstrap column from the {system} table.
*/
function system_update_7014() {
function system_update_7015() {
$ret = array();
db_drop_field($ret, 'system', 'bootstrap');
return $ret;
......@@ -3132,7 +3151,7 @@ function system_update_7014() {
/**
* Change the user logout path.
*/
function system_update_7015() {
function system_update_7016() {
$ret = array();
$ret[] = update_sql("UPDATE {menu_links} SET link_path = 'user/logout' WHERE link_path = 'logout'");
$ret[] = update_sql("UPDATE {menu_links} SET router_path = 'user/logout' WHERE router_path = 'logout'");
......@@ -3142,7 +3161,7 @@ function system_update_7015() {
/**
* Remove custom datatype *_unsigned in PostgreSQL.
*/
function system_update_7016() {
function system_update_7017() {
$ret = array();
// Only run these queries if the driver used is pgsql.
if (db_driver() == 'pgsql') {
......@@ -3176,7 +3195,7 @@ function system_update_7016() {
/**
* Change the theme setting 'toggle_node_info' into a per content type variable.
*/
function system_update_7017() {
function system_update_7018() {
$ret = array();
$types = node_get_types();
if (count($types)) {
......@@ -3205,7 +3224,7 @@ function system_update_7017() {
/**
* Replace src index on the {url_alias} table with src, language.
*/
function system_update_7018() {
function system_update_7019() {
$ret = array();
db_add_index($ret, 'url_alias', 'src_language', array('src', 'language'));
db_drop_index($ret, 'url_alias', 'src');
......@@ -3216,7 +3235,7 @@ function system_update_7018() {
/**
* Shorten the {system}.type column and add an index on type and name.
*/
function system_update_7019() {
function system_update_7020() {
$ret = array();
db_drop_index($ret, 'system', 'modules');
db_change_field($ret, 'system', 'type', 'type', array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''));
......@@ -3228,7 +3247,7 @@ function system_update_7019() {
/**
* Enable field module.
*/
function system_update_7020() {
function system_update_7021() {
$ret = array();
$module_list = array('field_sql_storage', 'field');
drupal_install_modules($module_list);
......
......@@ -216,14 +216,12 @@ function user_load_multiple($uids = array(), $conditions = array(), $reset = FAL
}
// If the conditions array is populated, add those to the query.
if ($conditions) {
// TODO D7: Using LIKE() to get a case insensitive comparison because Crell
// and chx promise that dbtng will map it to ILIKE in postgres.
if (isset($conditions['name'])) {
$query->condition('u.name', $conditions['name'], 'LIKE');
$query->where('LOWER(u.name) = LOWER(:name)', array(':name' => $conditions['name']));
unset($conditions['name']);
}
if (isset($conditions['mail'])) {
$query->condition('u.mail', $conditions['mail'], 'LIKE');
$query->where('LOWER(u.mail) = LOWER(:mail)', array(':mail' => $conditions['mail']));
unset($conditions['mail']);
}
foreach ($conditions as $field => $value) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment