r70967 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r70966‎ | r70967 | r70968 >
Date:16:06, 12 August 2010
Author:maxsem
Status:ok
Tags:
Comment:
maintenance/sqlite.php: added the ability to check .sql files for SQLite compatibility
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/maintenance/sqlite.inc (added) (history)
  • /trunk/phase3/maintenance/sqlite.php (modified) (history)
  • /trunk/phase3/maintenance/tests/DatabaseSqliteTest.php (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/tests/DatabaseSqliteTest.php
@@ -21,7 +21,7 @@
2222 var $db;
2323
2424 function setup() {
25 - if ( !extension_loaded( 'pdo_sqlite' ) ) {
 25+ if ( !Sqlite::isPresent() ) {
2626 $this->markTestIncomplete( 'No SQLite support detected' );
2727 }
2828 $this->db = new MockDatabaseSqlite();
@@ -62,27 +62,9 @@
6363 function testEntireSchema() {
6464 global $IP;
6565
66 - $allowedTypes = array_flip( array(
67 - 'integer',
68 - 'real',
69 - 'text',
70 - 'blob', // NULL type is omitted intentionally
71 - ) );
72 -
73 - $db = new DatabaseSqliteStandalone( ':memory:' );
74 - $db->sourceFile( "$IP/maintenance/tables.sql" );
75 -
76 - $tables = $db->query( "SELECT name FROM sqlite_master WHERE type='table'", __METHOD__ );
77 - foreach ( $tables as $table ) {
78 - if ( strpos( $table->name, 'sqlite_' ) === 0 ) continue;
79 -
80 - $columns = $db->query( "PRAGMA table_info({$table->name})", __METHOD__ );
81 - foreach ( $columns as $col ) {
82 - if ( !isset( $allowedTypes[strtolower( $col->type )] ) ) {
83 - $this->fail( "Table {$table->name} has column {$col->name} with non-native type '{$col->type}'" );
84 - }
85 - }
 66+ $result = Sqlite::checkSqlSyntax( "$IP/maintenance/tables.sql" );
 67+ if ( $result !== true ) {
 68+ $this->fail( $result );
8669 }
87 - $db->close();
8870 }
8971 }
\ No newline at end of file
Index: trunk/phase3/maintenance/sqlite.inc
@@ -0,0 +1,67 @@
 2+<?php
 3+
 4+/**
 5+ * This class contains code common to different SQLite-related maintenance scripts
 6+ */
 7+class Sqlite {
 8+
 9+ /**
 10+ * Checks whether PHP has SQLite support
 11+ * @return bool
 12+ */
 13+ public static function isPresent() {
 14+ wfSuppressWarnings();
 15+ $compiled = wfDl( 'pdo_sqlite' );
 16+ wfRestoreWarnings();
 17+ return $compiled;
 18+ }
 19+
 20+ /**
 21+ * Checks given files for correctness of SQL syntax. MySQL DDL will be converted to
 22+ * SQLite-compatible during processing.
 23+ * Will throw exceptions on SQL errors
 24+ * @return mixed true if no error or error string in case of errors
 25+ */
 26+ public static function checkSqlSyntax( $files ) {
 27+ if ( !Sqlite::isPresent() ) {
 28+ throw new MWException( "Can't check SQL syntax: SQLite not found" );
 29+ }
 30+ if ( !is_array( $files ) ) {
 31+ $files = array( $files );
 32+ }
 33+
 34+ $allowedTypes = array_flip( array(
 35+ 'integer',
 36+ 'real',
 37+ 'text',
 38+ 'blob', // NULL type is omitted intentionally
 39+ ) );
 40+
 41+ $db = new DatabaseSqliteStandalone( ':memory:' );
 42+ try {
 43+ foreach ( $files as $file ) {
 44+ $err = $db->sourceFile( $file );
 45+ if ( $err != true ) {
 46+ return $err;
 47+ }
 48+ }
 49+
 50+ $tables = $db->query( "SELECT name FROM sqlite_master WHERE type='table'", __METHOD__ );
 51+ foreach ( $tables as $table ) {
 52+ if ( strpos( $table->name, 'sqlite_' ) === 0 ) continue;
 53+
 54+ $columns = $db->query( "PRAGMA table_info({$table->name})", __METHOD__ );
 55+ foreach ( $columns as $col ) {
 56+ if ( !isset( $allowedTypes[strtolower( $col->type )] ) ) {
 57+ $db->close();
 58+ return "Table {$table->name} has column {$col->name} with non-native type '{$col->type}'";
 59+ }
 60+ }
 61+ }
 62+ } catch ( DBError $e ) {
 63+ return $e->getMessage();
 64+ }
 65+ $db->close();
 66+ return true;
 67+ }
 68+ };
\ No newline at end of file
Property changes on: trunk/phase3/maintenance/sqlite.inc
___________________________________________________________________
Added: svn:eol-style
169 + native
Index: trunk/phase3/maintenance/sqlite.php
@@ -29,6 +29,7 @@
3030 $this->addOption( 'vacuum', 'Clean up database by removing deleted pages. Decreases database file size' );
3131 $this->addOption( 'integrity', 'Check database for integrity' );
3232 $this->addOption( 'backup-to', 'Backup database to the given file', false, true );
 33+ $this->addOption( 'check-syntax', 'Check SQL file(s) for syntax errors', false, true );
3334 }
3435
3536 /**
@@ -42,6 +43,11 @@
4344 public function execute() {
4445 global $wgDBtype;
4546
 47+ // Should work even if we use a non-SQLite database
 48+ if ( $this->hasOption( 'check-syntax' ) ) {
 49+ $this->checkSyntax();
 50+ }
 51+
4652 if ( $wgDBtype != 'sqlite' ) {
4753 $this->error( "This maintenance script requires a SQLite database.\n" );
4854 return;
@@ -107,6 +113,20 @@
108114 $this->output( " Releasing lock...\n" );
109115 $this->db->query( 'COMMIT TRANSACTION', __METHOD__ );
110116 }
 117+
 118+ private function checkSyntax() {
 119+ if ( !Sqlite::IsPresent() ) {
 120+ $this->error( "Error: SQLite support not found\n" );
 121+ }
 122+ $files = array( $this->getOption( 'check-syntax' ) );
 123+ $files += $this->mArgs;
 124+ $result = Sqlite::checkSqlSyntax( $files );
 125+ if ( $result === true ) {
 126+ $this->output( "SQL syntax check: no errors detected.\n" );
 127+ } else {
 128+ $this->error( "Error: $result\n" );
 129+ }
 130+ }
111131 }
112132
113133 $maintClass = "SqliteMaintenance";
Index: trunk/phase3/includes/AutoLoader.php
@@ -670,6 +670,7 @@
671671 'ParserTestStaticParserHook' => 'maintenance/parserTestsStaticParserHook.php',
672672 'RemoteTestRecorder' => 'maintenance/parserTests.inc',
673673 'SevenZipStream' => 'maintenance/7zip.inc',
 674+ 'Sqlite' => 'maintenance/sqlite.inc',
674675 'TestFileIterator' => 'maintenance/parserTests.inc',
675676 'TestRecorder' => 'maintenance/parserTests.inc',
676677

Status & tagging log