$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;
-require_once INSTALLDIR.'/scripts/commandline.inc';
+$longoptions = array('diff', 'all', 'create', 'update', 'raw', 'checksum');
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
+
+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)
+function dumpTable($tableName, $live)
{
- echo "$tableName\n";
+ 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 = $schema->getTableDef($tableName);
- var_export($def);
+ $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) {
- dumpTable($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);
-}
\ No newline at end of file
+}