rdbms: Migrate Database::query() calls in DatabaseSqlite to Query object

Similar to basically any other direct caller of ::query()

Bug: T335630
Change-Id: I42cb99fafedc1b82e5af6ce959afc2283c443851
This commit is contained in:
Amir Sarabadani 2023-09-13 11:46:19 +02:00
parent ad0ea3803d
commit f0a841c4fa
3 changed files with 89 additions and 47 deletions

View file

@ -197,9 +197,13 @@ class DatabaseSqlite extends Database {
$this->platform->setPrefix( $tablePrefix );
try {
$flags = self::QUERY_CHANGE_TRX | self::QUERY_NO_RETRY;
// Enforce LIKE to be case sensitive, just like MySQL
$this->query( 'PRAGMA case_sensitive_like = 1', __METHOD__, $flags );
$query = new Query(
'PRAGMA case_sensitive_like = 1',
self::QUERY_CHANGE_TRX | self::QUERY_NO_RETRY,
'PRAGMA'
);
$this->query( $query, __METHOD__ );
// Set any connection-level custom PRAGMA options
$pragmas = array_intersect_key( $this->connectionVariables, self::VALID_PRAGMAS );
$pragmas += $this->getDefaultPragmas();
@ -209,7 +213,14 @@ class DatabaseSqlite extends Database {
( is_array( $allowed ) && in_array( $value, $allowed, true ) ) ||
( is_string( $allowed ) && gettype( $value ) === $allowed )
) {
$this->query( "PRAGMA $name = $value", __METHOD__, $flags );
$query = new Query(
"PRAGMA $name = $value",
self::QUERY_CHANGE_TRX | self::QUERY_NO_RETRY,
'PRAGMA',
null,
"PRAGMA $name = '?'"
);
$this->query( $query, __METHOD__ );
}
}
$this->attachDatabasesFromTableAliases();
@ -369,12 +380,12 @@ class DatabaseSqlite extends Database {
public function attachDatabase( $name, $file = false, $fname = __METHOD__ ) {
$file = is_string( $file ) ? $file : self::generateFileName( $this->dbDir, $name );
$encFile = $this->addQuotes( $file );
return $this->query(
$query = new Query(
"ATTACH DATABASE $encFile AS $name",
$fname,
self::QUERY_CHANGE_TRX
self::QUERY_CHANGE_TRX,
'ATTACH'
);
return $this->query( $query, $fname );
}
protected function doSingleStatementQuery( string $sql ): QueryStatus {
@ -463,11 +474,12 @@ class DatabaseSqlite extends Database {
}
$encTable = $this->addQuotes( $tableRaw );
$res = $this->query(
$query = new Query(
"SELECT 1 FROM sqlite_master WHERE type='table' AND name=$encTable",
__METHOD__,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'SELECT'
);
$res = $this->query( $query, __METHOD__ );
return (bool)$res->numRows();
}
@ -483,8 +495,12 @@ class DatabaseSqlite extends Database {
* @return array|false
*/
public function indexInfo( $table, $index, $fname = __METHOD__ ) {
$sql = 'PRAGMA index_info(' . $this->addQuotes( $this->platform->indexName( $index ) ) . ')';
$res = $this->query( $sql, $fname, self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE );
$query = new Query(
'PRAGMA index_info(' . $this->addQuotes( $this->platform->indexName( $index ) ) . ')',
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'PRAGMA'
);
$res = $this->query( $query, $fname );
if ( !$res || $res->numRows() == 0 ) {
return false;
}
@ -533,11 +549,13 @@ class DatabaseSqlite extends Database {
// https://sqlite.org/lang_insert.html
// Note that any auto-increment columns on conflicting rows will be reassigned
// due to combined DELETE+INSERT semantics. This will be reflected in insertId().
$this->query(
$query = new Query(
"REPLACE INTO $encTable ($sqlColumns) VALUES $sqlTuples",
$fname,
self::QUERY_CHANGE_ROWS
self::QUERY_CHANGE_ROWS,
'REPLACE',
$table
);
$this->query( $query, $fname );
}
/**
@ -614,11 +632,12 @@ class DatabaseSqlite extends Database {
*/
public function fieldInfo( $table, $field ) {
$tableRaw = $this->tableName( $table, 'raw' );
$res = $this->query(
$query = new Query(
'PRAGMA table_info(' . $this->addQuotes( $tableRaw ) . ')',
__METHOD__,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'PRAGMA'
);
$res = $this->query( $query, __METHOD__ );
foreach ( $res as $row ) {
if ( $row->name == $field ) {
return new SQLiteField( $row, $tableRaw );
@ -630,10 +649,12 @@ class DatabaseSqlite extends Database {
protected function doBegin( $fname = '' ) {
if ( $this->trxMode != '' ) {
$this->query( "BEGIN {$this->trxMode}", $fname, self::QUERY_CHANGE_TRX );
$sql = "BEGIN {$this->trxMode}";
} else {
$this->query( 'BEGIN', $fname, self::QUERY_CHANGE_TRX );
$sql = 'BEGIN';
}
$query = new Query( $sql, self::QUERY_CHANGE_TRX, 'BEGIN' );
$this->query( $query, $fname );
}
/**
@ -734,12 +755,13 @@ class DatabaseSqlite extends Database {
public function duplicateTableStructure(
$oldName, $newName, $temporary = false, $fname = __METHOD__
) {
$res = $this->query(
$query = new Query(
"SELECT sql FROM sqlite_master WHERE tbl_name=" .
$this->addQuotes( $oldName ) . " AND type='table'",
$fname,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'SELECT'
);
$res = $this->query( $query, $fname );
$obj = $res->fetchObject();
if ( !$obj ) {
throw new RuntimeException( "Couldn't retrieve structure for table $oldName" );
@ -768,18 +790,22 @@ class DatabaseSqlite extends Database {
}
}
$res = $this->query(
$query = new Query(
$sqlCreateTable,
$fname,
$flags
$flags,
$temporary ? 'CREATE TEMPORARY' : 'CREATE',
// Use a dot to avoid double-prefixing in Database::getTempTableWrites()
'.' . $newName
);
$res = $this->query( $query, $fname );
// Take over indexes
$indexList = $this->query(
$query = new Query(
'PRAGMA INDEX_LIST(' . $this->addQuotes( $oldName ) . ')',
$fname,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'PRAGMA'
);
// Take over indexes
$indexList = $this->query( $query, $fname );
foreach ( $indexList as $index ) {
if ( strpos( $index->name, 'sqlite_autoindex' ) === 0 ) {
continue;
@ -795,11 +821,12 @@ class DatabaseSqlite extends Database {
$sqlIndex .= ' ' . $this->platform->addIdentifierQuotes( $indexName ) .
' ON ' . $this->platform->addIdentifierQuotes( $newName );
$indexInfo = $this->query(
$query = new Query(
'PRAGMA INDEX_INFO(' . $this->addQuotes( $index->name ) . ')',
$fname,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'PRAGMA'
);
$indexInfo = $this->query( $query, $fname );
$fields = [];
foreach ( $indexInfo as $indexInfoRow ) {
$fields[$indexInfoRow->seqno] = $this->addQuotes( $indexInfoRow->name );
@ -807,11 +834,13 @@ class DatabaseSqlite extends Database {
$sqlIndex .= '(' . implode( ',', $fields ) . ')';
$this->query(
$query = new Query(
$sqlIndex,
__METHOD__,
self::QUERY_CHANGE_SCHEMA | self::QUERY_PSEUDO_PERMANENT
self::QUERY_CHANGE_SCHEMA | self::QUERY_PSEUDO_PERMANENT,
'CREATE',
$newName
);
$this->query( $query, __METHOD__ );
}
return $res;
@ -826,11 +855,12 @@ class DatabaseSqlite extends Database {
* @return array
*/
public function listTables( $prefix = null, $fname = __METHOD__ ) {
$result = $this->query(
$query = new Query(
"SELECT name FROM sqlite_master WHERE type = 'table'",
$fname,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'SELECT'
);
$result = $this->query( $query, $fname );
$endArray = [];
@ -854,18 +884,25 @@ class DatabaseSqlite extends Database {
$encSeqNames = [];
foreach ( $tables as $table ) {
// Use "truncate" optimization; https://www.sqlite.org/lang_delete.html
$sql = "DELETE FROM " . $this->tableName( $table );
$this->query( $sql, $fname, self::QUERY_CHANGE_SCHEMA );
$query = new Query(
"DELETE FROM " . $this->tableName( $table ),
self::QUERY_CHANGE_SCHEMA,
'DELETE',
$table
);
$this->query( $query, $fname );
$encSeqNames[] = $this->addQuotes( $this->tableName( $table, 'raw' ) );
}
$encMasterTable = $this->platform->addIdentifierQuotes( 'sqlite_sequence' );
$this->query(
$query = new Query(
"DELETE FROM $encMasterTable WHERE name IN(" . implode( ',', $encSeqNames ) . ")",
$fname,
self::QUERY_CHANGE_SCHEMA
self::QUERY_CHANGE_SCHEMA,
'DELETE',
'sqlite_sequence'
);
$this->query( $query, $fname );
$this->endAtomic( $fname );
}
@ -920,11 +957,12 @@ class DatabaseSqlite extends Database {
protected function getInsertIdColumnForUpsert( $table ) {
$tableRaw = $this->tableName( $table, 'raw' );
$res = $this->query(
$query = new Query(
'PRAGMA table_info(' . $this->addQuotes( $tableRaw ) . ')',
__METHOD__,
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE
self::QUERY_IGNORE_DBO_TRX | self::QUERY_CHANGE_NONE,
'PRAGMA'
);
$res = $this->query( $query, __METHOD__ );
foreach ( $res as $row ) {
if ( $row->pk && strtolower( $row->type ) === 'integer' ) {
return $row->name;

View file

@ -48,6 +48,8 @@ class MediaWikiIntegrationTestCaseSchema1Test extends MediaWikiIntegrationTestCa
}
public function testTableWasAltered() {
// The sql file does ALTER which doesn't exist in sqlite
$this->markTestSkippedIfDbType( 'sqlite' );
// Make sure pagelinks was altered
$this->assertTrue( $this->db->tableExists( 'pagelinks' ) );
$this->assertTrue( $this->db->fieldExists( 'pagelinks', 'pl_frobnitz' ) );

View file

@ -43,6 +43,8 @@ class MediaWikiIntegrationTestCaseSchema2Test extends MediaWikiIntegrationTestCa
}
public function testAlteredTableWasRestored() {
// The sql file does ALTER which doesn't exist in sqlite
$this->markTestSkippedIfDbType( 'sqlite' );
// Make sure pagelinks altered by MediaWikiIntegrationTestCaseSchema1Test
// was restored to the original schema before executing MediaWikiIntegrationTestCaseSchema2Test.
$this->assertTrue( $this->db->tableExists( 'pagelinks' ) );