? .DS_Store
? 1004068-sqlite-addtable.patch
? 850852-sqlite-concurrent-testing_1.patch
? 850852_transaction_14.patch
? 850852_transaction_15.patch
? asdf.patch
? databasecondition_multiple_queries.patch
? databasecondition_multiple_queries.patch.1
? foo.patch
? foo_3.patch
? head.db
? someone_screwed_up_the_logic_not_to_point_any_fingers_2.patch
? sqlite_more_broken.patch
? sqlite_update_query_expression.patch
? test.patch
? test_only.patch
? includes/database/.DS_Store
? includes/database/mysqlbigint
? includes/database/sqlite/.DS_Store
? modules/.DS_Store
? modules/field/modules/.DS_Store
? modules/simpletest/.DS_Store
? modules/simpletest/tests/.DS_Store
? sites/all/.DS_Store
? sites/all/contributions
? sites/all/modules/.DS_Store
? sites/all/modules/devel
? sites/all/modules/multiple_email
? sites/all/modules/multiple_email.tgz
? sites/default/files
? sites/default/settings.php
Index: includes/database/sqlite/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/sqlite/database.inc,v
retrieving revision 1.39
diff -u -p -r1.39 database.inc
--- includes/database/sqlite/database.inc	3 Oct 2010 01:29:41 -0000	1.39
+++ includes/database/sqlite/database.inc	22 Dec 2010 17:49:06 -0000
@@ -24,7 +24,7 @@ class DatabaseConnection_sqlite extends 
    * Version of sqlite lower then 3.6.8 can't use savepoints.
    * See http://www.sqlite.org/releaselog/3_6_8.html
    *
-   * @var bool
+   * @var boolean
    */
   protected $savepointSupport = FALSE;
 
@@ -35,6 +35,26 @@ class DatabaseConnection_sqlite extends 
    */
   protected $willRollback;
 
+  /**
+   * All databases attached to the current database. This is used to allow
+   * prefixes to be safely handled without locking the table
+   * 
+   * @var array
+   */
+  protected $attachedDatabases = array();
+
+  /**
+   * Whether or not a table has been dropped this request: the destructor will
+   * only try to get rid of unnecessary databases if there is potential of them
+   * being empty.
+   * 
+   * This variable is set to public because DatabaseSchema_sqlite needs to
+   * access it. However, it should not be manually set.
+   * 
+   * @var boolean
+   */
+  var $tableDropped = FALSE;
+
   public function __construct(array $connection_options = array()) {
     // We don't need a specific PDOStatement class here, we simulate it below.
     $this->statementClass = NULL;
@@ -51,6 +71,24 @@ class DatabaseConnection_sqlite extends 
       PDO::ATTR_STRINGIFY_FETCHES => TRUE,
     ));
 
+    // Record all databases that were attached. Start off with finding all
+    // unique prefixes ($this->prefixes maps table => prefix, and multiple
+    // tables can have the same prefix)
+    $this->attachedDatabases = array_unique($this->prefixes);
+    // Attach one database for each registered prefix.
+    if (!empty($this->defaultPrefix)) {
+      // Add in the default prefix, which is also attached.
+      $this->attachedDatabases[] = $this->defaultPrefix;
+      $this->query('ATTACH DATABASE :database AS :prefix', array(':database' => $connection_options['database'] . '-' . $this->defaultPrefix, ':prefix' => $this->defaultPrefix));
+      $this->defaultPrefix .= '.';
+    }
+    foreach ($this->prefixes as $table => $prefix) {
+      if (!empty($prefix)) {
+        $this->query('ATTACH DATABASE :database AS :prefix', array(':database' => $connection_options['database'] . '-' . $prefix, ':prefix' => $prefix));
+        $this->prefixes[$table] .= '.';
+      }
+    }
+
     $this->exec('PRAGMA encoding="UTF-8"');
 
     // Detect support for SAVEPOINT.
@@ -70,6 +108,36 @@ class DatabaseConnection_sqlite extends 
   }
 
   /**
+   * Destructor for the SQLite connection.
+   *
+   * We prune empty databases on destruct, but only if tables have been
+   * dropped. This is especially needed when running the test suite, which
+   * creates and destroy databases several times in a row.
+   */
+  public function __destruct() {
+    if ($this->tableDropped && !empty($this->attachedDatabases)) {
+      foreach ($this->attachedDatabases as $prefix) {
+        // Check if the database is now empty, ignore the internal SQLite tables.
+        try {
+          $count = $this->query('SELECT COUNT(*) FROM ' . $prefix . '.sqlite_master WHERE type = :type AND name NOT LIKE :pattern', array(':type' => 'table', ':pattern' => 'sqlite_%'))->fetchField();
+
+          // We can prune the database file if it doens't have any tables.
+          if ($count == 0) {
+            // Detach the database.
+            $this->query('DETACH DATABASE :schema', array(':schema' => $prefix));
+            // Destroy the database file.
+            unlink($this->connectionOptions['database'] . '-' . $prefix);
+          }
+        }
+        catch (Exception $e) {
+          // Ignore the exception and continue. There is nothing we can do here
+          // to report the error or fail safe.
+        }
+      }
+    }
+  }
+
+  /**
    * SQLite compatibility implementation for the IF() SQL function.
    */
   public function sqlFunctionIf($condition, $expr1, $expr2 = NULL) {
Index: includes/database/sqlite/schema.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/sqlite/schema.inc,v
retrieving revision 1.20
diff -u -p -r1.20 schema.inc
--- includes/database/sqlite/schema.inc	22 Oct 2010 15:18:56 -0000	1.20
+++ includes/database/sqlite/schema.inc	22 Dec 2010 17:49:06 -0000
@@ -271,7 +271,7 @@ class DatabaseSchema_sqlite extends Data
     if (!$this->tableExists($table)) {
       return FALSE;
     }
-
+    $this->connection->tableDropped = TRUE;
     $this->connection->query('DROP TABLE {' . $table . '}');
     return TRUE;
   }
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.255
diff -u -p -r1.255 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	18 Dec 2010 01:50:16 -0000	1.255
+++ modules/simpletest/drupal_web_test_case.php	22 Dec 2010 17:49:06 -0000
@@ -1314,8 +1314,26 @@ class DrupalWebTestCase extends DrupalTe
    */
   protected function preloadRegistry() {
     $original_connection = Database::getConnection('default', 'simpletest_original_default');
-    db_query('INSERT INTO {registry} SELECT * FROM ' . $original_connection->prefixTables('{registry}'));
-    db_query('INSERT INTO {registry_file} SELECT * FROM ' . $original_connection->prefixTables('{registry_file}'));
+    $test_connection = Database::getConnection();
+
+    foreach (array('registry', 'registry_file') as $table) {
+      $source_query = $original_connection
+        ->select($table, array(), array('fetch' => PDO::FETCH_ASSOC))
+        ->fields($table);
+
+      $dest_query = $test_connection->insert($table);
+
+      $first = TRUE;
+      foreach ($source_query->execute() as $row) {
+        if ($first) {
+          $dest_query->fields(array_keys($row));
+          $first = FALSE;
+        }
+        $dest_query->values($row);
+      }
+
+      $dest_query->execute();
+    }
   }
 
   /**
