public function testGetTimestampFromFilename()
 {
     $test_data = array('2009_01_01_09_31_23.php' => '2009-01-01T09:31:23', '2008_02_27_10_42_59.php' => '2008-02-27T10:42:59', '1973_12_31_16_01_00' => '1973-12-31T16:01:00', '2054_13_01_00_00_00.php' => null, '1922_06_31_10_23_19.php' => null, '2001_02_30_18_23_45.php' => null, '2323_23_23_23_23.php' => null, '3434_34_34_34_43.p' => null);
     foreach ($test_data as $in => $out) {
         $this->assertEqual($out, MpmStringHelper::getTimestampFromFilename($in));
     }
 }
 /**
  * @static
  * @param object $obj		a simple object with migration information (from a migration list)
  * @param string $method
  * @param array $options
  * @return mixed
  */
 public static function runMigration(&$obj, $method = 'up', array $options = array())
 {
     // if true, exceptions will not cause the script to exit
     $forced = isset($options['forced']) ? $options['forced'] : false;
     // if true, only echo back the SQL to be run
     $dryrun = isset($options['dryrun']) ? $options['dryrun'] : false;
     $db_config = MpmDbHelper::get_db_config();
     $migrations_table = $db_config->migrations_table;
     $filename = MpmStringHelper::getFilenameFromTimestamp($obj->timestamp);
     $classname = 'Migration_' . str_replace('.php', '', $filename);
     // make sure the file exists; if it doesn't, skip it but display a message
     $migration_file = MpmListHelper::get_migration_file(MPM_DB_PATH . $filename);
     if (!$migration_file) {
         echo "\n\tMigration " . $obj->timestamp . ' (ID ' . $obj->id . ') skipped - file missing.';
         return;
     }
     // file exists -- run the migration
     require_once $migration_file;
     $migration = new $classname();
     $msg = "# Performing " . strtoupper($method) . " migration " . $obj->timestamp . ' (ID ' . $obj->id . ')';
     if (!empty($migration->info)) {
         $msg .= "\n# {$migration->info}";
     }
     echo "\n" . $msg . " ... ";
     MpmSqlLogger::log_to_file("\n" . $msg . "\n");
     if ($migration instanceof MpmMigration) {
         $dbObj = MpmDbHelper::getPdoObj();
     } else {
         $dbObj = MpmDbHelper::getMysqliObj();
     }
     if ($dryrun) {
         $dbObj->dryrun = true;
     }
     $dbObj->beginTransaction();
     if ($method == 'down') {
         $active = 0;
     } else {
         $active = 1;
     }
     try {
         $migration->{$method}($dbObj);
         $sql = "UPDATE `{$migrations_table}` SET `active` = '{$active}' WHERE `id` = {$obj->id}";
         $dbObj->internal_exec($sql);
     } catch (Exception $e) {
         $dbObj->rollback();
         echo "failed!";
         echo "\n";
         $clw = MpmCommandLineWriter::getInstance();
         $clw->writeLine($e->getMessage(), 12);
         if (!$forced) {
             echo "\n\n";
             // Return with non-0 error code to notify external caller to stop the deployment
             exit(1);
         } else {
             return;
         }
     }
     $dbObj->commit();
     echo "done.";
 }
 /**
  * Determines what action should be performed and takes that action.
  *
  * @uses MpmHelpController::displayHelp()
  * @uses MpmStringHelper::strToCamel()
  * @uses MpmAutoloadHelper::load()
  * 
  * @return void
  */
 public function doAction()
 {
     if (count($this->arguments) == 0) {
         return $this->displayHelp();
     } else {
         $controller_name = $this->arguments[0];
         $class_name = ucwords(MpmStringHelper::strToCamel('mpm_' . strtolower($controller_name) . '_controller'));
         try {
             MpmAutoloadHelper::load($class_name);
         } catch (Exception $e) {
             return $this->displayHelp();
         }
         $obj = new $class_name();
         return $obj->displayHelp();
     }
 }
 /**
  * Performs a single migration.
  *
  * @uses MpmStringHelper::getFilenameFromTimestamp()
  * @uses MpmDbHelper::getPdoObj()
  * @uses MpmDbHelper::getMysqliObj()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::writeLine()
  * @uses MPM_DB_PATH
  *
  * @param object  $obj        		    a simple object with migration information (from a migration list)
  * @param int    &$total_migrations_run a running total of migrations run
  * @param bool    $forced               if true, exceptions will not cause the script to exit
  *
  * @return void
  */
 public static function runMigration(&$obj, $method = 'up', $forced = false)
 {
     $db_config = $GLOBALS['db_config'];
     $migrations_table = $db_config->migrations_table;
     $filename = MpmStringHelper::getFilenameFromTimestamp($obj->timestamp);
     $classname = 'Migration_' . str_replace('.php', '', $filename);
     // make sure the file exists; if it doesn't, skip it but display a message
     if (!file_exists(MPM_DB_PATH . $filename)) {
         echo "\n\tMigration " . $obj->timestamp . ' (ID ' . $obj->id . ') skipped - file missing.';
         return;
     }
     // file exists -- run the migration
     echo "\n\tPerforming " . strtoupper($method) . " migration " . $obj->timestamp . ' (ID ' . $obj->id . ')... ';
     require_once MPM_DB_PATH . $filename;
     $migration = new $classname();
     if ($migration instanceof MpmMigration) {
         $dbObj = MpmDbHelper::getPdoObj();
     } else {
         $dbObj = MpmDbHelper::getMysqliObj();
     }
     $dbObj->beginTransaction();
     if ($method == 'down') {
         $active = 0;
     } else {
         $active = 1;
     }
     try {
         $migration->{$method}($dbObj);
         $sql = "UPDATE `{$migrations_table}` SET `active` = '{$active}' WHERE `id` = {$obj->id}";
         $dbObj->exec($sql);
     } catch (Exception $e) {
         $dbObj->rollback();
         echo "failed!";
         echo "\n";
         $clw = MpmCommandLineWriter::getInstance();
         $clw->writeLine($e->getMessage(), 12);
         if (!$forced) {
             echo "\n\n";
             exit;
         } else {
             return;
         }
     }
     $dbObj->commit();
     echo "done.";
 }
 /**
  * When part of the class autoloader stack, this method will dynamically try to located the proper class file and include it if the class is instantiated without already existing.
  *
  * @throws MpmClassUndefinedException
  *
  * @uses MPM_PATH
  * @uses MpmStringHelper::camelToLower()
  *
  * @param string $class_name the name of the class being instantiated
  *
  * @return void
  */
 public static function load($class_name)
 {
     // already loaded, don't need this method
     if (class_exists($class_name, false) || interface_exists($class_name, false)) {
         return;
     }
     // where do we store the classes?
     $class_path = MPM_PATH . '/lib';
     // class name is coming to us in camel caps with (possibly) an Mpm prefix... remove prefix and turn into lowercase string with underscores
     $filename = MpmStringHelper::camelToLower($class_name);
     if (substr($filename, 0, 4) == 'mpm_') {
         $filename = substr($filename, 4, strlen($filename));
     }
     $filename .= '.php';
     // is it in the class path?
     if (file_exists($class_path . '/' . $filename)) {
         require_once $class_path . '/' . $filename;
     } else {
         if (file_exists(MPM_PATH . '/config/' . $filename)) {
             require_once MPM_PATH . '/config/' . $filename;
         } else {
             $dir = dir($class_path);
             while (false != ($file = $dir->read())) {
                 if ($file != '..' && $file != '.' && is_dir($class_path . '/' . $file)) {
                     if (file_exists($class_path . '/' . $file . '/' . $filename)) {
                         require_once $class_path . '/' . $file . '/' . $filename;
                     }
                 }
             }
         }
     }
     // make sure we've included the class
     if (false === class_exists($class_name, false)) {
         if (false === interface_exists($class_name, false)) {
             throw new MpmClassUndefinedException('Class or interface "' . $class_name . '" does not exist.', E_USER_ERROR);
         }
     }
     return;
 }
