forked from GNUsocial/gnu-social
		
	
		
			
				
	
	
		
			253 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| #!/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.
 | |
| 
 | |
|   --all     run over all defined core tables
 | |
|   --diff    show differences between the expected and live table defs
 | |
|   --raw     skip compatibility filtering for diffs
 | |
|   --create  dump SQL that would be run to update or create this table
 | |
|   --build   dump SQL that would be run to create this table fresh
 | |
|   --checksum just output checksums from the source schema defs
 | |
| 
 | |
| 
 | |
| END_OF_CHECKSCHEMA_HELP;
 | |
| 
 | |
| $longoptions = array('diff', 'all', 'create', 'update', 'raw', 'checksum');
 | |
| require_once INSTALLDIR.'/scripts/commandline.inc';
 | |
| 
 | |
| function indentOptions($indent)
 | |
| {
 | |
|     $cutoff = 3;
 | |
|     if ($indent < $cutoff) {
 | |
|         $space = $indent ? str_repeat(' ', $indent * 4) : '';
 | |
|         $sep = ",";
 | |
|         $lf = "\n";
 | |
|         $endspace = "$lf" . ($indent ? str_repeat(' ', ($indent - 1) * 4) : '');
 | |
|     } else {
 | |
|         $space = '';
 | |
|         $sep = ", ";
 | |
|         $lf = '';
 | |
|         $endspace = '';
 | |
|     }
 | |
|     if ($indent - 1 < $cutoff) {
 | |
|     }
 | |
|     return array($space, $sep, $lf, $endspace);
 | |
| }
 | |
| 
 | |
| function prettyDumpArray($arr, $key=null, $indent=0)
 | |
| {
 | |
|     // hack
 | |
|     if ($key == 'primary key') {
 | |
|         $subIndent = $indent + 2;
 | |
|     } else {
 | |
|         $subIndent = $indent + 1;
 | |
|     }
 | |
| 
 | |
|     list($space, $sep, $lf, $endspace) = indentOptions($indent);
 | |
|     list($inspace, $insep, $inlf, $inendspace) = indentOptions($subIndent);
 | |
| 
 | |
|     print "{$space}";
 | |
|     if (!is_numeric($key)) {
 | |
|         print "'$key' => ";
 | |
|     }
 | |
|     if (is_array($arr)) {
 | |
|         print "array({$inlf}";
 | |
|         $n = 0;
 | |
|         foreach ($arr as $key => $row) {
 | |
|             $n++;
 | |
|             prettyDumpArray($row, $key, $subIndent);
 | |
|             if ($n < count($arr)) {
 | |
|                 print "$insep$inlf";
 | |
|             }
 | |
|         }
 | |
|         // hack!
 | |
|         print "{$inendspace})";
 | |
|     } else {
 | |
|         print var_export($arr, true);
 | |
|     }
 | |
| }
 | |
| 
 | |
| function getCoreSchema($tableName)
 | |
| {
 | |
|     $schema = array();
 | |
|     include INSTALLDIR . '/db/core.php';
 | |
|     return $schema[$tableName];
 | |
| }
 | |
| 
 | |
| function getCoreTables()
 | |
| {
 | |
|     $schema = array();
 | |
|     include INSTALLDIR . '/db/core.php';
 | |
|     return array_keys($schema);
 | |
| }
 | |
| 
 | |
| function dumpTable($tableName, $live)
 | |
| {
 | |
|     if ($live) {
 | |
|         $schema = Schema::get();
 | |
|         $def = $schema->getTableDef($tableName);
 | |
|     } else {
 | |
|         // hack
 | |
|         $def = getCoreSchema($tableName);
 | |
|     }
 | |
|     prettyDumpArray($def, $tableName);
 | |
|     print "\n";
 | |
| }
 | |
| 
 | |
| 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);
 | |
|     echo "\n";
 | |
| }
 | |
| 
 | |
| function dumpEnsureTable($tableName)
 | |
| {
 | |
|     $schema = Schema::get();
 | |
|     $def = getCoreSchema($tableName);
 | |
|     $sql = $schema->buildEnsureTable($tableName, $def);
 | |
| 
 | |
|     if ($sql) {
 | |
|         echo "-- \n";
 | |
|         echo "-- $tableName\n";
 | |
|         echo "-- \n";
 | |
| 
 | |
|         $sql[] = '';
 | |
|         echo implode(";\n", $sql);
 | |
|         echo "\n";
 | |
|     }
 | |
| }
 | |
| 
 | |
| function dumpDiff($tableName, $filter)
 | |
| {
 | |
|     $schema = Schema::get();
 | |
|     $def = getCoreSchema($tableName);
 | |
|     try {
 | |
|         $old = $schema->getTableDef($tableName);
 | |
|     } catch (Exception $e) {
 | |
|         // @fixme this is a terrible check :D
 | |
|         if (preg_match('/no such table/i', $e->getMessage())) {
 | |
|             return dumpTable($tableName, false);
 | |
|         } else {
 | |
|             throw $e;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ($filter) {
 | |
|         //$old = $schema->filterDef($old);
 | |
|         $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?
 | |
|         }
 | |
|         $diff = $schema->diffArrays($old, $def, $section);
 | |
|         $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];
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     prettyDumpArray($final, $tableName);
 | |
|     print "\n";
 | |
| }
 | |
| 
 | |
| function tweakPrimaryKey($def)
 | |
| {
 | |
|     if (isset($def['primary key'])) {
 | |
|         $def['primary keys'] = array('primary key' => $def['primary key']);
 | |
|         unset($def['primary key']);
 | |
|     }
 | |
|     if (isset($def['description'])) {
 | |
|         $def['descriptions'] = array('description' => $def['description']);
 | |
|         unset($def['description']);
 | |
|     }
 | |
|     return $def;
 | |
| }
 | |
| 
 | |
| 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";
 | |
|     }
 | |
| }
 | |
| 
 | |
| if (have_option('all')) {
 | |
|     $args = getCoreTables();
 | |
| }
 | |
| 
 | |
| if (count($args)) {
 | |
|     foreach ($args as $tableName) {
 | |
|         if (have_option('diff')) {
 | |
|             dumpDiff($tableName, !have_option('raw'));
 | |
|         } else if (have_option('create')) {
 | |
|             dumpBuildTable($tableName);
 | |
|         } else if (have_option('update')) {
 | |
|             dumpEnsureTable($tableName);
 | |
|         } else if (have_option('checksum')) {
 | |
|             dumpChecksum($tableName);
 | |
|         } else {
 | |
|             dumpTable($tableName, true);
 | |
|         }
 | |
|     }
 | |
| } else {
 | |
|     show_help($helptext);
 | |
| } |