Skip to content

Commit

Permalink
Add basic support for "information_schema.tables" in CREATE TABLE
Browse files Browse the repository at this point in the history
  • Loading branch information
JanJakes committed Dec 4, 2024
1 parent b47db70 commit 79c0bfd
Show file tree
Hide file tree
Showing 3 changed files with 307 additions and 9 deletions.
2 changes: 1 addition & 1 deletion tests/WP_SQLite_Driver_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static function setUpBeforeClass(): void {
public function setUp(): void {
$this->sqlite = new PDO( 'sqlite::memory:' );

$this->engine = new WP_SQLite_Driver( $this->sqlite );
$this->engine = new WP_SQLite_Driver( 'wp', $this->sqlite );
$this->engine->query(
"CREATE TABLE _options (
ID INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
Expand Down
86 changes: 80 additions & 6 deletions tests/WP_SQLite_Driver_Translation_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ public static function setUpBeforeClass(): void {
self::$grammar = new WP_Parser_Grammar( include self::GRAMMAR_PATH );
}

public function setUp(): void {
$this->driver = new WP_SQLite_Driver( new PDO( 'sqlite::memory:' ) );
}

public function testSelect(): void {
$this->assertQuery(
'SELECT 1',
Expand Down Expand Up @@ -201,25 +197,64 @@ public function testDelete(): void {
}

public function testCreateTable(): void {
// Basic CREATE TABLE.
$this->assertQuery(
'CREATE TABLE "t" ( "id" INTEGER )',
'CREATE TABLE t (id INT)'
);
$this->assertExecutedInformationSchemaQueries(
array(
'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)'
. " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')",
)
);

// Multiple columns.
$this->assertQuery(
'CREATE TABLE "t" ( "id" INTEGER , "name" TEXT , "score" REAL DEFAULT 0.0 )',
'CREATE TABLE t (id INT, name TEXT, score FLOAT DEFAULT 0.0)'
);
$this->assertExecutedInformationSchemaQueries(
array(
'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)'
. " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')",
)
);

// Basic constraints.
$this->assertQuery(
'CREATE TABLE "t" ( "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT )',
'CREATE TABLE t (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT)'
);
$this->assertExecutedInformationSchemaQueries(
array(
'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)'
. " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')",
)
);

// ENGINE is not supported in SQLite, we save it in "information schema".
$this->assertQuery(
'CREATE TABLE "t" ( "id" INTEGER )',
'CREATE TABLE t (id INT) ENGINE=MyISAM'
);
$this->assertExecutedInformationSchemaQueries(
array(
'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)'
. " VALUES ('wp', 't', 'BASE TABLE', 'MyISAM', 'Fixed', 'utf8mb4_general_ci')",
)
);

// ENGINE is not supported in SQLite.
// COLLATE is not supported in SQLite, we save it in "information schema".
$this->assertQuery(
'CREATE TABLE "t" ( "id" INTEGER )',
'CREATE TABLE t (id INT) ENGINE=InnoDB'
'CREATE TABLE t (id INT) COLLATE utf8mb4_czech_ci'
);
$this->assertExecutedInformationSchemaQueries(
array(
'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)'
. " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_czech_ci')",
)
);

/*
Expand Down Expand Up @@ -446,6 +481,7 @@ public function testSystemVariables(): void {
}

private function assertQuery( $expected, string $query ): void {
$this->driver = new WP_SQLite_Driver( 'wp', new PDO( 'sqlite::memory:' ) );
$this->driver->query( $query );

// Check for SQLite syntax errors.
Expand All @@ -465,6 +501,16 @@ private function assertQuery( $expected, string $query ): void {
$executed_queries = array_values( array_slice( $executed_queries, 1, -1, true ) );
}

// Remove "information_schema" queries.
$executed_queries = array_values(
array_filter(
$executed_queries,
function ( $query ) {
return ! str_contains( $query, '_mysql_information_schema_' );
}
)
);

// Remove "select changes()" executed after some queries.
if (
count( $executed_queries ) > 1
Expand All @@ -477,4 +523,32 @@ private function assertQuery( $expected, string $query ): void {
}
$this->assertSame( $expected, $executed_queries );
}

private function assertExecutedInformationSchemaQueries( array $expected ): void {
// Collect and normalize "information_schema" queries.
$queries = array();
foreach ( $this->driver->executed_sqlite_queries as $query ) {
if ( ! str_contains( $query['sql'], '_mysql_information_schema_' ) ) {
continue;
}

// Normalize whitespace.
$sql = trim( preg_replace( '/\s+/', ' ', $query['sql'] ) );

// Inline parameters.
$sql = str_replace( '?', '%s', $sql );
$queries[] = sprintf(
$sql,
...array_map(
function ( $param ) {
return is_string( $param ) ?
$this->driver->get_pdo()->quote( $param )
: $param;
},
$query['params']
)
);
}
$this->assertSame( $expected, $queries );
}
}
Loading

0 comments on commit 79c0bfd

Please sign in to comment.