Setup/Maintenance

* toggle maintenance mode in a more reasonable manner (i.e. not when displaying help test)
 * move connectivity tests to class DB
 * restore generate everything functionality when running --sql and --build with an empty parameter set
This commit is contained in:
Sarjuuk
2021-02-20 19:19:24 +01:00
parent 43778b01e7
commit fbc5d43aab
13 changed files with 130 additions and 113 deletions

View File

@@ -49,6 +49,23 @@ class DB
self::$connectionCache[$idx] = true;
}
public static function test(array $options, ?string &$err = '') : bool
{
$defPort = ini_get('mysqli.default_port');
$port = 0;
if (strstr($options['host'], ':'))
[$options['host'], $port] = explode(':', $options['host']);
if ($link = @mysqli_connect($options['host'], $options['user'], $options['pass'], $options['db'], $port ?: $defPort))
{
mysqli_close($link);
return true;
}
$err = '['.mysqli_connect_errno().'] '.mysqli_connect_error();
return false;
}
public static function errorHandler($message, $data)
{
if (!error_reporting())

View File

@@ -12,65 +12,44 @@ require_once 'setup/tools/setupScript.class.php';
require_once 'setup/tools/dbc.class.php';
require_once 'setup/tools/imagecreatefromblp.func.php';
function finish(bool $unlock = true) : void
function finish() : void
{
if (CLISetup::getOpt('delete')) // generated with TEMPORARY keyword. Manual deletion is not needed
CLI::write('generated dbc_* - tables have been deleted.', CLI::LOG_INFO);
if ($unlock)
lockSite(false);
die("\n");
}
function lockSite(bool $enable = true) : void
{
if (DB::isConnectable(DB_AOWOW))
DB::Aowow()->query('UPDATE ?_config SET `value` = ?d WHERE `key` = "maintenance"', $enable ? 1 : 0);
}
CLISetup::init();
if (!CLISetup::getOpt(0x3))
die(CLISetup::optHelp(0x7));
$cmd = CLISetup::getOpt(0x3)[0]; // get arguments present in argGroup 1 or 2, if set. Pick first.
$unlock = false;
$s = [];
$b = [];
$cmd = CLISetup::getOpt(0x3)[0]; // get arguments present in argGroup 1 or 2, if set. Pick first.
$s = [];
$b = [];
switch ($cmd) // we accept only one main parameter
{
case 'setup':
lockSite(true);
require_once 'setup/tools/clisetup/firstrun.func.php';
$success = firstrun();
finish($success);
case 'sql':
case 'build':
lockSite(true);
$unlock = true;
case 'account':
case 'dbconfig':
case 'siteconfig':
require_once 'setup/tools/clisetup/'.$cmd.'.func.php';
$cmd();
finish($unlock);
finish();
case 'update':
lockSite(true);
require_once 'setup/tools/clisetup/update.func.php';
[$s, $b] = update(); // return true if we do not rebuild stuff
update($s, $b); // return true if we do not rebuild stuff
if (!$s && !$b)
finish(true);
finish();
case 'sync':
lockSite(true);
require_once 'setup/tools/clisetup/sync.func.php';
sync($s, $b);
finish(true);
finish();
case 'dbc':
foreach (CLISetup::getOpt('dbc') as $n)
{

View File

@@ -24,6 +24,12 @@ class CLISetup
'ruRU' => LOCALE_RU
);
public const LOCK_OFF = 0;
public const LOCK_ON = 1;
public const LOCK_RESTORE = 2;
private static $lock = 1;
private const ARGV_REQUIRED = 0x01;
private const ARGV_OPTIONAL = 0x02;
private const ARGV_ARRAY = 0x10;
@@ -123,6 +129,12 @@ class CLISetup
foreach (self::$locales as $idx => $str)
if (!defined('CFG_LOCALES') || CFG_LOCALES & (1 << $idx))
self::$localeIds[] = $idx;
// get site status
if (DB::isConnectable(DB_AOWOW))
self::$lock = (int)DB::Aowow()->selectCell('SELECT `value` FROM ?_config WHERE `key` = "maintenance"');
else
self::$lock = self::LOCK_ON;
}
public static function getOpt(...$args)
@@ -182,6 +194,17 @@ class CLISetup
}
/*******************/
/* web page access */
/*******************/
public static function siteLock(int $mode = self::LOCK_RESTORE) : void
{
if (DB::isConnectable(DB_AOWOW))
DB::Aowow()->query('UPDATE ?_config SET `value` = ?d WHERE `key` = "maintenance"', (int)!!($mode == self::LOCK_RESTORE ? self::$lock : $mode));
}
/*******************/
/* MPQ-file access */
/*******************/

