5use Doctrine\SqlFormatter\NullHighlighter;
6use Doctrine\SqlFormatter\SqlFormatter;
24 $json = file_get_contents( $jsonPath );
31 $abstractSchema = json_decode( $json,
true, 512, JSON_THROW_ON_ERROR );
32 }
catch ( JsonException $e ) {
33 throw new AbstractSchemaValidationError(
"Invalid JSON schema: " . $e->getMessage(), 0, $e );
36 $validator =
new AbstractSchemaValidator();
37 $validator->validate( $jsonPath );
39 return $abstractSchema;
45 public function generateSchema(
string $platform,
string $jsonPath ): string {
46 $abstractSchemaChange = $this->validateAndGetSchema( $jsonPath );
48 $sql = $this->makeSQLComment(
'generateSchemaSql.php', $jsonPath );
52 foreach ( $abstractSchemaChange as $table ) {
53 $schemaBuilder->addTable( $table );
55 $tableSqls = $schemaBuilder->getSql();
57 $sql .= $this->cleanupSqlArray( $platform, $tableSqls );
66 $abstractSchemaChange = $this->validateAndGetSchema( $jsonPath );
68 $sql = $this->makeSQLComment(
'generateSchemaChangeSql.php', $jsonPath );
72 $schemaChangeSqls = $schemaChangeBuilder->getSchemaChangeSql( $abstractSchemaChange );
73 if ( !$schemaChangeSqls ) {
77 $sql .= $this->cleanupSqlArray( $platform, $schemaChangeSqls );
82 private function makeSQLComment(
string $scriptName,
string $jsonPath ): string {
85 $installPath = realpath(
$IP );
86 $jsonPath = realpath( $jsonPath );
89 if ( DIRECTORY_SEPARATOR ===
'\\' ) {
90 $installPath = strtr( $installPath,
'\\',
'/' );
91 $jsonPath = strtr( $jsonPath,
'\\',
'/' );
94 $canonicalJsonPath = str_replace(
"$installPath/",
'', $jsonPath );
95 $canonicalJsonPath = preg_replace(
'!^extensions/[^/]+/!',
'', $canonicalJsonPath );
97 return "-- This file is automatically generated using maintenance/$scriptName.\n" .
98 "-- Source: $canonicalJsonPath\n" .
99 "-- Do not modify this file directly.\n" .
100 "-- See https://www.mediawiki.org/wiki/Manual:Schema_changes\n";
111 private function cleanupSqlArray(
string $platform, array $sqlArray ): string {
117 $sql = implode(
";\n\n", $sqlArray ) .
';';
118 $sql = (
new SqlFormatter(
new NullHighlighter() ) )->format( $sql );
121 if ( $platform ===
'postgres' ) {
126 [
"WHERE\n ",
"\n /*_*/\n ",
" ",
" );",
"KEY(\n " ],
127 [
"WHERE",
' ',
" ",
');',
"KEY(\n " ],
135 $sql = preg_replace(
"!\s+/\*_\*/\s+!",
" /*_*/", $sql );
137 '!\s+/\*\$wgDBTableOptions\*/\s+;!',
138 ' /*$wgDBTableOptions*/;',
142 $sql = str_replace(
"; CREATE ",
";\n\nCREATE ", $sql );
143 $sql = str_replace(
";\n\nCREATE TABLE ",
";\n\n\nCREATE TABLE ", $sql );
144 $sql = preg_replace(
'/^(CREATE|DROP|ALTER)\s+(TABLE|VIEW|INDEX)\s+/m',
'$1 $2 ', $sql );
145 $sql = preg_replace(
'/(?<!\s|;)\s+(ADD|DROP|ALTER|MODIFY|CHANGE|RENAME)\s+/',
"\n \$1 ", $sql );
147 $sql = str_replace(
"; ",
";\n", $sql );
149 if ( !str_ends_with( $sql,
"\n" ) ) {
154 if ( $platform ===
'sqlite' ) {
157 $sql = preg_replace(
'/__temp__\s*\/\*_\*\//',
'/*_*/__temp__', $sql );
if(!defined( 'MEDIAWIKI')) if(ini_get('mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
if(!defined('MW_SETUP_CALLBACK'))
Helper to generate abstract schema and schema changes in maintenance scripts.
generateSchemaChange(string $platform, string $jsonPath)
generateSchema(string $platform, string $jsonPath)
validateAndGetSchema(string $jsonPath)
Fetches the abstract schema.