* @version 1.0 */ error_reporting (E_ALL); set_time_limit (0); ini_set ('memory_limit', '-1'); ini_set ('register_argc_argv', '1'); require 'binary.php'; require 'function.php'; $_corePath = dirname (dirname (__FILE__)); require $_corePath . DIRECTORY_SEPARATOR .'class'. DIRECTORY_SEPARATOR .'Xml.php'; echo "\n"; echo "Starting Titan Framework's installation tool... \n\n"; try { if (PHP_SAPI != 'cli') throw new Exception ("[ERROR] This is a command-line script! You cannot call by browser."); if (!(int) ini_get ('register_argc_argv')) throw new Exception ("[ERROR] This is a command-line script! You must enable 'register_argc_argv' directive."); if (!function_exists ('system') || !function_exists ('exec')) throw new Exception ("[ERROR] You need enable OS call functions (verify if PHP is not in safe mode)!"); if ($argc < 2) throw new Exception ("[ERROR] The correct formart of command is:\nphp path/to/core/update/db.php path/to/instance [--ignore-errors]"); if (!file_exists ($argv [1]) || !is_dir ($argv [1])) throw new Exception ("[ERROR] Instance directory not appear a Titan application!"); $_path = realpath ($argv [1]); $_ignore = FALSE; if ($argc == 3 && $argv [2] == '--ignore-errors') $_ignore = TRUE; chdir ($_path); /* * Open configuration file */ $file = 'configure/titan.xml'; if (!file_exists ($file) || !is_readable ($file)) throw new Exception ("[ERROR] Dont exists a valid instance of Titan and is not possible create a new without file [". $_path . DIRECTORY_SEPARATOR . $file ."]! \n"); $xml = new Xml ($file); $_xml = $xml->getArray (); if (!isset ($_xml ['titan-configuration'][0])) throw new Exception ("[ERROR] The tag 'titan-configuration' dont exist in file [". $_path . DIRECTORY_SEPARATOR . $file ."]! \n"); $_xml = $_xml ['titan-configuration'][0]; echo "[INFO] The file 'titan.xml' is loaded! [". $_path . DIRECTORY_SEPARATOR . $file ."] \n"; if (isset ($_xml ['url']) && trim ($_xml ['url']) != '') echo "[INFO] This instance is located at [". $_xml ['url'] ."] \n"; if (isset ($_xml ['timezone']) && trim ($_xml ['timezone']) != '') date_default_timezone_set (trim ($_xml ['timezone'])); /* * Connecting to DB */ if (!isset ($_xml ['database'][0]) || !isset ($_xml ['database'][0]['host']) || !isset ($_xml ['database'][0]['name'])) throw new Exception ("[ERROR] You need configure 'database' on 'titan.xml'!"); $_xml ['database'][0]['port'] = isset ($_xml ['database'][0]['port']) && is_numeric ($_xml ['database'][0]['port']) ? trim ($_xml ['database'][0]['port']) : '5432'; if (!in_array ($_xml ['database'][0]['host'], array ('localhost', '127.0.0.1', '::1'))) $dsn = 'pgsql:host='. $_xml ['database'][0]['host'] .' port='. $_xml ['database'][0]['port'] .' dbname='. $_xml ['database'][0]['name'] .' user='. @$_xml ['database'][0]['user'] .' password='. @$_xml ['database'][0]['password']; else $dsn = 'pgsql:dbname='. $_xml ['database'][0]['name'] .' user='. @$_xml ['database'][0]['user'] .' password='. @$_xml ['database'][0]['password']; $dbUser = @$_xml ['database'][0]['user']; $dbPass = @$_xml ['database'][0]['password']; $dbName = @$_xml ['database'][0]['name']; $dbPort = @$_xml ['database'][0]['port']; $dbHost = @$_xml ['database'][0]['host']; $_db = new PDO ($dsn, $dbUser, $dbPass); $_db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); if (isset ($_xml ['timezone']) && trim ($_xml ['timezone']) != '') $_db->exec ("SET timezone TO '". trim ($_xml ['timezone']) ."'"); $schema = isset ($_xml ['database'][0]['schema']) && trim ($_xml ['database'][0]['schema']) != '' ? trim ($_xml ['database'][0]['schema']) : 'public'; $_versionTable = $schema .'._version'; if (!tableExists ($_db, $_versionTable)) $_db->exec ("CREATE TABLE ". $_versionTable ." (_version CHAR(14) NOT NULL, _author VARCHAR(64) NOT NULL, _date TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, CONSTRAINT _version_pkey PRIMARY KEY(_version))"); /* * Updating database to last version */ $_pathToMigrationFiles = 'update'. DIRECTORY_SEPARATOR .'db'. DIRECTORY_SEPARATOR; if (file_exists ($_pathToMigrationFiles) && is_dir ($_pathToMigrationFiles)) { $query = $_db->query ("SELECT MAX(_version) AS v FROM ". $_versionTable); $version = (int) $query->fetchColumn (0); $dh = opendir ($_pathToMigrationFiles); if (!$dh) throw new Exception ("[CRITICAL] Fail to list migration folder [". $_pathToMigrationFiles ."]!"); $files = array (); while (($file = readdir ($dh)) !== false) { preg_match ('/^(?P\d{14})\.sql/', $file, $m); if (!is_array ($m) || !isset ($m ['v'])) continue; if ($version < (int) $m ['v']) $files [] = $m ['v']; } closedir ($dh); echo "[INFO] Has ". sizeof ($files) ." new versions to be applied in DB... \n\n"; if (sizeof ($files)) { sort ($files); reset ($files); $_sthUpdateVersion = $_db->prepare ("INSERT INTO ". $_versionTable ." (_version, _author) VALUES (:version, 'DB Migration Update Script')"); foreach ($files as $trash => $file) try { $_db->beginTransaction (); echo "[INFO] Trying to apply migration file [". $_pathToMigrationFiles . $file .".sql]... \n"; $sql = file_get_contents ($_pathToMigrationFiles . $file .'.sql'); if (trim ($sql) != '') $_db->exec ($sql); $_sthUpdateVersion->bindParam (':version', $file, PDO::PARAM_STR, 14); $_sthUpdateVersion->execute (); $_db->commit (); echo "[SUCCESS] DB is now in version [". $file ."]! \n\n"; } catch (PDOException $e) { $_db->rollBack (); $error = "[CRITICAL] Error for apply SQL in DB [". $_pathToMigrationFiles . $file .".sql]: ". $e->getMessage (); if ($_ignore) echo $error ."\n\n"; else throw new Exception ($error); } } } echo "[SUCCESS] All done! \n\n"; } catch (Exception $e) { echo $e->getMessage () ." \n"; } echo "\n";