View File

@@ -11,7 +11,7 @@ if (!CLI)
/* Account creation */
/********************/
function account()
function account() : void
{
$fields = array(
'name' => ['Username', false],

View File

@@ -11,15 +11,17 @@ if (!CLI)
/* Create required files */
/*************************/
function build($syncMe = null)
function build($syncMe = null) : array
{
require_once 'setup/tools/fileGen.class.php';
FileGen::init($syncMe !== null ? FileGen::MODE_UPDATE : FileGen::MODE_NORMAL, $syncMe ?: []);
if(!FileGen::init($syncMe !== null ? FileGen::MODE_UPDATE : FileGen::MODE_NORMAL, $syncMe ?: []))
return [];
$done = [];
if (FileGen::$subScripts)
{
CLISetup::siteLock(CLISetup::LOCK_ON);
$allOk = true;
// start file generation
@@ -80,6 +82,8 @@ function build($syncMe = null)
CLI::write('successfully finished file generation', CLI::LOG_OK);
else
CLI::write('finished file generation with errors', CLI::LOG_ERROR);
CLISetup::siteLock(CLISetup::LOCK_RESTORE);
}
else if (FileGen::getMode() == FileGen::MODE_NORMAL)
CLI::write('no valid script names supplied', CLI::LOG_ERROR);

View File

@@ -11,7 +11,7 @@ if (!CLI)
/* Configure DB connection*/
/**************************/
function dbconfig()
function dbconfig() : void
{
$databases = ['aowow', 'world', 'auth', 'characters'];
$AoWoWconf = [];
@@ -24,21 +24,11 @@ function dbconfig()
);
$testDB = function($idx, $name, $dbInfo)
{
$buff = '['.CLI::bold($idx).'] '.str_pad($name, 17);
$errStr = '';
$defPort = ini_get('mysqli.default_port');
$port = 0;
if (strstr($dbInfo['host'], ':'))
[$dbInfo['host'], $port] = explode(':', $dbInfo['host']);
$buff = '['.CLI::bold($idx).'] '.str_pad($name, 17);
if ($dbInfo['host'])
{
// test DB
if ($link = @mysqli_connect($dbInfo['host'], $dbInfo['user'], $dbInfo['pass'], $dbInfo['db'], $port ?: $defPort))
mysqli_close($link);
else
$errStr = '['.mysqli_connect_errno().'] '.mysqli_connect_error();
DB::test($dbInfo, $errStr);
$buff .= $errStr ? CLI::red('ERR ') : CLI::green('OK ');
$buff .= 'mysqli://'.$dbInfo['user'].':'.str_pad('', mb_strlen($dbInfo['pass']), '*').'@'.$dbInfo['host'].($port ? ':'.$port : null).'/'.$dbInfo['db'];
@@ -54,10 +44,8 @@ function dbconfig()
require 'config/config.php';
foreach ($databases as $idx => $name)
{
if (empty($AoWoWconf[$name]) && $name != 'characters' )
$AoWoWconf[$name] = array_combine(array_keys($dbFields), ['', '', '', '', '']);
}
while (true)
{

View File

@@ -11,7 +11,7 @@ if (!CLI)
/* string setup steps together for first use */
/*********************************************/
function firstrun() : bool
function setup() : void
{
require_once 'setup/tools/sqlGen.class.php';
require_once 'setup/tools/fileGen.class.php';
@@ -118,26 +118,16 @@ function firstrun() : bool
require 'config/config.php';
$error = [];
$defPort = ini_get('mysqli.default_port');
foreach (['aowow', 'world', 'auth'] as $idx => $what)
foreach (['world', 'aowow', 'auth'] as $idx => $what)
{
if ($what == 'auth' && (empty($AoWoWconf['auth']) || empty($AoWoWconf['auth']['host'])))
continue;
$port = 0;
if (strstr($AoWoWconf[$what]['host'], ':'))
[$AoWoWconf[$what]['host'], $port] = explode(':', $AoWoWconf[$what]['host']);
if ($link = @mysqli_connect($AoWoWconf[$what]['host'], $AoWoWconf[$what]['user'], $AoWoWconf[$what]['pass'], $AoWoWconf[$what]['db'], $port ?: $defPort))
{
mysqli_close($link);
// init proper access for further setup
// init proper access for further setup
if (DB::test($AoWoWconf[$what], $err))
DB::load($idx, $AoWoWconf[$what]);
}
else
$error[] = ' * '.$what.': '.'['.mysqli_connect_errno().'] '.mysqli_connect_error();
$error[] = ' * '.$what.': '.$err;
}
return empty($error);
@@ -247,7 +237,7 @@ function firstrun() : bool
}
CLI::write();
exit;
return;
}
if ($startStep)
@@ -274,6 +264,8 @@ function firstrun() : bool
/* run */
/*******/
CLISetup::siteLock(CLISetup::LOCK_ON);
foreach ($steps as $idx => $step)
{
if ($startStep > $idx)
@@ -288,7 +280,7 @@ function firstrun() : bool
$inp = ['x' => ['Press any key to continue', true]];
if (!CLI::read($inp, true)) // we don't actually care about the input
return false;
return;
}
while (true)
@@ -329,20 +321,21 @@ function firstrun() : bool
case 'r':
break;
case 'a':
return false;
return;
}
}
else
{
CLI::write();
return false;
return;
}
}
}
unlink('cache/firstrun');
CLISetup::siteLock(CLISetup::LOCK_OFF);
CLI::write('setup finished', CLI::LOG_OK);
return true;
return;
}
?>

