MediaWiki REL1_37
generateSchemaChangeSql.php
Go to the documentation of this file.
1<?php
2
25use Doctrine\SqlFormatter\NullHighlighter;
26use Doctrine\SqlFormatter\SqlFormatter;
28
29require_once __DIR__ . '/Maintenance.php';
30
37 public function __construct() {
38 parent::__construct();
39 $this->addDescription( 'Build SQL files from abstract JSON files' );
40
41 $this->addOption(
42 'json',
43 'Path to the json file.',
44 true,
45 true
46 );
47 $this->addOption(
48 'sql',
49 'Path to output.',
50 true,
51 true
52 );
53 $this->addOption(
54 'type',
55 'Can be either \'mysql\', \'sqlite\', or \'postgres\'. Default: mysql',
56 false,
57 true
58 );
59 }
60
61 public function execute() {
62 global $IP;
63 $jsonPath = $this->getOption( 'json' );
64 $relativeJsonPath = str_replace( "$IP/", '', $jsonPath );
65 $sqlPath = $this->getOption( 'sql' );
66 $abstractSchemaChange = json_decode( file_get_contents( $jsonPath ), true );
67
68 if ( $abstractSchemaChange === null ) {
69 $this->fatalError( "'$jsonPath' seems to be invalid json. Check the syntax and try again!" );
70 }
71
72 $schemaChangeBuilder = ( new DoctrineSchemaBuilderFactory() )->getSchemaChangeBuilder(
73 $this->getOption( 'type', 'mysql' )
74 );
75
76 $schemaChangeSqls = $schemaChangeBuilder->getSchemaChangeSql( $abstractSchemaChange );
77
78 $sql = "-- This file is automatically generated using maintenance/generateSchemaChangeSql.php.\n" .
79 "-- Source: $relativeJsonPath\n" .
80 "-- Do not modify this file directly.\n" .
81 "-- See https://www.mediawiki.org/wiki/Manual:Schema_changes\n";
82
83 if ( $schemaChangeSqls !== [] ) {
84 // Temporary
85 $sql .= implode( ";\n\n", $schemaChangeSqls ) . ';';
86 $sql = ( new SqlFormatter( new NullHighlighter() ) )->format( $sql );
87 }
88
89 // Postgres hacks
90 if ( $this->getOption( 'type', 'mysql' ) === 'postgres' ) {
91 // Remove table prefixes from Postgres schema, people should not set it
92 // but better safe than sorry.
93 $sql = str_replace( "\n/*_*/\n", ' ', $sql );
94
95 // MySQL goes with varbinary for collation reasons, but postgres can't
96 // properly understand BYTEA type and works just fine with TEXT type
97 // FIXME: This should be fixed at some point (T257755)
98 $sql = str_replace( "BYTEA", 'TEXT', $sql );
99 }
100
101 // Until the linting issue is resolved
102 // https://github.com/doctrine/sql-formatter/issues/53
103 $sql = str_replace( "\n/*_*/\n", " /*_*/", $sql );
104 $sql = str_replace( "; ", ";\n", $sql );
105 $sql = preg_replace( "/\n+? +?/", ' ', $sql );
106 $sql = str_replace( "/*_*/ ", "/*_*/", $sql );
107
108 // Sqlite hacks
109 if ( $this->getOption( 'type', 'mysql' ) === 'sqlite' ) {
110 // Doctrine prepends __temp__ to the table name and we set the table with the schema prefix causing invalid
111 // sqlite.
112 $sql = str_replace( '__temp__ /*_*/', '/*_*/__temp__', $sql );
113 }
114
115 file_put_contents( $sqlPath, $sql );
116 }
117
118}
119
120$maintClass = GenerateSchemaChangeSql::class;
121require_once RUN_MAINTENANCE_IF_MAIN;
$IP
Definition WebStart.php:49
Maintenance script to generate schema from abstract json files.
__construct()
Default constructor.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.