| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  | #!/usr/bin/env php
 | 
					
						
							|  |  |  | <?php | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * StatusNet - a distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2008, 2009, StatusNet, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 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 Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $helptext = <<<END_OF_CHECKSCHEMA_HELP | 
					
						
							|  |  |  | Attempt to pull a schema definition for a given table. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-12 17:58:26 -07:00
										 |  |  |   --all     run over all defined core tables | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |   --diff    show differences between the expected and live table defs | 
					
						
							|  |  |  |   --raw     skip compatibility filtering for diffs | 
					
						
							| 
									
										
										
										
											2010-10-18 17:49:08 -07:00
										 |  |  |   --create  dump SQL that would be run to update or create this table | 
					
						
							| 
									
										
										
										
											2010-10-12 17:58:26 -07:00
										 |  |  |   --build   dump SQL that would be run to create this table fresh | 
					
						
							| 
									
										
										
										
											2010-10-19 17:07:37 -07:00
										 |  |  |   --checksum just output checksums from the source schema defs | 
					
						
							| 
									
										
										
										
											2010-10-12 17:58:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  | END_OF_CHECKSCHEMA_HELP; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 17:07:37 -07:00
										 |  |  | $longoptions = array('diff', 'all', 'create', 'update', 'raw', 'checksum'); | 
					
						
							| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  | require_once INSTALLDIR.'/scripts/commandline.inc'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  | function indentOptions($indent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     $cutoff = 3; | 
					
						
							|  |  |  |     if ($indent < $cutoff) { | 
					
						
							| 
									
										
										
										
											2010-10-07 17:01:14 -07:00
										 |  |  |         $space = $indent ? str_repeat(' ', $indent * 4) : ''; | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  |         $sep = ","; | 
					
						
							|  |  |  |         $lf = "\n"; | 
					
						
							| 
									
										
										
										
											2010-10-07 17:01:14 -07:00
										 |  |  |         $endspace = "$lf" . ($indent ? str_repeat(' ', ($indent - 1) * 4) : ''); | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         $space = ''; | 
					
						
							|  |  |  |         $sep = ", "; | 
					
						
							|  |  |  |         $lf = ''; | 
					
						
							|  |  |  |         $endspace = ''; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ($indent - 1 < $cutoff) { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return array($space, $sep, $lf, $endspace); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function prettyDumpArray($arr, $key=null, $indent=0) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-07 16:23:36 -07:00
										 |  |  |     // hack
 | 
					
						
							|  |  |  |     if ($key == 'primary key') { | 
					
						
							|  |  |  |         $subIndent = $indent + 2; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         $subIndent = $indent + 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  |     list($space, $sep, $lf, $endspace) = indentOptions($indent); | 
					
						
							| 
									
										
										
										
											2010-10-07 16:23:36 -07:00
										 |  |  |     list($inspace, $insep, $inlf, $inendspace) = indentOptions($subIndent); | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     print "{$space}"; | 
					
						
							|  |  |  |     if (!is_numeric($key)) { | 
					
						
							|  |  |  |         print "'$key' => "; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (is_array($arr)) { | 
					
						
							|  |  |  |         print "array({$inlf}"; | 
					
						
							|  |  |  |         $n = 0; | 
					
						
							|  |  |  |         foreach ($arr as $key => $row) { | 
					
						
							|  |  |  |             $n++; | 
					
						
							| 
									
										
										
										
											2010-10-07 16:23:36 -07:00
										 |  |  |             prettyDumpArray($row, $key, $subIndent); | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  |             if ($n < count($arr)) { | 
					
						
							|  |  |  |                 print "$insep$inlf"; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // hack!
 | 
					
						
							|  |  |  |         print "{$inendspace})"; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         print var_export($arr, true); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | function getCoreSchema($tableName) | 
					
						
							| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  |     $schema = array(); | 
					
						
							|  |  |  |     include INSTALLDIR . '/db/core.php'; | 
					
						
							|  |  |  |     return $schema[$tableName]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-07 17:02:42 -07:00
										 |  |  | function getCoreTables() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     $schema = array(); | 
					
						
							|  |  |  |     include INSTALLDIR . '/db/core.php'; | 
					
						
							|  |  |  |     return array_keys($schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | function dumpTable($tableName, $live) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if ($live) { | 
					
						
							|  |  |  |         $schema = Schema::get(); | 
					
						
							|  |  |  |         $def = $schema->getTableDef($tableName); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         // hack
 | 
					
						
							|  |  |  |         $def = getCoreSchema($tableName); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-07 15:48:38 -07:00
										 |  |  |     prettyDumpArray($def, $tableName); | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |     print "\n"; | 
					
						
							| 
									
										
										
										
											2010-10-11 19:10:51 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function dumpBuildTable($tableName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     echo "-- \n"; | 
					
						
							|  |  |  |     echo "-- $tableName\n"; | 
					
						
							|  |  |  |     echo "-- \n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $schema = Schema::get(); | 
					
						
							|  |  |  |     $def = getCoreSchema($tableName); | 
					
						
							|  |  |  |     $sql = $schema->buildCreateTable($tableName, $def); | 
					
						
							|  |  |  |     $sql[] = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     echo implode(";\n", $sql); | 
					
						
							| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  |     echo "\n"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-12 17:58:26 -07:00
										 |  |  | function dumpEnsureTable($tableName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     $schema = Schema::get(); | 
					
						
							|  |  |  |     $def = getCoreSchema($tableName); | 
					
						
							|  |  |  |     $sql = $schema->buildEnsureTable($tableName, $def); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 16:04:28 -07:00
										 |  |  |     if ($sql) { | 
					
						
							|  |  |  |         echo "-- \n"; | 
					
						
							|  |  |  |         echo "-- $tableName\n"; | 
					
						
							|  |  |  |         echo "-- \n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $sql[] = ''; | 
					
						
							|  |  |  |         echo implode(";\n", $sql); | 
					
						
							|  |  |  |         echo "\n"; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-12 17:58:26 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  | function dumpDiff($tableName, $filter) | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |     $schema = Schema::get(); | 
					
						
							|  |  |  |     $def = getCoreSchema($tableName); | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         $old = $schema->getTableDef($tableName); | 
					
						
							|  |  |  |     } catch (Exception $e) { | 
					
						
							|  |  |  |         // @fixme this is a terrible check :D
 | 
					
						
							| 
									
										
										
										
											2010-10-13 17:35:18 -07:00
										 |  |  |         if (preg_match('/no such table/i', $e->getMessage())) { | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |             return dumpTable($tableName, false); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             throw $e; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |     if ($filter) { | 
					
						
							| 
									
										
										
										
											2010-10-15 16:32:37 -07:00
										 |  |  |         //$old = $schema->filterDef($old);
 | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |         $def = $schema->filterDef($def); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // @hack
 | 
					
						
							|  |  |  |     $old = tweakPrimaryKey($old); | 
					
						
							|  |  |  |     $def = tweakPrimaryKey($def); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $sections = array_unique(array_merge(array_keys($old), array_keys($def))); | 
					
						
							|  |  |  |     $final = array(); | 
					
						
							|  |  |  |     foreach ($sections as $section) { | 
					
						
							|  |  |  |         if ($section == 'fields') { | 
					
						
							|  |  |  |             // this shouldn't be needed maybe... wait what?
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-10-29 15:11:41 -07:00
										 |  |  |         $diff = $schema->diffArrays($old, $def, $section); | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |         $chunks = array('del', 'mod', 'add'); | 
					
						
							|  |  |  |         foreach ($chunks as $chunk) { | 
					
						
							|  |  |  |             if ($diff[$chunk]) { | 
					
						
							|  |  |  |                 foreach ($diff[$chunk] as $key) { | 
					
						
							|  |  |  |                     if ($chunk == 'del') { | 
					
						
							|  |  |  |                         $final[$section]["DEL $key"] = $old[$section][$key]; | 
					
						
							|  |  |  |                     } else if ($chunk == 'add') { | 
					
						
							|  |  |  |                         $final[$section]["ADD $key"] = $def[$section][$key]; | 
					
						
							|  |  |  |                     } else if ($chunk == 'mod') { | 
					
						
							|  |  |  |                         $final[$section]["OLD $key"] = $old[$section][$key]; | 
					
						
							|  |  |  |                         $final[$section]["NEW $key"] = $def[$section][$key]; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |     prettyDumpArray($final, $tableName); | 
					
						
							|  |  |  |     print "\n"; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  | function tweakPrimaryKey($def) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (isset($def['primary key'])) { | 
					
						
							|  |  |  |         $def['primary keys'] = array('primary key' => $def['primary key']); | 
					
						
							|  |  |  |         unset($def['primary key']); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-29 15:11:41 -07:00
										 |  |  |     if (isset($def['description'])) { | 
					
						
							|  |  |  |         $def['descriptions'] = array('description' => $def['description']); | 
					
						
							|  |  |  |         unset($def['description']); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |     return $def; | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 17:07:37 -07:00
										 |  |  | function dumpChecksum($tableName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     $schema = Schema::get(); | 
					
						
							|  |  |  |     $def = getCoreSchema($tableName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $updater = new SchemaUpdater($schema); | 
					
						
							|  |  |  |     $checksum = $updater->checksum($def); | 
					
						
							|  |  |  |     $old = @$updater->checksums[$tableName]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($old == $checksum) { | 
					
						
							|  |  |  |         echo "OK  $checksum $tableName\n"; | 
					
						
							|  |  |  |     } else if (!$old) { | 
					
						
							|  |  |  |         echo "NEW $checksum $tableName\n"; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         echo "MOD $checksum $tableName (was $old)\n"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-07 17:02:42 -07:00
										 |  |  | if (have_option('all')) { | 
					
						
							|  |  |  |     $args = getCoreTables(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  | if (count($args)) { | 
					
						
							|  |  |  |     foreach ($args as $tableName) { | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  |         if (have_option('diff')) { | 
					
						
							| 
									
										
										
										
											2010-10-13 16:58:28 -07:00
										 |  |  |             dumpDiff($tableName, !have_option('raw')); | 
					
						
							| 
									
										
										
										
											2010-10-18 17:49:08 -07:00
										 |  |  |         } else if (have_option('create')) { | 
					
						
							| 
									
										
										
										
											2010-10-11 19:10:51 -07:00
										 |  |  |             dumpBuildTable($tableName); | 
					
						
							| 
									
										
										
										
											2010-10-12 17:58:26 -07:00
										 |  |  |         } else if (have_option('update')) { | 
					
						
							|  |  |  |             dumpEnsureTable($tableName); | 
					
						
							| 
									
										
										
										
											2010-10-19 17:07:37 -07:00
										 |  |  |         } else if (have_option('checksum')) { | 
					
						
							|  |  |  |             dumpChecksum($tableName); | 
					
						
							| 
									
										
										
										
											2010-10-07 16:49:15 -07:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             dumpTable($tableName, true); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-10-06 18:28:19 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | } else { | 
					
						
							|  |  |  |     show_help($helptext); | 
					
						
							|  |  |  | } |