View File

@@ -11,7 +11,7 @@ if (!CLI)
/* Configure Site variables */
/****************************/
function siteconfig()
function siteconfig() : void
{
$reqKeys = ['site_host', 'static_host'];
$updScripts = [];

View File

@@ -11,15 +11,17 @@ if (!CLI)
/* Create content from world tables / dbc files */
/************************************************/
function sql($syncMe = null)
function sql($syncMe = null) : array
{
require_once 'setup/tools/sqlGen.class.php';
SqlGen::init($syncMe !== null ? SqlGen::MODE_UPDATE : SqlGen::MODE_NORMAL, $syncMe ?: []);
if (!SqlGen::init($syncMe !== null ? SqlGen::MODE_UPDATE : SqlGen::MODE_NORMAL, $syncMe ?: []))
return [];
$done = [];
if (SqlGen::$subScripts)
{
CLISetup::siteLock(CLISetup::LOCK_ON);
$allOk = true;
// start file generation
@@ -46,6 +48,8 @@ function sql($syncMe = null)
CLI::write('successfully finished sql generation', CLI::LOG_OK);
else
CLI::write('finished sql generation with errors', CLI::LOG_ERROR);
CLISetup::siteLock(CLISetup::LOCK_RESTORE);
}
else if (SqlGen::getMode() == SqlGen::MODE_NORMAL)
CLI::write('no valid script names supplied', CLI::LOG_ERROR);

View File

@@ -27,7 +27,7 @@ function sync(array $s = [], array $b = []) : void
CLI::write(' e.g.: "php aowow --sync=creature_queststarter" causes the table aowow_quests_startend to be recreated.', -1, false);
CLI::write(' Also quest-related profiler files will be recreated as they depend on aowow_quests_startend and thus indirectly on creature_queststarter.', -1, false);
CLI::write();
exit;
return;
}
$_s = sql($s);
@@ -43,6 +43,9 @@ function sync(array $s = [], array $b = []) : void
$_ = array_diff($b, $_b);
DB::Aowow()->query('UPDATE ?_dbversion SET `build` = ?', $_ ? implode(' ', $_) : '');
}
if (!$s && !$_s && !$b && !$_b)
CLI::write('no valid table names supplied', CLI::LOG_ERROR);
}
?>

View File

@@ -11,7 +11,7 @@ if (!CLI)
/* automaticly apply sql-updates */
/*********************************/
function update() : array
function update(?array &$sql = [], ?array &$build = []) : void
{
[$date, $part] = array_values(DB::Aowow()->selectRow('SELECT `date`, `part` FROM ?_dbversion'));
@@ -25,10 +25,11 @@ function update() : array
CLI::write();
CLI::write(' Last Update: '.date(Util::$dateFormatInternal, $date).' (Part #'.$part.')', -1, false);
CLI::write();
exit;
return;
}
CLI::write('checking sql updates');
CLISetup::siteLock(CLISetup::LOCK_ON);
$nFiles = 0;
foreach (glob('setup/updates/*.sql') as $file)
@@ -69,6 +70,7 @@ function update() : array
CLI::write(' -> '.date('d.m.Y', $fDate).' #'.$fPart.': '.$nQuerys.' queries applied', CLI::LOG_OK);
}
CLISetup::siteLock(CLISetup::LOCK_RESTORE);
CLI::write($nFiles ? 'applied '.$nFiles.' update(s)' : 'db is already up to date', CLI::LOG_OK);
// fetch sql/build after applying updates, as they may contain sync-prompts
@@ -84,8 +86,6 @@ function update() : array
if ($build)
CLI::write('The following file(s) require syncing: '.implode(', ', $build));
return [$sql, $build];
}
?>

