Mercurial > hg > fapweb
diff managedb.php @ 529:ddbc84031a7b
Rename createdb.php to managedb.php
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 10 Dec 2013 17:51:20 +0200 |
parents | createdb.php@dd5c5577c495 |
children | f872843ae396 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/managedb.php Tue Dec 10 17:51:20 2013 +0200 @@ -0,0 +1,774 @@ +#!/usr/bin/php +<? +require_once "mconfig.inc.php"; +require_once "msite.inc.php"; + +stCheckCLIExec(); + +$dbVersion = 11; + +$dbMeta = array( + "dbVersion" => array(VT_INT, $dbVersion, "Database version"), +); + + +// +// Site settings and defaults we put in +// +$siteDefaults = array( + "maxAttendeesHard" => array(VT_INT, 60, "Maximum attendees (HARD limit, <= 0 means no limit)"), + "maxAttendeesSoft" => array(VT_INT, 50, "Maximum attendees (soft limit, <= 0 means no limit)"), + + "userTimeout" => array(VT_INT, 120, "User pages (voting) timeout in minutes"), + "admTimeout" => array(VT_INT, 15, "Administration interface timeout in minutes"), + + "showAdmin" => array(VT_BOOL, false, "Always show administration interface link on the menu"), + "showAttendees" => array(VT_BOOL, true, "Show attendees list"), + "allowRegister" => array(VT_BOOL, false, "Enable event registration"), + "allowVoting" => array(VT_BOOL, false, "Enable voting (individual compos must be enabled as well)"), + + "showResults" => array(VT_BOOL, false, "Enable results page"), + "showResAuthors" => array(VT_BOOL, true, "Show entry authors on results page"), + + "requireEMail" => array(VT_BOOL, false, "Require e-mail address in registrations"), + + "showNews" => array(VT_BOOL, true, "Enable News link on main menu"), + "showNewsOnAbout" => array(VT_BOOL, true, "Show latest news item on About page"), + + "registerInfoText" => array(VT_TEXT, "<p> +Only your <b>handle</b> and the answer to the botcheck are strictly required. +If you plan on joining the IRC channel +(<a href=\"irc://#fap2013@ircnet\">#fap2013 @ IRCNet</a>) or staying up to date by other means, +<b>e-mail</b> is not required either. +</p>", "Registration page info text"), + + "registerPostText" => array(VT_TEXT, " +<h1>Registration successful</h1> +<p>Now go make a demo about it!</p>", + "Successful post-registration note text"), + + "registerLimitExceeded" => array(VT_TEXT, " +<h1>Sorry, registration disabled!</h1> +<p> +Registration to the event is not available at this time due to +number of attendees limit having been reached. <b>:(</b> +</p> +", + "Registration attendee limit exceeded note text"), + + "registerNotEnabled" => array(VT_TEXT, " +<h1>Sorry, registration disabled!</h1> +<p> +Registration to the event is not enabled at this time. +</p> +", + "Registration not enabled note text"), + + "registerPostNoEmail" => array(VT_TEXT, " +<h2>By the way ...</h2> +<p>As you did not specify an e-mail contact address, you'll have to get updates +and information about the location (if you don't already know it) by +some other means (IRC, for example.)</p> +", "No e-mail address registration note"), + + "eventDescription" => array(VT_TEXT, " +<h1>Event program & schedule</h1> +<ul> + <li><b>Aegis</b> of DSS and FAG will be performing a DJ gig.</li> + <li>.. and possible additional live acts. More info to come.</li> +</ul> + +<h2>Friday 30.11.</h2> +<ul> + <li><b>18:00</b> - <i>Doors open</i>.</li> + <li><b>22:00</b> - DJ set by Aegis.</li> +</ul> + +<h2>Saturday 1.12.</h2> +<ul> + <li><b>14:00</b> - Deadline for remote entries.</li> + <li><b>18:00</b> - Deadline for the entries delivered on location.</li> + <li><b>20:00</b> - Competitions start.</li> +</ul> + +Competition schedule and voting deadline will depend on number of entries. + +<h2>Sunday 2.12.</h2> +<ul> + <li><b>12:00</b> - Party over?</li> +</ul> +", "Event general description / timetables etc."), + + + "compoDescription" => array(VT_TEXT, " +<h1>General</h1> +<p class=\"notice\"> +YOU <b>MUST</b> HAVE AT LEAST ONE ENTRY TO COMPETITIONS IF YOU COME TO THE PARTY. +</p> + +<p class=\"note\"> +If there are enough entries, then AGA/OCS/ECS demos will be run in separate compos. +<br /> +Remote entries are welcome! +</p> + +<p> +The compo machine will be an <b>A1200 with an 060/50 and lots of +RAM</b>. An <b>A500 1.3 512k/512k</b> will also be available if your +prod is not AGA compatible. +</p> + +<h1>Compos</h1> +", "Compo general description"), + + + "siteInfoText" => array(VT_TEXT, " +<a href=\"about\"> +<img src=\"img/fapsm.png\" alt=\"Finnish Amiga Party 2013\" class=\"logo\" /></a> +<div id=\"date\"> +5.-8.12.2013<br /> +Helsinki, Finland<br /> +@ old location<br /> +<span class=\"notice\">Entry 15 EUR + prod</span> +</div>", "Site header text"), + + + "newsHeader" => array(VT_TEXT, "", "News page header text"), + + + "aboutDescription" => array(VT_TEXT, " +<div style=\"text-align: center;\"> +<img src=\"img/fap.png\" alt=\"FAP\" /> +<p> +Pure Amiga demoscene party, all traditional Amiga compos and purely Amiga-oriented program. +<br /> +<span class=\"notice\"> +YOU <b>MUST</b> HAVE AT LEAST ONE ENTRY TO COMPETITIONS IF YOU COME TO THE PARTY. +</span> +</p> +</div>", + "About page text"), + + "voteFinishedText" => array(VT_TEXT, " +<h1>Yay, you have voted!</h1> +<p>Now go FAP some more! And make a demo about it.</p>", + "Message shown after successful voting."), + + "siteMenuHeader" => array(VT_TEXT, "<div>13.FAP:> <span class=\"mblink\">■</span></div>", "Site menu header text"), + "siteMenuFooter" => array(VT_TEXT, "", "Site menu footer text"), + "siteExtraHTML" => array(VT_TEXT, "<div id=\"sponsors\">Gentle Eye</div>", "Extra global HTML code (f.e. sponsors box)"), +); + + +// +// +// +$sqlTables = array( + // Database metadata + "dbmeta" => array( + array("key" , "VARCHAR(32)", "PRIMARY KEY"), + array("vtype" , "INT"), + array("vstr" , "VARCHAR(128)"), + array("vtext" , "TEXT"), + array("vint" , "INT"), + array("sdesc" , "VARCHAR(128)"), + ), + + // Site settings + "settings" => array( + array("key" , "VARCHAR(32)", "PRIMARY KEY"), + array("vtype" , "INT"), + array("vstr" , "VARCHAR(128)"), + array("vtext" , "TEXT"), + array("vint" , "INT"), + array("sdesc" , "VARCHAR(128)"), + ), + + "news" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("utime" , "INT"), + array("title" , "VARCHAR(".SET_LEN_NEWS_TITLE.")"), + array("text" , "VARCHAR(".SET_LEN_NEWS_TEXT.")"), + array("author" , "VARCHAR(".SET_LEN_NEWS_AUTHOR.")"), + array("persist" , "INT", "DEFAULT 0"), + ), + + "compos" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("name" , "VARCHAR(".SET_LEN_COMPO_NAME.")"), + array("description" , "VARCHAR(".SET_LEN_COMPO_DESC.")"), + array("visible" , "INT", "DEFAULT 0"), + array("voting" , "INT", "DEFAULT 0"), + array("showAuthors" , "INT", "DEFAULT 0"), + array("type" , "INT", "DEFAULT 0"), + ), + + "entries" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("show_id" , "INT", "DEFAULT 0"), + array("name" , "VARCHAR(".SET_LEN_ENTRY_NAME.")"), + array("author" , "VARCHAR(".SET_LEN_ENTRY_AUTHOR.")"), + array("compo_id" , "INT", "DEFAULT 0"), + array("filename" , "VARCHAR(".SET_LEN_ENTRY_FILENAME.")", "DEFAULT NULL"), + array("info" , "VARCHAR(".SET_LEN_ENTRY_INFO.")", "DEFAULT NULL"), + array("notes" , "VARCHAR(".SET_LEN_ENTRY_NOTES.")", "DEFAULT NULL"), + array("preview_file" , "VARCHAR(".SET_LEN_ENTRY_PREVIEW_FILE.")", "DEFAULT NULL"), + array("preview_type" , "INT", "DEFAULT 0"), + array("flags" , "INT", "DEFAULT 0"), + ), + + "attendees" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("regtime" , "INT"), + array("name" , "VARCHAR(".SET_LEN_USERNAME.")"), + array("groups" , "VARCHAR(".SET_LEN_GROUPS.")"), + array("oneliner" , "VARCHAR(".SET_LEN_ONELINER.")"), + array("email" , "VARCHAR(".SET_LEN_EMAIL.")"), + array("key_id" , "INT", "DEFAULT NULL"), + ), + + "votekeys" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("key" , "VARCHAR(".SET_LEN_VOTEKEY.")"), + array("active" , "INT", "DEFAULT 0"), + ), + + "votes" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("entry_id" , "INT", "DEFAULT NULL"), + array("key_id" , "INT", "DEFAULT 0"), + array("value" , "INT", "DEFAULT 0"), + ), + + + // Party information system tables + "displayVars" => array( + array("key" , "VARCHAR(32)", "PRIMARY KEY"), + array("vtype" , "INT"), + array("vstr" , "VARCHAR(128)"), + array("vtext" , "TEXT"), + array("vint" , "INT"), + array("sdesc" , "VARCHAR(128)"), + ), + + "displaySlides" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("title" , "VARCHAR(".SET_LEN_DISP_SLIDE_TITLE.")"), + array("text" , "VARCHAR(".SET_LEN_DISP_SLIDE_TEXT.")"), + ), + + "rotationListData" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("name" , "VARCHAR(".SET_LEN_ROT_LIST_NAME.")"), + ), + + "rotationListSlides" => array( + array("id" , "INTEGER", "PRIMARY KEY", "AUTOINCREMENT"), + array("list_id" , "INT", "DEFAULT 0"), + array("slide_id" , "INT", "DEFAULT 0"), + array("order_num" , "INT", "DEFAULT 0"), + ), +); + + +// +// Party information system settings / data +// +$siteDisplayVars = array( + "showMode" => array(VT_INT, 0, "Currently active display mode"), + "rotateDuration" => array(VT_INT, 15, "Slide rotation time per slide (seconds)"), + + "tempDuration" => array(VT_INT, 5, "Temporary slide display time (minutes)"), + "tempSlide" => array(VT_INT, 0, "Temporary slide ID"), + + "compoID" => array(VT_INT, 0, "Compo ID of current compo"), + "compoPrevEntry" => array(VT_INT, 0, "Previously shown compo entry"), + "compoCurrEntry" => array(VT_INT, 0, "Current / next compo entry to be shown"), + + // Not user-manageable + "tempSlideSet" => array(VT_BOOL, false, "Temporary slide set"), + + "activeSlideMode" => array(VT_INT, 0, "Current active slide display mode"), + "activeSlide" => array(VT_INT, 0, "Current active slide"), + "activeSlideExpire" => array(VT_INT, 0, "Expiration timestamp of current slide"), + + "rotateList" => array(VT_INT, 0, "Current rotation list ID"), + "rotateListIndex" => array(VT_INT, 0, "Current index in rotation list"), + + "lastUpdate" => array(VT_INT, 0, "Timestamp of last slide update"), +); + + +// +// Some premade test data +// +$siteTestData = array( + "news" => array( + "utime,title,text,author", + time().",%s,%s,%s", + array("Today's news", "We. Are. Back.", "orgaz"), + array("Good news, everybody!", "...", "The Professor"), + ), + + "votekeys" => array( + "key", + "%s", + array("test1"), + array("test2"), + array("7jjnqt5z"), + array("c7jcfk1G"), + ), + + "attendees" => array( + "regtime,name,groups,oneliner,email", + "%d,%s,%s,%s,%s", + array(time()-0, "man with no alias", "supergroup", "foo-bar", "c@supergroup.com"), + array(time()-15, "man with alias", "supergroup", "hi!", "c@supergroup.com"), + array(time()-30, "alias with a man", "supergroup", "mega super kewl rulets", "x@microsoft.com"), + ), + + "compos" => array( + "name,description,visible,voting", + "%s,%s,1,1", + array("Graphics", "Anything in standard resolutions."), + array("Protracker music", "Standard 4-channel Protracker MOD music."), + array("4k intro", "4k intro competition"), + ), + + "entries" => array( + "name,author,compo_id,filename,info", + "%s,%s,%d,%s,%s", + array("Donkey Dong", "electric/extend", 1, "donkey.lbm", "amigaaaah!"), + array("Your kondom", "ccr/TNSP", 1, "kondom.lbm", "oh my god, it's full of cocks!"), + array("Penis song", "reed/flt", 2, "penis.mod", "laulu rakkaudelle"), + array("jenkka", "aegis", 2, "jenkka.mod", ""), + array("Fungiform 2", "mfx", 3, "mfx-fungiform2.lzh", "OCS-only"), + ), + + "displaySlides" => array( + "title,text", + "%s,%s", + array("Next Up 4k", "<h1>Next up: 4k intro</h1><h2>4k intro compo is about to begin</h2>... in about 10 minutes."), + array("Astu to infodesk", "<b>Astu</b> - please come to info desk!"), + array("Gentle Eye mainos", "<b>Buy Amiga stuff!</b><br />Gentle Eye Oy is selling Amiga-related stuff near organizer desk!"), + ), + + "rotationListData" => array( + "name", + "%s", + array("Main rotation"), + array("Next Up"), + ), + + "rotationListSlides" => array( + "list_id,slide_id", + "%d,%d", + array(1,2), + array(1,3), + array(2,1), + ), +); + + +// +// Helper functions +// +function stGetTableSchema($dbh, $data) +{ + $res = array(); + $driver = $dbh->getAttribute(PDO::ATTR_DRIVER_NAME); + + foreach ($data as $col) + { + $tmp = array(); + + switch ($driver) + { + case "pgsql": + foreach ($col as $elem) + { + if ($elem != "AUTOINCREMENT") + $tmp[] = $elem; + } + break; + + case "sqlite": + case "mysql": + $tmp = $col; + break; + + default: + die("Don't know how to handle PDO driver '".$driver."' yet.\n"); + } + + $res[] = implode(" ", $tmp); + } + + return implode(", ", $res); +} + + +function stCreateOneTable($dbh, $name, $schema) +{ + return (stDBExecSQL($dbh, "CREATE TABLE IF NOT EXISTS ".$name." (".$schema.")") !== FALSE) ? TRUE : FALSE; +} + + +function stCreateTables($dbh, $upgrade) +{ + global $sqlTables; + echo "Creating tables...\n"; + foreach ($sqlTables as $name => $schemaData) + { + echo " - '".$name."'\n"; + if (!stCreateOneTable($dbh, $name, stGetTableSchema($dbh, $schemaData)) && !$upgrade) + return FALSE; + } + return TRUE; +} + + +$upgradeMappings = array( +// "" => array("key" => "", value => ""), +); + + +function stUpgradeMap($type, $name, $value = FALSE) +{ + global $upgradeMappings; + + if (isset($upgradeMappings[$name])) + { + if (isset($upgradeMappings[$name][$type])) + { + // XXX TODO .. + } + else + die("Upgrade failed due to missing or invalid upgrade definition: ".$type." ".$name." from version X to Y.\n"); + } + else + switch ($type) + { + case "key": return $name; + case "value": return $value; + } +} + + +function stAddSettings($inDB, $outDB, $settings, $table, $upgrade) +{ + echo ($upgrade ? "Adding settings to" : "Upgrading settings in")." '".$table."' table."; + + $status = TRUE; + stDBExecSQL($outDB, "BEGIN TRANSACTION"); + + foreach ($settings as $key => $data) + { + // Get setting type + switch ($data[0]) + { + case VT_TEXT: $type = "%s"; $var = "vtext"; break; + case VT_STR: $type = "%s"; $var = "vstr"; break; + case VT_BOOL: $type = "%b"; $var = "vint"; break; + case VT_INT: $type = "%d"; $var = "vint"; break; + default: die("Invalid type in default settings '".$key."', type=".$data[0]."\n"); + } + + // Map the key, in case the name has changed + $inKey = stUpgradeMap("key", $key); + + // Check if we are upgrading + if ($upgrade && ($res = stDBFetchSQL($inDB, stDBPrepareSQL($inDB, "SELECT * FROM ".$table." WHERE key=%s", $inKey))) !== FALSE) + { + // Yup, upgrade the data, if we can + echo "."; + + if ($res["vtype"] != $data[0]) + die("Oops! Data type of '".$key."' does not match in table '".$table.". DB upgrade failed.\n"); + + $sql = stDBPrepareSQL($outDB, + "INSERT INTO ".$table." (key,vtype,".$var.",sdesc) VALUES (%s,%d,".$type.",%s)", + $key, $data[0], stUpgradeMap("value", $key, $res[$var]), $data[2]); + } + else + { + // Normal insertion of default data + echo "+"; + $sql = stDBPrepareSQL($outDB, + "INSERT INTO ".$table." (key,vtype,".$var.",sdesc) VALUES (%s,%d,".$type.",%s)", + $key, $data[0], $data[1], $data[2]); + } + + if (stDBExecSQL($outDB, $sql) === FALSE) + { + $status = FALSE; + break; + } + } + echo "\n"; + + stDBExecSQL($outDB, "COMMIT"); + return $status; +} + + +function stAddTestData($outDB) +{ + global $siteTestData; + + echo "Adding test data.\n"; + + $status = TRUE; + stDBExecSQL($outDB, "BEGIN TRANSACTION"); + + foreach ($siteTestData as $table => $data) + { + echo " - ".$table."...\n"; + if (count($data) >= 3) + { + for ($n = 2; $n < count($data); $n++) + { + $arr = array_merge( + array($outDB, "INSERT INTO ".$table." (".$data[0].") VALUES (".$data[1].")"), + $data[$n]); + + $sql = call_user_func_array('stDBPrepareSQL', $arr); + if (stDBExecSQL($outDB, $sql) === false) + { + $status = false; + break; + } + } + } + else + { + echo " Invalid table / data definition.\n"; + } + } + + stDBExecSQL($outDB, "COMMIT"); + return $status; +} + + +function stGetSQLTypeParam($dbh, $def, $value) +{ + switch (substr($def, 0, 3)) + { + case "INT": + return intval($value); + + case "VAR": + case "TEX": + return $dbh->quote($value); + + default: die("Unknown type ".$col[1].".\n"); + } +} + + +function stMigrateTables($inDB, $outDB, $excluded) +{ + global $sqlTables; + + echo "Migrating tables...\n"; + $status = TRUE; + stDBExecSQL($outDB, "BEGIN TRANSACTION"); + + foreach ($sqlTables as $name => $schema) + if (!in_array($name, $excluded)) + { + echo " - '".$name."' "; + + foreach (stDBExecSQL($inDB, "SELECT * FROM ".$name) as $row) + { + $avals = array(); + $acols = array(); + + foreach ($schema as $col) + { + if (isset($row[$col[0]])) + { + $avals[] = stGetSQLTypeParam($outDB, $col[1], $row[$col[0]]); + $acols[] = $col[0]; + } + } + + $sql = "INSERT INTO ".$name." (".implode(",", $acols).") VALUES (".implode(",", $avals).")"; + if (stDBExecSQL($outDB, $sql) === false) + { + $status = FALSE; + break; + } + echo "."; + } + echo "\n"; + } + + stDBExecSQL($outDB, "COMMIT"); + + return $status; +} + + +function stSetDBPermissions($spec) +{ + if (substr($spec, 0, 7) == "sqlite:") + { + $filename = substr($spec, 7); + echo + "NOTICE! It seems you have SQLite database in use, changing permission ". + "of the target file '".$filename."' to 0600, for security. You may have to ". + "loosen up that for the things to actually work, but be careful. Having your ". + "database world-readable in the web is NOT good.\n"; + + if (chmod($filename, 0600) === FALSE) + { + echo "ERROR! Could not set permissions of '".$filename."!\n"; + } + } +} + + +// +// Main program starts +// +if ($argc < 2) +{ + echo + "ManageDB - Manage FAPWeb SQL database\n". + "(C) Copyright 2012-2013 ccr/TNSP\n". + "\n". + "Usage: ".$argv[0]." <mode> [args]\n". + "Where mode is one of following:\n". + "\n". + " new <dbspec> Create a new database with given PDO spec\n". + " or default to the one in mconfig.inc.php\n". + "\n". + " test <dbspec> Like new, but add initial test data.\n". + "\n". + " upgrade <input_dbspec> <output_dbspec>\n". + " Upgrade current database, if possible.\n". + " Output to new database (DO NOT USE SAME as current!)\n". + "\n". + " migrate <input_dbspec> <output_dbspec>\n". + " Like upgrade, but no version check. Creates\n". + " a copy of the database to the output spec.\n". + "\n"; + exit; +} + + +// Act according to specified command +$addTestData = FALSE; +switch (stCArgLC(1)) +{ + case "test": + $addTestData = TRUE; + + case "new": + // Try to connect to database + if (($inSpec = stCArg(2)) === false) + die("No PDO database spec specified.\n"); + + if (($inDB = stConnectSQLDBSpec($inSpec)) === false) + die("Could not connect to SQL database '".$inSpec."'.\n"); + + echo "Using database spec '".$inSpec."'.\n"; + + // Create tables, add defaults + if (stCreateTables($inDB, FALSE)) + { + stAddSettings($inDB, $inDB, $dbMeta, "dbmeta", FALSE); + stAddSettings($inDB, $inDB, $siteDefaults, "settings", FALSE); + stAddSettings($inDB, $inDB, $siteDisplayVars, "displayVars", FALSE); + } + + if ($addTestData) + stAddTestData($inDB); + + stSetDBPermissions($inSpec); + break; + + case "upgrade": + case "migrate": + // + // Attempt to upgrade database + // + if ($argc < 4) + die("Usage: ".$argv[0]." upgrade <input_dbspec> <output_dbspec>\n"); + + $inSpec = stCArg(2); + $outSpec = stCArg(3); + + if ($outSpec == $inSpec) + die("The input and output databases CAN NOT BE SAME.\nBe VERY CAREFUL to not accidentally specify same db!\n"); + + echo "Using database spec '".$inSpec."'.\n"; + + if (($inDB = stConnectSQLDBSpec($inSpec)) === false) + die("Could not connect to SQL database '".$inSpec."'.\n"); + + // Check the current version first ... + if (($currVersion = stGetDBMeta($inDB, "dbVersion")) === FALSE) + $currVersion = -1; + + if ($currVersion == $dbVersion && stCArgLC(1) == "upgrade") + { + echo "Database is already version ".$dbVersion.", no upgrading needed.\n"; + } + else + { + // Okay, we shall create an upgraded version .. + if (($outDB = stConnectSQLDBSpec($outSpec)) === false) + die("Could not connect to SQL database '".$outSpec."'.\n"); + + echo "Database at version ".$currVersion.", upgrading to ".$dbVersion."\n"; + echo "Using OUTPUT database spec '".$outSpec."'.\n"; + + // Possibly bail out incompatible upgrades here + + // Create tables + if (!stCreateTables($outDB, TRUE)) + exit; + + // Migrate data from setting tables .. + if (!stAddSettings($inDB, $outDB, $siteDefaults, "settings", TRUE)) + exit; + + if (!stAddSettings($inDB, $outDB, $siteDisplayVars, "displayVars", TRUE)) + exit; + + stAddSettings($inDB, $outDB, $dbMeta, "dbmeta", TRUE); + + // Migrate other tables + if (!stMigrateTables($inDB, $outDB, array("settings", "displayVars", "dbmeta"))) + exit; + + echo "Setting dbVersion.\n"; + stSetDBMeta($outDB, "dbVersion", $dbVersion); + echo "Upgrade complete.\n"; + + stSetDBPermissions($inSpec); + stSetDBPermissions($outSpec); + } + break; + + default: + echo "ERROR! Invalid operation mode '".stCArg(1)."'.\n"; + break; +} + + +// +// Clean up permissions +// +foreach (array("managedb.php") as $filename) +{ + if (chmod($filename, 0700) === FALSE) + { + echo "ERROR! Could not set permissions for '".$filename."'!\n"; + } +} + +?> \ No newline at end of file