wiki.techinc.nl/maintenance/generateSchemaSql.php
Amir Sarabadani bfe636bb18 Add test to compare generated sql with the abstract schema
This helps preventing mistakes, for example if you don't know or you
forget to generate the sql schema for one or all of them.
Also it helps preventing malicious changes to the generated files that
might go in without much scrutiny as the manual files.

Bug: T252919
Change-Id: I50e2715a55914f7712f9925c149bd09e8265a20b
2020-05-16 19:57:54 +02:00

105 lines
3.2 KiB
PHP

<?php
/**
* Convert a JSON abstract schema to a schema file in the given DBMS type
*
* 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 Doctrine\SqlFormatter\NullHighlighter;
use Doctrine\SqlFormatter\SqlFormatter;
use Wikimedia\Rdbms\DoctrineSchemaBuilderFactory;
require_once __DIR__ . '/Maintenance.php';
/**
* Maintenance script to generate schema from abstract json files.
*
* @ingroup Maintenance
*/
class GenerateSchemaSql extends Maintenance {
public function __construct() {
parent::__construct();
$this->addDescription( 'Build SQL files from abstract JSON files' );
$this->addOption(
'json',
'Path to the json file. Default: tables.json',
false,
true
);
$this->addOption(
'sql',
'Path to output. Default: tables-generated.sql',
false,
true
);
$this->addOption(
'type',
'Can be either \'mysql\', \'sqlite\', or \'postgres\'. Default: mysql',
false,
true
);
}
public function execute() {
global $IP;
$jsonPath = $this->getOption( 'json', __DIR__ . '/tables.json' );
$relativeJsonPath = str_replace( "$IP/", '', $jsonPath );
$sqlPath = $this->getOption( 'sql', __DIR__ . '/tables-generated.sql' );
$abstractSchema = json_decode( file_get_contents( $jsonPath ), true );
$schemaBuilder = ( new DoctrineSchemaBuilderFactory() )->getSchemaBuilder(
$this->getOption( 'type', 'mysql' )
);
foreach ( $abstractSchema as $table ) {
$schemaBuilder->addTable( $table );
}
$sql = "-- This file is automatically generated using maintenance/generateSchemaSql.php.\n" .
"-- Source: $relativeJsonPath\n" .
"-- Do not modify this file directly.\n" .
"-- See https://www.mediawiki.org/wiki/Manual:Schema_changes\n";
$tables = $schemaBuilder->getSql();
if ( $tables !== [] ) {
// Temporary
$sql = $sql . implode( ";\n\n", $tables ) . ';';
$sql = ( new SqlFormatter( new NullHighlighter() ) )->format( $sql );
}
// Until the linting issue is resolved
// https://github.com/doctrine/sql-formatter/issues/53
$sql = str_replace( "\n/*_*/\n", " /*_*/", $sql );
$sql = str_replace( "; CREATE ", ";\nCREATE ", $sql );
$sql = str_replace(
"\n" . '/*$wgDBTableOptions*/' . ";",
' /*$wgDBTableOptions*/;' . "\n",
$sql
);
$sql = str_replace(
"\n" . '/*$wgDBTableOptions*/' . "\n;",
' /*$wgDBTableOptions*/;' . "\n",
$sql
);
file_put_contents( $sqlPath, $sql );
}
}
$maintClass = GenerateSchemaSql::class;
require_once RUN_MAINTENANCE_IF_MAIN;