View File

@@ -65,33 +65,25 @@ class FileGen
'STATIC_URL' => STATIC_URL
);
public static function init($mode = self::MODE_NORMAL, array $updScripts = [])
public static function init(int $mode = self::MODE_NORMAL, array $updScripts = []) : bool
{
self::$defaultExecTime = ini_get('max_execution_time');
$doScripts = null;
self::$mode = $mode;
// handle command prompts
self::handleCLIOpts($doScripts);
if ($mode == self::MODE_NORMAL && !$doScripts)
if (!CLISetup::$localeIds)
{
self::printCLIHelp();
exit;
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
return false;
}
// handle command prompts
if (!self::handleCLIOpts($doScripts))
return false;
// check passed subscript names; limit to real scriptNames
self::$subScripts = array_merge(array_keys(self::$tplFiles), array_keys(self::$datasets));
if ($doScripts || $updScripts)
self::$subScripts = array_intersect($doScripts ?: $updScripts, self::$subScripts);
else if ($doScripts === null)
self::$subScripts = [];
if (!CLISetup::$localeIds /* todo: && this script has localized text */)
{
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
exit;
}
// create directory structure
CLI::write('FileGen::init() - creating required directories');
@@ -102,9 +94,11 @@ class FileGen
CLI::write('created '.$pathOk.' extra paths'.($pathOk == count(self::$reqDirs) ? '' : ' with errors'));
CLI::write();
return true;
}
private static function handleCLIOpts(&$doScripts)
private static function handleCLIOpts(?array &$doScripts) : bool
{
$doScripts = [];
@@ -117,7 +111,7 @@ class FileGen
else
self::printCLIHelp();
exit;
return false;
}
// required subScripts
@@ -136,10 +130,19 @@ class FileGen
$doScripts[] = $name;
}
$doScripts = $doScripts ? array_unique($doScripts) : null;
if (!$doScripts)
return false;
$doScripts = array_unique($doScripts);
return true;
}
else if ($_ = CLISetup::getOpt('build'))
{
$doScripts = $_;
return true;
}
return false;
}
private static function printCLIHelp()

View File

@@ -23,13 +23,17 @@ class SqlGen
public static $defaultExecTime = 30;
public static $sqlBatchSize = 1000;
public static function init(int $mode = self::MODE_NORMAL, array $updScripts = []) : void
public static function init(int $mode = self::MODE_NORMAL, array $updScripts = []) : bool
{
self::$defaultExecTime = ini_get('max_execution_time');
$doScripts = null;
self::$mode = $mode;
if (!CLISetup::$localeIds)
{
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
return false;
}
// register subscripts
foreach (glob('setup/tools/sqlgen/*.func.php') as $file)
include_once $file;
@@ -76,25 +80,15 @@ class SqlGen
}
// handle command prompts
self::handleCLIOpts($doScripts);
if ($mode == self::MODE_NORMAL && !$doScripts)
{
self::printCLIHelp();
exit;
}
if (!self::handleCLIOpts($doScripts))
return false;
// check passed subscript names; limit to real scriptNames
self::$subScripts = array_keys(self::$tables);
if ($doScripts || $updScripts)
self::$subScripts = array_intersect($doScripts ?: $updScripts, self::$subScripts);
else if ($doScripts === null)
self::$subScripts = [];
if (!CLISetup::$localeIds /* && this script has localized text */)
{
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
exit;
}
return true;
}
public static function register(SetupScript $ssRef) : void
@@ -138,14 +132,14 @@ class SqlGen
}
}
private static function handleCLIOpts(&$doTbls) : void
private static function handleCLIOpts(?array &$doTbls) : bool
{
$doTbls = [];
if (CLISetup::getOpt('help') && self::$mode == self::MODE_NORMAL)
{
self::printCLIHelp();
exit;
return false;
}
// required subScripts
@@ -160,10 +154,19 @@ class SqlGen
if (array_intersect($sync, $ssRef->getDependencies(true)))
$doTbls[] = $name;
$doTbls = $doTbls ? array_unique($doTbls) : null;
if (!$doTbls)
return false;
$doTbls = array_unique($doTbls);
return true;
}
else if ($_ = CLISetup::getOpt('sql'))
{
$doTbls = $_;
return true;
}
return false;
}
private static function printCLIHelp() : void