Follow-up r82856: instead of remembering magic table names, just analyse its structur...
authorMax Semenik <maxsem@users.mediawiki.org>
Sat, 26 Feb 2011 16:45:35 +0000 (16:45 +0000)
committerMax Semenik <maxsem@users.mediawiki.org>
Sat, 26 Feb 2011 16:45:35 +0000 (16:45 +0000)
includes/db/DatabaseSqlite.php
tests/phpunit/includes/db/DatabaseSqliteTest.php

index b5baf21..8186395 100644 (file)
@@ -601,11 +601,12 @@ class DatabaseSqlite extends DatabaseBase {
                }
                $sql = $obj->sql;
                $sql = preg_replace( '/\b' . preg_quote( $oldName ) . '\b/', $newName, $sql, 1 );
-               if ( $temporary && strpos( $oldName, 'searchindex' ) === false ) {
-                       # For some reason TEMPORARY TABLE doesn't work with searchindex
-                       # We need to explicitly look for searchindex rather than VIRTUAL
-                       # because we don't want to clone the FTS subtables either
-                       $sql = str_replace( 'CREATE TABLE', 'CREATE TEMPORARY TABLE', $sql );
+               if ( $temporary ) {
+                       if ( preg_match( '/^\\s*CREATE\\s+VIRTUAL\\s+TABLE\b/', $sql ) ) {
+                               wfDebug( "Table $oldName is virtual, can't create a temporary duplicate.\n" );
+                       } else {
+                               $sql = str_replace( 'CREATE TABLE', 'CREATE TEMPORARY TABLE', $sql );
+                       }
                }
                return $this->query( $sql, $fname );
        }
index 24704ad..366f341 100644 (file)
@@ -75,6 +75,47 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) );
                $this->assertEquals( 'foobar', $db->tableName( 'bar' ) );
        }
+       
+       public function testDuplicateTableStructure() {
+               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db->query( 'CREATE TABLE foo(foo, barfoo)' );
+
+               $db->duplicateTableStructure( 'foo', 'bar' );
+               $this->assertEquals( 'CREATE TABLE bar(foo, barfoo)',
+                       $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ),
+                       'Normal table duplication'
+               );
+
+               $db->duplicateTableStructure( 'foo', 'baz', true );
+               $this->assertEquals( 'CREATE TABLE baz(foo, barfoo)',
+                       $db->selectField( 'sqlite_temp_master', 'sql', array( 'name' => 'baz' ) ),
+                       'Creation of temporary duplicate'
+               );
+               $this->assertEquals( 0,
+                       $db->selectField( 'sqlite_master', 'COUNT(*)', array( 'name' => 'baz' ) ),
+                       'Create a temporary duplicate only'
+               );
+       }
+       
+       public function testDuplicateTableStructureVirtual() {
+               $db = new DatabaseSqliteStandalone( ':memory:' );
+               if ( $db->getFulltextSearchModule() != 'FTS3' ) {
+                       $this->markTestSkipped( 'FTS3 not supported, cannot create virtual tables' );
+               }
+               $db->query( 'CREATE VIRTUAL TABLE foo USING FTS3(foobar)' );
+
+               $db->duplicateTableStructure( 'foo', 'bar' );
+               $this->assertEquals( 'CREATE VIRTUAL TABLE bar USING FTS3(foobar)',
+                       $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ),
+                       'Duplication of virtual tables'
+               );
+
+               $db->duplicateTableStructure( 'foo', 'baz', true );
+               $this->assertEquals( 'CREATE VIRTUAL TABLE baz USING FTS3(foobar)',
+                       $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'baz' ) ),
+                       "Can't create temporary virtual tables, should fall back to non-temporary duplication"
+               );
+       }
 
        function testEntireSchema() {
                global $IP;