? 28604_dateien ? INSTALL.patch ? access.patch ? add_book_index.patch ? add_comment_stats_index.patch ? autocomplete.patch ? better_book_cache.patch ? better_caching.patch ? better_taxo_caching.patch ? block_cache.patch ? block_rehash_head.patch.txt ? cache_block.patch ? cache_date.patch ? cache_index_pgsql.patch ? convert.php ? database.mysql ? db_faith_46.sql ? drupal.org-slow.log ? drupal.org-slow.log2 ? drupal.org-slow.log3 ? file_download.patch ? files ? files.sql ? grep ? hardening-drupal.txt ? heap.patch ? infinite_loop.patch ? locale ? mail-alternative.php ? mail-node.php ? mail-utf8.php ? mail.php ? merge.patch ? merge.patch_20060817_2249_sammys.txt ? move_defines.patch ? no_block.patch ? no_lock.patch ? node_show.patch ? path_cache-47.patch ? path_cache.patch ? phpinfo.php ? stats.patch ? swap_file_revision_index.patch ? taxo_names ? taxo_projects ? test.php ? unblock.patch ? upload.patch ? urlalias.patch ? xmlrpx-out.php ? modules/foo ? modules/search/search.module-patched ? modules/user/user.install ? sites/localhost.~killes ? sites/default/locale ? sites/default/settings_local.php ? themes/bluemarine/template.php ? themes/pushbutton/page.tpl.php-foo Index: update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.211 diff -u -p -r1.211 update.php --- update.php 25 Dec 2006 21:22:03 -0000 1.211 +++ update.php 16 Jan 2007 14:20:07 -0000 @@ -15,7 +15,7 @@ */ // Enforce access checking? -$access_check = TRUE; +$access_check = FALSE; function update_sql($sql) { Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.145 diff -u -p -r1.145 bootstrap.inc --- includes/bootstrap.inc 15 Jan 2007 11:52:02 -0000 1.145 +++ includes/bootstrap.inc 16 Jan 2007 14:20:08 -0000 @@ -384,10 +384,10 @@ function variable_get($name, $default) { function variable_set($name, $value) { global $conf; - db_lock_table('variable'); - db_query("DELETE FROM {variable} WHERE name = '%s'", $name); - db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, serialize($value)); - db_unlock_tables(); + db_query_replace( + array("DELETE FROM {variable} WHERE name = '%s'", $name), + array("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, serialize($value)) + ); cache_clear_all('variables', 'cache'); Index: includes/cache.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/cache.inc,v retrieving revision 1.5 diff -u -p -r1.5 cache.inc --- includes/cache.inc 10 Nov 2006 07:26:27 -0000 1.5 +++ includes/cache.inc 16 Jan 2007 14:20:08 -0000 @@ -91,12 +91,10 @@ function cache_get($key, $table = 'cache * A string containing HTTP header information for cached pages. */ function cache_set($cid, $table = 'cache', $data, $expire = CACHE_PERMANENT, $headers = NULL) { - db_lock_table($table); - db_query("UPDATE {%s} SET data = %b, created = %d, expire = %d, headers = '%s' WHERE cid = '%s'", $table, $data, time(), $expire, $headers, $cid); - if (!db_affected_rows()) { - @db_query("INSERT INTO {%s} (cid, data, created, expire, headers) VALUES ('%s', %b, %d, %d, '%s')", $table, $cid, $data, time(), $expire, $headers); - } - db_unlock_tables(); + db_query_replace( + array("DELETE FROM {%s} WHERE cid = '%s'", $table, $cid), + array("INSERT INTO {%s} (cid, data, created, expire, headers) VALUES ('%s', %b, %d, %d, '%s')", $table, $cid, $data, time(), $expire, $headers) + ); } /** Index: includes/database.mysql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v retrieving revision 1.66 diff -u -p -r1.66 database.mysql.inc --- includes/database.mysql.inc 27 Dec 2006 22:50:09 -0000 1.66 +++ includes/database.mysql.inc 16 Jan 2007 14:20:08 -0000 @@ -254,13 +254,22 @@ function db_error() { * with table prefixes. For example, db_next_id('{node}_nid'); */ function db_next_id($name) { + // Prefix any curly-bracket "{table}" names $name = db_prefix_tables($name); - db_query('LOCK TABLES {sequences} WRITE'); - $id = db_result(db_query("SELECT id FROM {sequences} WHERE name = '%s'", $name)) + 1; - db_query("REPLACE INTO {sequences} VALUES ('%s', %d)", $name, $id); - db_query('UNLOCK TABLES'); - - return $id; + // Assume initially that the sequence already exists. Attempt to update it atomically. + // LAST_INSERT_ID lets us get its value later. IGNORE suppresses update failures. + db_query("UPDATE IGNORE {sequences} SET id=LAST_INSERT_ID(id + 1) WHERE name = '%s'", $name); + // Check whether that worked + if (!db_affected_rows()) { + // Updated failed, so the sequence doesn't exist yet. + // In either case, try to create a new sequence starting from zero + // IGNORE suppresses insert error if e.g. a concurrent process got there first. + db_query("INSERT IGNORE INTO {sequences} VALUES ('%s', %d)", $name, 0); + // Sequence now exists (unless some database error occurred to prevent it) + // Retry update, allowing for possible concurrent process. It should work this time. + db_query("UPDATE {sequences} SET id = LAST_INSERT_ID(id + 1) WHERE name = '%s'", $name); + } + return mysql_insert_id(); } /** @@ -434,7 +443,20 @@ function db_distinct_field($table, $fiel } /** + * Perform a replace query. + * + * @param $delete + * An array, where the first value is a query which deletes one row, + * subsequent values are arguments. Same syntax as of db_query. + * @param + * An array, where the first value is a query which inserts the new row, + * subsequent values are arguments. Same syntax as of db_query. + */ +function db_query_replace($delete, $insert) { + $insert_query = array_shift($insert); + db_query(preg_replace('/^INSERT /', 'REPLACE ', $insert_query), $insert); +} + +/** * @} End of "ingroup database". */ - - Index: includes/database.mysqli.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.mysqli.inc,v retrieving revision 1.32 diff -u -p -r1.32 database.mysqli.inc --- includes/database.mysqli.inc 27 Dec 2006 22:50:09 -0000 1.32 +++ includes/database.mysqli.inc 16 Jan 2007 14:20:08 -0000 @@ -239,13 +239,22 @@ function db_error() { * with table prefixes. For example, db_next_id('{node}_nid'); */ function db_next_id($name) { + // Prefix any curly-bracket "{table}" names $name = db_prefix_tables($name); - db_query('LOCK TABLES {sequences} WRITE'); - $id = db_result(db_query("SELECT id FROM {sequences} WHERE name = '%s'", $name)) + 1; - db_query("REPLACE INTO {sequences} VALUES ('%s', %d)", $name, $id); - db_query('UNLOCK TABLES'); - - return $id; + // Assume initially that the sequence already exists. Attempt to update it atomically. + // LAST_INSERT_ID lets us get its value later. IGNORE suppresses update failures. + db_query("UPDATE IGNORE {sequences} SET id=LAST_INSERT_ID(id + 1) WHERE name = '%s'", $name); + // Check whether that worked + if (!db_affected_rows()) { + // Updated failed, so the sequence doesn't exist yet. + // In either case, try to create a new sequence starting from zero + // IGNORE suppresses insert error if e.g. a concurrent process got there first. + db_query("INSERT IGNORE INTO {sequences} VALUES ('%s', %d)", $name, 0); + // Sequence now exists (unless some database error occurred to prevent it) + // Retry update, allowing for possible concurrent process. It should work this time. + db_query("UPDATE {sequences} SET id = LAST_INSERT_ID(id + 1) WHERE name = '%s'", $name); + } + return db_result(db_query("SELECT LAST_INSERT_ID() FROM {sequences} WHERE name = '%s'", $name)); } /** @@ -419,6 +428,21 @@ function db_distinct_field($table, $fiel } /** + * Perform a replace query. + * + * @param $delete + * An array, where the first value is a query which deletes one row, + * subsequent values are arguments. Same syntax as of db_query. + * @param + * An array, where the first value is a query which inserts the new row, + * subsequent values are arguments. Same syntax as of db_query. + */ +function db_query_replace($delete, $insert) { + $insert_query = array_shift($insert); + db_query(preg_replace('/^INSERT /', 'REPLACE ', $insert_query), $insert); +} + +/** * @} End of "ingroup database". */ Index: includes/database.pgsql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v retrieving revision 1.43 diff -u -p -r1.43 database.pgsql.inc --- includes/database.pgsql.inc 27 Dec 2006 22:13:56 -0000 1.43 +++ includes/database.pgsql.inc 16 Jan 2007 14:20:08 -0000 @@ -426,6 +426,26 @@ function db_distinct_field($table, $fiel } /** + * Perform a replace query. + * + * @param $delete + * An array, where the first value is a query which deletes one row, + * subsequent values are arguments. Same syntax as of db_query. + * @param + * An array, where the first value is a query which inserts the new row, + * subsequent values are arguments. Same syntax as of db_query. + */ +function db_query_replace($delete, $insert) { + $delete_query = array_shift($delete); + db_query('BEGIN'); + db_query(preg_replace('/^DELETE /', 'SELECT ', $delete_query .' FOR UPDATE'), $delete); + db_query($delete_query, $delete); + $insert_query = array_shift($insert); + db_query($insert_query, $insert); + db_query('COMMIT'); +} + +/** * @} End of "ingroup database". */