| <?php␊ |
| ␊ |
| /*␊ |
| * USAGE EXAMPLES:␊ |
| *␊ |
| * backup(); // backup to current dir␊ |
| * backup("/tmp/"); // backup to different dir␊ |
| *␊ |
| * // backup data to this directory in my format␊ |
| * backup($cfg['tmp_dir'].'/'.date("myApp_d-m-Y"), true);␊ |
| *␊ |
| * $dir = '/tmp/2009-07-21_01-40-52'; // full path to restore data␊ |
| * restore($dir);␊ |
| *␊ |
| * TODO␊ |
| *␊ |
| * 1) merge into migrate.php [ok]␊ |
| * -> call backup/restore from migrate and use what['xxx']␊ |
| * 2) add zip/tar.bz2 support [-]␊ |
| * 3) allow partial/full backup [1/2] (try{}catch(){})␊ |
| *␊ |
| * add name of backuped app to directory as prefix␊ |
| * (for sure when making archive)␊ |
| *␊ |
| * NEED HELP:␊ |
| * - save ALL and _restore_ data in right order (!!)␊ |
| * - review code and maybe unit testing␊ |
| *␊ |
| * KNOWN ISSUES:␊ |
| * - when restoring, dates are throwed away␊ |
| * and rewriten with actual (restore) date&time␊ |
| * - there are some exceptions when restoring some objects␊ |
| * (from pluf/src/Pluf/Test/Fixture.php:56)␊ |
| *␊ |
| * => maybe need something which saves raw model␊ |
| * and don't calls postSave() and so on␊ |
| *␊ |
| * - and this one:␊ |
| * Fatal error: Call to a member function _toIndex() on a non-object in /srv/http/indefero/src/IDF/WikiPage.php on line 133␊ |
| * (but maybe this is caused by my broken InDefero instance)␊ |
| *␊ |
| */␊ |
| ␊ |
| ␊ |
| //===========================␊ |
| ␊ |
| function pex($info, $e) {␊ |
| $tmps = $e->getFile().":".$e->getLine()␊ |
| ." [$info] Caught exception: ".var_dump($e->getMessage())."\n";␊ |
| echo $tmps;␊ |
| //fprintf($STDERR, "%s", $tmps);␊ |
| }␊ |
| ␊ |
| ␊ |
| /*␊ |
| * if included␊ |
| * not define debug␊ |
| * not require pluf␊ |
| * not call pluf::start␊ |
| */␊ |
| ␊ |
| $run = false;␊ |
| if (__FILE__ == realpath($argv[0])) {␊ |
| $run = true;␊ |
| }␊ |
| ␊ |
| if ($run) {␊ |
| ␊ |
| global $debug;␊ |
| $debug = false;␊ |
| ␊ |
| //===========================␊ |
| ␊ |
| //$conf='/srv/http/indefero/src/IDF/conf/idf.php.sqlite'; // from␊ |
| $conf='/srv/http/indefero/src/IDF/conf/idf.php'; // to␊ |
| ␊ |
| $app_path = '/srv/http/indefero/src';␊ |
| //$path_to_Pluf = '/srv/http/pluf/src'; // stable␊ |
| $path_to_Pluf = '/mnt/data/third-party/WEB/pluf/src'; // dev␊ |
| ␊ |
| set_include_path(get_include_path()␊ |
| .PATH_SEPARATOR.$path_to_Pluf␊ |
| .PATH_SEPARATOR.$app_path␊ |
| );␊ |
| ␊ |
| //===========================␊ |
| function debug($what)␊ |
| {␊ |
| global $debug;␊ |
| if ($debug) {␊ |
| echo($what."\n");␊ |
| //fprintf($STDERR, "%s", $what);␊ |
| }␊ |
| }␊ |
| //===========================␊ |
| ␊ |
| global $what;␊ |
| $what = array(␊ |
| 'dry_run' => false,␊ |
| );␊ |
| ␊ |
| require 'Pluf.php';␊ |
| Pluf::start($conf);␊ |
| }␊ |
| ␊ |
| /*␊ |
| * [CONCEPT] - how it works␊ |
| *␊ |
| * backup procedure␊ |
| *␊ |
| * 1. backup application will parse big application conf,␊ |
| * get all versions of migrations of all apps␊ |
| * AND pick to array all names of used models␊ |
| *␊ |
| * how:␊ |
| *␊ |
| * a) by parsing relations.php - done (loaded in _PX_MODELS)␊ |
| * b) by parsing migrations - should be better to find standalone models (?)␊ |
| * c) combination of two methods above or something else␊ |
| *␊ |
| * 2. using ...␊ |
| * > $json = Pluf_Test_Fixture::dump('YourApp_Model'); // the full table␊ |
| * ... we get data (and only data; we dont care about sql, because migrations␊ |
| * could recreate correctly for specific database on the fly)␊ |
| *␊ |
| * 3. we save all of that␊ |
| *␊ |
| *␊ |
| * restore procedure␊ |
| *␊ |
| * 1) read data (reverse 3)␊ |
| * 2) get versions of apps and migrate on specific databese␊ |
| * to correct version to match data (mostly reverse 1 stage)␊ |
| * 3) restore thanx to Pluf_Test_Fixture::load␊ |
| * 4) migrate to last versions␊ |
| *␊ |
| * and enjoy :D␊ |
| *␊ |
| * i think this _could_ work also as migration from one databese to second␊ |
| * (MySQL <--> PostgreSQL) or not?␊ |
| *␊ |
| *␊ |
| * HINT:␊ |
| *␊ |
| * this tool will not repair or work on broken databse !!!␊ |
| * (realy bad idea is doing migration on SQLite)␊ |
| *␊ |
| * it could try dump as most data as it can␊ |
| * but still your backup and restored DB will be broken␊ |
| *␊ |
| * (should mark broken dumps)␊ |
| *␊ |
| */␊ |
| ␊ |
| //=========================================================␊ |
| ␊ |
| function get_apps()␊ |
| {␊ |
| global $debug;␊ |
| global $what;␊ |
| $apps = Pluf::f('installed_apps');␊ |
| $versions = array();␊ |
| ␊ |
| foreach ($apps as $app)␊ |
| {␊ |
| $m = new Pluf_Migration($app);␊ |
| $m->display = $debug;␊ |
| $m->dry_run = $what['dry_run'];␊ |
| $ver = $m->getAppVersion($app);␊ |
| $versions[$app] = $ver;␊ |
| debug("|| {$app}: {$ver}");␊ |
| }␊ |
| ␊ |
| return( $versions );␊ |
| } //end get_apps()␊ |
| ␊ |
| function get_models()␊ |
| {␊ |
| global $debug;␊ |
| global $what;␊ |
| $a = $GLOBALS['_PX_models'];␊ |
| $modelsA = array();␊ |
| $modelsB = array();␊ |
| ␊ |
| while (list($mod, $rel) = each($a)) {␊ |
| array_push( $modelsB, $mod );␊ |
| $mm = array_pop( $rel ); // contains relate_to_*␊ |
| foreach ($mm as $m) {␊ |
| array_push( $modelsA, $m );␊ |
| }␊ |
| }␊ |
| unset( $a );␊ |
| ␊ |
| /*␊ |
| *␊ |
| * should this help to save (and reload)␊ |
| * in right order (???)␊ |
| *␊ |
| */␊ |
| $modelsA = array_unique( $modelsA ); // independent␊ |
| $modelsB = array_unique( $modelsB ); // related␊ |
| ␊ |
| $models = array_merge($modelsA, $modelsB);␊ |
| debug(print_r($models, true));␊ |
| ␊ |
| return($models);␊ |
| } //end get_apps()␊ |
| ␊ |
| //=========================================================␊ |
| ␊ |
| function backup($dir=null, $full_path=false)␊ |
| {␊ |
| global $debug;␊ |
| global $what;␊ |
| ␊ |
| if (!is_null($dir)) {␊ |
| if ($full_path == false) {␊ |
| $dir .= "/".date("Y-m-d_H-i-s");␊ |
| }␊ |
| } else {␊ |
| $dir = date("Y-m-d_H-i-s");␊ |
| }␊ |
| debug("# backuped to '{$dir}'");␊ |
| ␊ |
| $versions = get_apps();␊ |
| $models = get_models();␊ |
| ␊ |
| $versions_js = json_encode($versions);␊ |
| $models_js = json_encode($models);␊ |
| ␊ |
| if (!file_exists($dir)) {␊ |
| mkdir($dir, 0777, true);␊ |
| }␊ |
| ␊ |
| file_put_contents($dir."/versions.json", $versions_js);␊ |
| file_put_contents($dir."/models.json", $models_js);␊ |
| ␊ |
| $i=0;␊ |
| $failed = 0;␊ |
| while (list($k, $mod) = each($models))␊ |
| {␊ |
| $i+=1;␊ |
| $fname = "{$dir}/{$mod}.json";␊ |
| try {␊ |
| $string = Pluf_Test_Fixture::dump($mod);␊ |
| file_put_contents($fname, $string);␊ |
| debug($mod);␊ |
| }␊ |
| catch (Exception $e) {␊ |
| $failed+=1;␊ |
| pex("dumping '{$mod}'", $e);␊ |
| }␊ |
| }␊ |
| debug("# status: failed dump {$failed} from {$i}\n");␊ |
| ␊ |
| } // end backup()␊ |
| ␊ |
| function check_file($f) {␊ |
| $ret = true;␊ |
| if (! Pluf::fileExists($f)) {␊ |
| $ret = false;␊ |
| echo "!! file '{$f}' doesn't exist\n";␊ |
| }␊ |
| return $ret;␊ |
| } // end check_file()␊ |
| ␊ |
| function restore($dir)␊ |
| {␊ |
| global $debug;␊ |
| global $what;␊ |
| ␊ |
| if (is_null($dir)) {␊ |
| echo "!! don't know what to load\n";␊ |
| exit( 2 );␊ |
| }␊ |
| ␊ |
| if (check_file($dir)==false) {␊ |
| exit( 3 );␊ |
| }␊ |
| ␊ |
| if (!check_file($dir."/versions.json")␊ |
| || !check_file($dir."/models.json")) {␊ |
| throw new Exception("Version/Models file doesn't exist.");␊ |
| }␊ |
| ␊ |
| $versions_js = file_get_contents($dir."/versions.json");␊ |
| $models_js = file_get_contents($dir."/models.json");␊ |
| ␊ |
| $versions = json_decode($versions_js, true);␊ |
| $models = json_decode($models_js, true);␊ |
| ␊ |
| /* migrate all apps to right versions */␊ |
| $i=0;␊ |
| $failed=0;␊ |
| while (list($app,$ver) = each( $versions ))␊ |
| {␊ |
| $i+=1;␊ |
| try {␊ |
| $m = new Pluf_Migration($app);␊ |
| $m->display = $debug;␊ |
| $m->dry_run = $what['dry_run'];␊ |
| $m->installApp($app, false, $ver); // should be ok␊ |
| }␊ |
| catch (Exception $e) {␊ |
| $failed+=1;␊ |
| pex("recreate", $e);␊ |
| }␊ |
| }␊ |
| debug("# status: failed recreate {$failed} from {$i}\n");␊ |
| ␊ |
| /* restore data */␊ |
| $i=0;␊ |
| $failed=0;␊ |
| while (list($k, $mod) = each($models))␊ |
| {␊ |
| $i+=1;␊ |
| try␊ |
| {␊ |
| $fname = "{$dir}/{$mod}.json";␊ |
| if (check_file($fname) == false) {␊ |
| continue;␊ |
| }␊ |
| $content = file_get_contents($fname);␊ |
| $created = Pluf_Test_Fixture::load($content);␊ |
| debug($mod);␊ |
| }␊ |
| catch (Exception $e) {␊ |
| $failed+=1;␊ |
| pex("loading '{$mod}'", $e);␊ |
| }␊ |
| }␊ |
| debug("# status: failed load {$failed} from {$i}\n");␊ |
| ␊ |
| /* migrate to latest versions */␊ |
| $m = new Pluf_Migration();␊ |
| $m->display = $debug;␊ |
| $m->dry_run = $what['dry_run'];␊ |
| $m->migrate();␊ |
| } // end restore()␊ |
| ␊ |
| if ($run) {␊ |
| /*␊ |
| $dir = date("Y-m-d_H-i-s");␊ |
| echo $dir."\n";␊ |
| backup($dir, true);␊ |
| ␊ |
| restore('2009-07-22_22-32-34');␊ |
| */␊ |
| }␊ |
| ␊ |
| // END␊ |