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 ); } // Postgres hacks if ( $this->getOption( 'type', 'mysql' ) === 'postgres' ) { // Remove table prefixes from Postgres schema, people should not set it // but better safe than sorry. $sql = str_replace( "\n/*_*/\n", ' ', $sql ); // MySQL goes with varbinary for collation reasons, but postgres can't // properly understand BYTEA type and works just fine with TEXT type // FIXME: This should be fixed at some point (T257755) $sql = str_replace( "BYTEA", 'TEXT', $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;