예제 #6
0
 /**
  * Returns an array of objects which hold data about a migration file (timestamp, file, etc.).
  *
  * @uses MPM_DB_PATH
  * @uses MpmStringHelper::getTimestampFromFilename()
  *
  * @param string $sort should either be old or new; determines how the migrations are sorted in the array
  *
  * @return array
  */
 public static function getListOfFiles($sort = 'old')
 {
     $list = array();
     if ($sort == 'new') {
         $sort_order = 1;
     } else {
         $sort_order = 0;
     }
     $files = scandir(MPM_DB_PATH, $sort_order);
     foreach ($files as $file) {
         $full_file = MPM_DB_PATH . $file;
         if ($file != 'schema.php' && $file != '.' && $file != '..' && !is_dir($full_file) && stripos($full_file, '.php') !== false) {
             $timestamp = MpmStringHelper::getTimestampFromFilename($file);
             if ($timestamp !== null) {
                 $obj = (object) array();
                 $obj->timestamp = $timestamp;
                 $obj->filename = $file;
                 $obj->full_file = $full_file;
                 $list[] = $obj;
             }
         }
     }
     return $list;
 }
 /**
  * Performs a single migration.
  *
  * @uses MpmStringHelper::getFilenameFromTimestamp()
  * @uses MpmDbHelper::getPdoObj()
  * @uses MpmDbHelper::getMysqliObj()
  * @uses MpmCommandLineWriter::getInstance()
  * @uses MpmCommandLineWriter::writeLine()
  * @uses MPM_DB_PATH
  *
  * @param object  $obj        		    a simple object with migration information (from a migration list)
  * @param int    &$total_migrations_run a running total of migrations run
  * @param bool    $forced               if true, exceptions will not cause the script to exit
  *
  * @return void
  */
 public static function runMigration(&$obj, $method = 'up', $forced = false)
 {
     $file_timestamp = MpmStringHelper::getFilenameFromTimestamp($obj->timestamp);
     if ($method == 'up') {
         $classname = 'Migration_' . $file_timestamp;
         // make sure the file exists; if it doesn't, skip it but display a message
         $files = glob(MPM_DB_PATH . $file_timestamp . '*.php');
         if (empty($files)) {
             echo "\n\tMigration " . $obj->timestamp . ' (ID ' . $obj->id . ') skipped - file missing.';
             return;
         }
         if (count($files) > 1) {
             echo "\n\tError: Duplicate migration timestamp found! " . $obj->timestamp . ' (ID ' . $obj->id . ')';
             exit;
         }
         $filename = $files[0];
         // file exists -- run the migration
         echo "\n\tPerforming " . strtoupper($method) . " migration " . $obj->timestamp . ' (ID ' . $obj->id . ')... ';
         require_once $filename;
         $migration = new $classname();
     } else {
         //migrate down via stored database objects
         //fetch object from database
         //unserialize
         eval('?>' . $obj->objectstore . '<?');
         $down_migration = 'Migration_objectstore_' . $file_timestamp;
         $migration = new $down_migration();
         if (!$migration) {
             echo "failed!";
             $clw = MpmCommandLineWriter::getInstance();
             $clw->writeLine("Migration " . $obj->timestamp . ' (ID ' . $obj->id . ') - Object missing or broken', 12);
             if (!$forced) {
                 echo "\n\n";
                 exit;
             } else {
                 return;
             }
         }
         echo "\n\tPerforming " . strtoupper($method) . " migration " . $obj->timestamp . ' (ID ' . $obj->id . ')... ';
     }
     if ($migration instanceof MpmMigration) {
         $dbObj = MpmDbHelper::getPdoObj();
     } else {
         $dbObj = MpmDbHelper::getMysqliObj();
     }
     $dbObj->beginTransaction();
     if ($method == 'down') {
         $active = 0;
     } else {
         $active = 1;
     }
     try {
         $migration->{$method}($dbObj);
         if ($method == 'up') {
             //fetch object, store in database
             $string = file_get_contents($filename);
             $string = preg_replace('/(class Migration_)(\\d{4}(?:_\\d{2}){5})/', '$1objectstore_$2', $string, 1);
             $query_serial = sprintf(', objectstore="%s" ', $dbObj->real_escape_string($string));
             $sql = "UPDATE `mpm_migrations` SET `active` = '{$active}' {$query_serial} WHERE `id` = {$obj->id}";
         } else {
             //delete from database.
             //Old and new items may need to take same ID space in DB
             $sql = "DELETE FROM `mpm_migrations` WHERE `id` = {$obj->id}";
         }
         $dbObj->exec($sql);
     } catch (Exception $e) {
         $dbObj->rollback();
         echo "failed!";
         echo "\n";
         $clw = MpmCommandLineWriter::getInstance();
         $clw->writeLine($e->getMessage(), 12);
         if (!$forced) {
             echo "\n\n";
             exit;
         } else {
             return;
         }
     }
     $dbObj->commit();
     echo "done.";
 }
