]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - scripts/dumpschema.php
some more tweaking to do the mappings during filterDef; not totally sure I like it
[quix0rs-gnu-social.git] / scripts / dumpschema.php
1 #!/usr/bin/env php
2 <?php
3 /*
4  * StatusNet - a distributed open-source microblogging tool
5  * Copyright (C) 2008, 2009, StatusNet, Inc.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
22
23 $helptext = <<<END_OF_CHECKSCHEMA_HELP
24 Attempt to pull a schema definition for a given table.
25
26   --all     run over all defined core tables
27   --diff    show differences between the expected and live table defs
28   --raw     skip compatibility filtering for diffs
29   --update  dump SQL that would be run to update or create this table
30   --build   dump SQL that would be run to create this table fresh
31
32
33 END_OF_CHECKSCHEMA_HELP;
34
35 $longoptions = array('diff', 'all', 'build', 'update', 'raw');
36 require_once INSTALLDIR.'/scripts/commandline.inc';
37
38 function indentOptions($indent)
39 {
40     $cutoff = 3;
41     if ($indent < $cutoff) {
42         $space = $indent ? str_repeat(' ', $indent * 4) : '';
43         $sep = ",";
44         $lf = "\n";
45         $endspace = "$lf" . ($indent ? str_repeat(' ', ($indent - 1) * 4) : '');
46     } else {
47         $space = '';
48         $sep = ", ";
49         $lf = '';
50         $endspace = '';
51     }
52     if ($indent - 1 < $cutoff) {
53     }
54     return array($space, $sep, $lf, $endspace);
55 }
56
57 function prettyDumpArray($arr, $key=null, $indent=0)
58 {
59     // hack
60     if ($key == 'primary key') {
61         $subIndent = $indent + 2;
62     } else {
63         $subIndent = $indent + 1;
64     }
65
66     list($space, $sep, $lf, $endspace) = indentOptions($indent);
67     list($inspace, $insep, $inlf, $inendspace) = indentOptions($subIndent);
68
69     print "{$space}";
70     if (!is_numeric($key)) {
71         print "'$key' => ";
72     }
73     if (is_array($arr)) {
74         print "array({$inlf}";
75         $n = 0;
76         foreach ($arr as $key => $row) {
77             $n++;
78             prettyDumpArray($row, $key, $subIndent);
79             if ($n < count($arr)) {
80                 print "$insep$inlf";
81             }
82         }
83         // hack!
84         print "{$inendspace})";
85     } else {
86         print var_export($arr, true);
87     }
88 }
89
90 function getCoreSchema($tableName)
91 {
92     $schema = array();
93     include INSTALLDIR . '/db/core.php';
94     return $schema[$tableName];
95 }
96
97 function getCoreTables()
98 {
99     $schema = array();
100     include INSTALLDIR . '/db/core.php';
101     return array_keys($schema);
102 }
103
104 function dumpTable($tableName, $live)
105 {
106     if ($live) {
107         $schema = Schema::get();
108         $def = $schema->getTableDef($tableName);
109     } else {
110         // hack
111         $def = getCoreSchema($tableName);
112     }
113     prettyDumpArray($def, $tableName);
114     print "\n";
115 }
116
117 function dumpBuildTable($tableName)
118 {
119     echo "-- \n";
120     echo "-- $tableName\n";
121     echo "-- \n";
122
123     $schema = Schema::get();
124     $def = getCoreSchema($tableName);
125     $sql = $schema->buildCreateTable($tableName, $def);
126     $sql[] = '';
127
128     echo implode(";\n", $sql);
129     echo "\n";
130 }
131
132 function dumpEnsureTable($tableName)
133 {
134     $schema = Schema::get();
135     $def = getCoreSchema($tableName);
136     $sql = $schema->buildEnsureTable($tableName, $def);
137
138     if ($sql) {
139         echo "-- \n";
140         echo "-- $tableName\n";
141         echo "-- \n";
142
143         $sql[] = '';
144         echo implode(";\n", $sql);
145         echo "\n";
146     }
147 }
148
149 function dumpDiff($tableName, $filter)
150 {
151     $schema = Schema::get();
152     $def = getCoreSchema($tableName);
153     try {
154         $old = $schema->getTableDef($tableName);
155     } catch (Exception $e) {
156         // @fixme this is a terrible check :D
157         if (preg_match('/no such table/i', $e->getMessage())) {
158             return dumpTable($tableName, false);
159         } else {
160             throw $e;
161         }
162     }
163
164     if ($filter) {
165         //$old = $schema->filterDef($old);
166         $def = $schema->filterDef($def);
167     }
168
169     // @hack
170     $old = tweakPrimaryKey($old);
171     $def = tweakPrimaryKey($def);
172
173     $sections = array_unique(array_merge(array_keys($old), array_keys($def)));
174     $final = array();
175     foreach ($sections as $section) {
176         if ($section == 'fields') {
177             // this shouldn't be needed maybe... wait what?
178         }
179         $diff = $schema->diffArrays($old, $def, $section, $compare);
180         $chunks = array('del', 'mod', 'add');
181         foreach ($chunks as $chunk) {
182             if ($diff[$chunk]) {
183                 foreach ($diff[$chunk] as $key) {
184                     if ($chunk == 'del') {
185                         $final[$section]["DEL $key"] = $old[$section][$key];
186                     } else if ($chunk == 'add') {
187                         $final[$section]["ADD $key"] = $def[$section][$key];
188                     } else if ($chunk == 'mod') {
189                         $final[$section]["OLD $key"] = $old[$section][$key];
190                         $final[$section]["NEW $key"] = $def[$section][$key];
191                     }
192                 }
193             }
194         }
195     }
196
197     prettyDumpArray($final, $tableName);
198     print "\n";
199 }
200
201 function tweakPrimaryKey($def)
202 {
203     if (isset($def['primary key'])) {
204         $def['primary keys'] = array('primary key' => $def['primary key']);
205         unset($def['primary key']);
206     }
207     return $def;
208 }
209
210 if (have_option('all')) {
211     $args = getCoreTables();
212 }
213
214 if (count($args)) {
215     foreach ($args as $tableName) {
216         if (have_option('diff')) {
217             dumpDiff($tableName, !have_option('raw'));
218         } else if (have_option('build')) {
219             dumpBuildTable($tableName);
220         } else if (have_option('update')) {
221             dumpEnsureTable($tableName);
222         } else {
223             dumpTable($tableName, true);
224         }
225     }
226 } else {
227     show_help($helptext);
228 }