Skip to content

Commit 43c60f9

Browse files
authored
Add support for table locking statements and transaction savepoints (#221)
This PR includes the following changes: - Add support for `LOCK` and `UNLOCK` statements. - Add support for transaction savepoints (`SAVEPOINT`, `ROLLBACK TO`, `RELEASE SAVEPOINT`) - Improve verification of internal identifier names
1 parent 1dc9eec commit 43c60f9

File tree

2 files changed

+298
-100
lines changed

2 files changed

+298
-100
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4144,27 +4144,27 @@ public function getReservedPrefixTestData(): array {
41444144
return array(
41454145
array(
41464146
'SELECT * FROM _wp_sqlite_t',
4147-
"Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved",
4147+
"Invalid identifier '_wp_sqlite_t', prefix '_wp_sqlite_' is reserved",
41484148
),
41494149
array(
41504150
'SELECT _wp_sqlite_t FROM t',
4151-
"Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved",
4151+
"Invalid identifier '_wp_sqlite_t', prefix '_wp_sqlite_' is reserved",
41524152
),
41534153
array(
41544154
'SELECT t._wp_sqlite_t FROM t',
4155-
"Invalid identifier `t`.`_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved",
4155+
"Invalid identifier '_wp_sqlite_t', prefix '_wp_sqlite_' is reserved",
41564156
),
41574157
array(
41584158
'CREATE TABLE _wp_sqlite_t (id INT)',
4159-
"Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved",
4159+
"Invalid identifier '_wp_sqlite_t', prefix '_wp_sqlite_' is reserved",
41604160
),
41614161
array(
41624162
'ALTER TABLE _wp_sqlite_t ADD COLUMN name TEXT',
4163-
"Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved",
4163+
"Invalid identifier '_wp_sqlite_t', prefix '_wp_sqlite_' is reserved",
41644164
),
41654165
array(
41664166
'DROP TABLE _wp_sqlite_t',
4167-
"Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved",
4167+
"Invalid identifier '_wp_sqlite_t', prefix '_wp_sqlite_' is reserved",
41684168
),
41694169
);
41704170
}
@@ -6238,4 +6238,94 @@ public function testUserVariables(): void {
62386238
$result = $this->assertQuery( 'SELECT @my_var' );
62396239
$this->assertEquals( 3, $result[0]->{'@my_var'} );
62406240
}
6241+
6242+
public function testLockingStatements(): void {
6243+
$this->assertQuery( 'CREATE TABLE t (id INT)' );
6244+
6245+
// When there is no lock, UNLOCK statement shouldn't fail.
6246+
$this->assertQuery( 'UNLOCK TABLES' );
6247+
6248+
// READ LOCK.
6249+
$this->assertQuery( 'LOCK TABLES t READ' );
6250+
$this->assertQuery( 'UNLOCK TABLES' );
6251+
6252+
// WRITE LOCK.
6253+
$this->assertQuery( 'LOCK TABLES t WRITE' );
6254+
$this->assertQuery( 'UNLOCK TABLES' );
6255+
6256+
// LOCK inside a transaction.
6257+
$this->assertQuery( 'BEGIN' );
6258+
$this->assertQuery( 'LOCK TABLES t WRITE' );
6259+
$this->assertQuery( 'UNLOCK TABLES' );
6260+
$this->assertQuery( 'COMMIT' );
6261+
6262+
// Transaction inside LOCK statements.
6263+
$this->assertQuery( 'LOCK TABLES t WRITE' );
6264+
$this->assertQuery( 'BEGIN' );
6265+
$this->assertQuery( 'COMMIT' );
6266+
$this->assertQuery( 'UNLOCK TABLES' );
6267+
}
6268+
6269+
public function testLockNonExistentTableForRead(): void {
6270+
$this->expectException( 'WP_SQLite_Driver_Exception' );
6271+
$this->expectExceptionMessage( "Table 'wp.t' doesn't exist" );
6272+
$this->assertQuery( 'LOCK TABLES t READ' );
6273+
}
6274+
6275+
public function testLockNonExistentTableForWrite(): void {
6276+
$this->expectException( 'WP_SQLite_Driver_Exception' );
6277+
$this->expectExceptionMessage( "Table 'wp.t' doesn't exist" );
6278+
$this->assertQuery( 'LOCK TABLES t WRITE' );
6279+
}
6280+
6281+
public function testLockMultipleWithNonExistentTable(): void {
6282+
$this->assertQuery( 'CREATE TABLE t1 (id INT)' );
6283+
$this->assertQuery( 'CREATE TABLE t3 (id INT)' );
6284+
6285+
$this->expectException( 'WP_SQLite_Driver_Exception' );
6286+
$this->expectExceptionMessage( "Table 'wp.t2' doesn't exist" );
6287+
$this->assertQuery( 'LOCK TABLES t1 READ, t2 READ, t3 WRITE' );
6288+
}
6289+
6290+
public function testLockTemporaryTables(): void {
6291+
$this->assertQuery( 'CREATE TEMPORARY TABLE t1 (id INT)' );
6292+
$this->assertQuery( 'CREATE TABLE t2 (id INT)' );
6293+
$this->assertQuery( 'CREATE TEMPORARY TABLE t3 (id INT)' );
6294+
$this->assertQuery( 'LOCK TABLES t1 READ, t2 READ, t3 WRITE' );
6295+
$this->assertQuery( 'UNLOCK TABLES' );
6296+
}
6297+
6298+
public function testTransactionSavepoints(): void {
6299+
$this->assertQuery( 'CREATE TABLE t (id INT)' );
6300+
6301+
$this->assertQuery( 'BEGIN' );
6302+
$this->assertQuery( 'INSERT INTO t (id) VALUES (1)' );
6303+
$result = $this->assertQuery( 'SELECT * FROM t' );
6304+
$this->assertSame( array( '1' ), (array) array_column( $result, 'id' ) );
6305+
6306+
$this->assertQuery( 'SAVEPOINT sp1' );
6307+
$this->assertQuery( 'INSERT INTO t (id) VALUES (2)' );
6308+
$result = $this->assertQuery( 'SELECT * FROM t' );
6309+
$this->assertSame( array( '1', '2' ), (array) array_column( $result, 'id' ) );
6310+
6311+
$this->assertQuery( 'SAVEPOINT sp2' );
6312+
$this->assertQuery( 'INSERT INTO t (id) VALUES (3)' );
6313+
$result = $this->assertQuery( 'SELECT * FROM t' );
6314+
$this->assertSame( array( '1', '2', '3' ), (array) array_column( $result, 'id' ) );
6315+
6316+
$this->assertQuery( 'ROLLBACK TO SAVEPOINT sp1' );
6317+
$result = $this->assertQuery( 'SELECT * FROM t' );
6318+
$this->assertSame( array( '1' ), (array) array_column( $result, 'id' ) );
6319+
6320+
$this->assertQuery( 'RELEASE SAVEPOINT sp1' );
6321+
$this->assertQuery( 'ROLLBACK' );
6322+
$result = $this->assertQuery( 'SELECT * FROM t' );
6323+
$this->assertSame( array(), (array) array_column( $result, 'id' ) );
6324+
}
6325+
6326+
public function testRollbackNonExistentTransactionSavepoint(): void {
6327+
$this->expectException( 'WP_SQLite_Driver_Exception' );
6328+
$this->expectExceptionMessage( 'no such savepoint: sp1' );
6329+
$this->assertQuery( 'ROLLBACK TO SAVEPOINT sp1' );
6330+
}
62416331
}

0 commit comments

Comments
 (0)