Mercurial > hg > fapweb
changeset 529:ddbc84031a7b
Rename createdb.php to managedb.php
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 10 Dec 2013 17:51:20 +0200 |
parents | dd5c5577c495 |
children | 966c41ee129c ec30ad303bd1 |
files | createdb.php managedb.php |
diffstat | 2 files changed, 774 insertions(+), 774 deletions(-) [+] |
line wrap: on
line diff
--- a/createdb.php Tue Dec 10 17:50:22 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,774 +0,0 @@ -#!/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 - "CreateDB - 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("createdb.php") as $filename) -{ - if (chmod($filename, 0700) === FALSE) - { - echo "ERROR! Could not set permissions for '".$filename."'!\n"; - } -} - -?> \ No newline at end of file
--- /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