예제 #8
0
 /**
  * Returns an array of objects which hold data about a migration file (timestamp, file, etc.).
  *
  * @uses MPM_DB_PATH
  * @uses MpmStringHelper::getTimestampFromFilename()
  *
  * @param string $sort should either be old or new; determines how the migrations are sorted in the array
  *
  * @return array
  */
 public static function getListOfFiles($sort = 'old')
 {
     $list = array();
     $exclude_list = array("templates\\/", "schema\\.php\$", "test_data\\.php\$");
     $exclude_list_pattern = implode("|", $exclude_list);
     // SKIP_DOTS (. / ..) suppose to be included by default, but apparently not;
     $dir_iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(MPM_DB_PATH, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS));
     foreach ($dir_iter as $file) {
         $file_name = $file->getFilename();
         // abc.js
         $file_local_path = $file->getPathName();
         // /home/www/dev/jscommon/test/abc.js
         if (preg_match('/\\.php$/i', $file_name) && !preg_match('/' . $exclude_list_pattern . '/i', $file_name)) {
             $timestamp = MpmStringHelper::getTimestampFromFilename($file_name);
             if ($timestamp !== null) {
                 $obj = (object) array();
                 $obj->timestamp = $timestamp;
                 $obj->filename = $file_name;
                 $obj->full_file = $file_local_path;
                 $list[strtotime($timestamp)] = $obj;
             }
         }
     }
     // foreach
     // sort by timestamp
     if ($sort == 'new') {
         krsort($list, SORT_NUMERIC);
     } else {
         // 'old'
         ksort($list, SORT_NUMERIC);
     }
     return $list;
 }