=== modified file 'includes/database.inc' --- includes/database.inc 2007-08-30 19:54:21 +0000 +++ includes/database.inc 2007-09-02 12:19:32 +0000 @@ -428,6 +428,28 @@ function db_create_table(&$ret, $name, $ } /** + * Creates a unique named table with the same structure as an existing table. + * + * @param $module + * The name of the module that defines the existing table. + * @param $table + * The name of the table to copy. Prefixing is handled by this function, + * so just use the table name. + * @return + * Name of the freshly created table. + */ +function db_create_table_like($module, $table) { + $new_table_name = 'temp_'. str_replace(array('.', ' '), '_', microtime()); + $schema[$new_table_name] = drupal_get_schema_unprocessed($module, $table); + _drupal_initialize_schema($module, $schema); + $ret = array(); + db_create_table($ret, $new_table_name, $schema[$new_table_name]); + return $new_table_name; +} + + + +/** * Return an array of field names from an array of key/index column * specifiers. This is usually an identity function but if a * key/index uses a column prefix specification, this function === modified file 'includes/database.mysql-common.inc' --- includes/database.mysql-common.inc 2007-08-26 08:27:08 +0000 +++ includes/database.mysql-common.inc 2007-09-02 12:20:52 +0000 @@ -481,5 +481,25 @@ function db_last_insert_id($table, $fiel } /** + * Renames a table to another, replacing the latter. + * + * This function uses db specific ways to guarantee that no data loss can + * occur. In case of a failure, the replace simply does not happen. + * + * @param $src + * Name of the source table, usally from db_create_table_like(). As + * db_create_table_like() creates unique names, this is not prefixed. + * @param $target + * Name of the target table. This one will get prefixed. + */ +function db_replace_table($src, $target) { + $swap_table = 'temp_'. str_replace(array('.', ' '), '_', microtime()); + db_query('RENAME TABLE {'. $target .'} TO '. $swap_table .', '. $src .' TO {'. $target .'}'); + if (!db_error()) { + db_query("DROP TABLE $swap_table"); + } +} + +/** * @} End of "ingroup schemaapi". - */ \ No newline at end of file + */ === modified file 'includes/database.pgsql.inc' --- includes/database.pgsql.inc 2007-08-29 18:38:55 +0000 +++ includes/database.pgsql.inc 2007-09-02 12:06:41 +0000 @@ -443,6 +443,25 @@ function db_distinct_field($table, $fiel } /** + * Renames a table to an existing one. + * + * This function uses db specific ways to guarantee that no data loss can + * occur. In case of a failure, the rename simply does not happen. + * + * @param $new_table_name + * Name of the source table, usally from db_create_table_like(). As + * db_create_table_like() creates unique names, this is not prefixed. + * @param $table + * Name of the target table. + */ +function db_replace_table($src, $target) { + db_query('BEGIN'); + db_query('DROP TABLE {'. $target .'}'); + db_query('ALTER TABLE '. $src .' RENAME TO {'. $target .'}'); + db_query('COMMIT'); +} + +/** * @} End of "ingroup database". */ === modified file 'modules/block/block.module' --- modules/block/block.module 2007-09-01 05:31:09 +0000 +++ modules/block/block.module 2007-09-02 12:06:59 +0000 @@ -256,19 +256,17 @@ function _block_rehash() { } } - db_lock_table('blocks'); - // Remove all blocks from table. - db_query("DELETE FROM {blocks} WHERE theme = '%s'", $theme_key); - // Reinsert new set of blocks into table. + // Reinsert new set of blocks into a temporary table. + $temporary_table_name = db_create_table_like('block', 'blocks'); foreach ($blocks as $block) { $block += array( 'visibility' => NULL, 'throttle' => NULL, ); - db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s', %d)", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title'], $block['cache']); + db_query('INSERT INTO {'. $temporary_table_name ."} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s', %d)", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title'], $block['cache']); } - db_unlock_tables(); + db_replace_table($temporary_table_name, 'blocks'); return $blocks; }