=== modified file 'database/database.mysql' --- database/database.mysql +++ database/database.mysql @@ -667,9 +667,7 @@ CREATE TABLE sessions ( -- CREATE TABLE sequences ( - name varchar(255) NOT NULL default '', - id int(10) unsigned NOT NULL default '0', - PRIMARY KEY (name) + id UNSIGNED INT NOT NULL AUTO_INCREMENT PRIMARY KEY ) /*!40100 DEFAULT CHARACTER SET utf8 */ ; @@ -905,7 +903,7 @@ INSERT INTO variable (name, value) VALUE INSERT INTO blocks (module, delta, theme, status, pages) VALUES ('user', '0', 'bluemarine', '1', ''); INSERT INTO blocks (module, delta, theme, status, pages) VALUES ('user', '1', 'bluemarine', '1', ''); -INSERT INTO sequences (name, id) VALUES ('menu_mid', 2); +INSERT INTO sequences VALUES (2); INSERT INTO node_access VALUES (0, 0, 'all', 1, 0, 0); === modified file 'database/updates.inc' --- database/updates.inc +++ database/updates.inc @@ -1806,7 +1806,7 @@ function system_update_178() { $args[] = $node->vid; db_query('UPDATE {node_revisions} SET '. implode(', ', $set) .' WHERE vid = %d', $args); } - + } if ($_SESSION['system_update_178_comment'] == $_SESSION['system_update_178_comment_max'] && @@ -1828,3 +1828,18 @@ function system_update_178() { return array(); } + +function system_update_179() { + $ret = array(); + + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $new_id = db_result(db_query('SELECT MAX(id) FROM {sequences}')); + $ret[] = update_sql('DROP TABLE {sequences}'); + $ret[] = update_sql('CREATE TABLE {sequences} (id UNSIGNED INT NOT NULL AUTO_INCREMENT PRIMARY KEY)'); + db_query('INSERT INTO {sequences} VALUES (%d)', $new_id); + } + + return $ret; +} === modified file 'includes/bootstrap.inc' --- includes/bootstrap.inc +++ includes/bootstrap.inc @@ -234,10 +234,11 @@ 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(); + $serialized_value = serialize($value); + db_query_replace(array( + 'table' => 'variable', + 'update' => array("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name), + 'insert' => array("{variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value))); cache_clear_all('variables'); @@ -321,12 +322,10 @@ function cache_get($key) { * A string containing HTTP header information for cached pages. */ function cache_set($cid, $data, $expire = CACHE_PERMANENT, $headers = NULL) { - db_lock_table('cache'); - db_query("UPDATE {cache} SET data = %b, created = %d, expire = %d, headers = '%s' WHERE cid = '%s'", $data, time(), $expire, $headers, $cid); - if (!db_affected_rows()) { - @db_query("INSERT INTO {cache} (cid, data, created, expire, headers) VALUES ('%s', %b, %d, %d, '%s')", $cid, $data, time(), $expire, $headers); - } - db_unlock_tables(); + db_query_replace(array( + 'table' => 'cache', + 'update' => array("UPDATE {cache} SET data = %b, created = %d, expire = %d, headers = '%s' WHERE cid = '%s'", $data, time(), $expire, $headers, $cid), + 'insert' => array("{cache} (cid, data, created, expire, headers) VALUES ('%s', %b, %d, %d, '%s')", $cid, $data, time(), $expire, $headers))); } /** === modified file 'includes/database.mysql.inc' --- includes/database.mysql.inc +++ includes/database.mysql.inc @@ -195,21 +195,11 @@ function db_error() { } /** - * Return a new unique ID in the given sequence. - * - * For compatibility reasons, Drupal does not use auto-numbered fields in its - * database tables. Instead, this function is used to return a new unique ID - * of the type requested. If necessary, a new sequence with the given name - * will be created. - */ -function db_next_id($name) { - $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; + * Return a new unique ID. + */ +function db_next_id() { + db_query('INSERT INTO {sequences} VALUES (NULL)'); + return mysql_insert_id(); } /** @@ -317,6 +307,25 @@ function db_query_temporary($query) { } /** + * Try an update and if that fails, do an INSERT. + * + * @param $queries + * An associative array, containing three keys: update, insert and table. + * The value of update is an update query, in the same format as db_query + * expects. The value of insert is an insert query without the INSERT INTO, + * just begin with the table name. The value of table is the table under + * changing. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_replace($queries) { + $queries['insert'][0] = 'REPLACE '. $queries['insert'][0]; + return call_user_func_array('db_query', $queries['insert']); +} + + +/** * Returns a properly formatted Binary Large OBject value. * * @param $data === modified file 'includes/database.mysqli.inc' --- includes/database.mysqli.inc +++ includes/database.mysqli.inc @@ -197,19 +197,12 @@ function db_error() { } /** - * Return a new unique ID in the given sequence. - * - * For compatibility reasons, Drupal does not use auto-numbered fields in its - * database tables. Instead, this function is used to return a new unique ID - * of the type requested. If necessary, a new sequence with the given name - * will be created. - */ -function db_next_id($name) { - $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 a new unique ID. + */ +function db_next_id() { + db_query('INSERT INTO {sequences} VALUES (NULL)'); + return mysql_insert_id(); +} return $id; } @@ -319,6 +312,24 @@ function db_query_temporary($query) { } /** + * Try an update and if that fails, do an INSERT. + * + * @param $queries + * An associative array, containing three keys: update, insert and table. + * The value of update is an update query, in the same format as db_query + * expects. The value of insert is an insert query without the INSERT INTO, + * just begin with the table name. The value of table is the table under + * changing. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_replace($queries) { + $queries['insert'][0] = 'REPLACE '. $queries['insert'][0]; + return call_user_func_array('db_query', $queries['insert']); +} + +/** * Returns a properly formatted Binary Large Object value. * * @param $data === modified file 'includes/database.pgsql.inc' --- includes/database.pgsql.inc +++ includes/database.pgsql.inc @@ -327,6 +327,35 @@ function db_escape_string($text) { } /** + * Performs an INSERT but if an old row in the table has the same value as a + * new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before + * the new row is inserted. + * + * @param $queries + * An associative array, containing three keys: update, insert and table. + * The value of update is an update query, in the same format as db_query + * expects. The value of insert is an insert query without the INSERT INTO, + * just begin with the table name. The value of table is the table under + * changing. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_replace($queries) { + $args = func_get_args(); + + db_lock_table($queries['table']); + $result = call_user_func_array('db_query', $queries['update']); + if (!db_affected_rows()) { + $queries['insert'][0] = 'INSERT INTO '. $queries['insert'][0]; + $result = call_user_func_array('db_query', $queries['insert']); + } + db_unlock_table($queries['table']); + return $result; +} + + +/** * Lock a table. * This function automatically starts a transaction. */