wiki.techinc.nl/maintenance/Sqlite.php
Umherirrender a36eca22b5 Improve code around internal queries in sqlite database class
Use database quote function for the internal table names
Rename variable to avoid reuse and not confuse taint

This makes taint happy

Bug: T216348
Change-Id: Ic35f63857e85cc523d655aad18384d5bfbc48420
2020-12-03 19:30:11 +00:00

100 lines
2.7 KiB
PHP

<?php
/**
* Helper class for sqlite-specific scripts
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Maintenance
*/
use Wikimedia\Rdbms\DatabaseSqlite;
use Wikimedia\Rdbms\DBError;
/**
* This class contains code common to different SQLite-related maintenance scripts
*
* @ingroup Maintenance
*/
class Sqlite {
/**
* Checks whether PHP has SQLite support
* @return bool
*/
public static function isPresent() {
return extension_loaded( 'pdo_sqlite' );
}
/**
* Checks given files for correctness of SQL syntax. MySQL DDL will be converted to
* SQLite-compatible during processing.
* Will throw exceptions on SQL errors
* @param array|string $files
* @throws MWException
* @return bool True if no error or error string in case of errors
*/
public static function checkSqlSyntax( $files ) {
if ( !self::isPresent() ) {
throw new MWException( "Can't check SQL syntax: SQLite not found" );
}
if ( !is_array( $files ) ) {
$files = [ $files ];
}
$allowedTypes = array_flip( [
'integer',
'real',
'text',
'blob',
// NULL type is omitted intentionally
] );
$db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
try {
foreach ( $files as $file ) {
$err = $db->sourceFile( $file );
if ( $err != true ) {
return $err;
}
}
$tables = $db->query( "SELECT name FROM sqlite_master WHERE type='table'", __METHOD__ );
foreach ( $tables as $table ) {
if ( strpos( $table->name, 'sqlite_' ) === 0 ) {
continue;
}
$columns = $db->query(
'PRAGMA table_info(' . $db->addIdentifierQuotes( $table->name ) . ')',
__METHOD__
);
foreach ( $columns as $col ) {
if ( !isset( $allowedTypes[strtolower( $col->type )] ) ) {
$db->close( __METHOD__ );
return "Table {$table->name} has column {$col->name} with non-native type '{$col->type}'";
}
}
}
} catch ( DBError $e ) {
return $e->getMessage();
}
$db->close( __METHOD__ );
return true;
}
}