Beispiel #1
0
 /**
  * Create ProjectState based on migrations on disk.
  *
  * @return ProjectState
  *
  * @throws NodeNotFoundError
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 public function getState()
 {
     $leaves = $this->getLeafNodes();
     $state = ProjectState::createObject();
     if (empty($leaves)) {
         return $state;
     }
     // from the leave go up its family tree though its parents and ancestors until we get to the root_node.
     // this way we get the full lineage we need to follow to get to this leaf from root_node to leaf_node
     // we use this lineage to apply migrations in database
     $lineage = [];
     foreach ($leaves as $leaf) {
         // get lineage
         $lineage_members = $this->getAncestryTree($leaf);
         foreach ($lineage_members as $i => $l_member) {
             if (in_array($l_member, $lineage)) {
                 continue;
             }
             $lineage[] = $l_member;
         }
     }
     // use the lineage to update the project state based on the migrations.
     /* @var $migration Migration */
     foreach ($lineage as $member) {
         $migration = $this->nodes[$member];
         $state = $migration->updateState($state);
     }
     return $state;
 }
Beispiel #2
0
 /**
  * Migrates the database up to the given targets.
  *
  * @param $targets
  * @param $plan
  * @param $fake
  *
  * @since 1.1.0
  *
  * @author Eddilbert Macharia (http://eddmash.com) <*****@*****.**>
  */
 public function migrate($targets, $plan, $fake)
 {
     if (empty($plan)) {
         $plan = $this->getMigrationPlan($targets);
     }
     $migrationsToRun = $this->getMigrationsFromPlan($plan);
     // the full plan that would be executed if we to run on a new database
     $fullPlan = $this->getMigrationsFromPlan($this->getMigrationPlan($this->loader->graph->getLeafNodes(), true));
     // Holds all states right before a migration is applied
     // if the migration is being run.
     $states = [];
     $state = ProjectState::createObject();
     //Phase 1 -- create all project states before a migration is (un)applied
     /** @var $migration Migration */
     foreach ($fullPlan as $migName => $migration) {
         // we use the migration to mutate state
         // after we mutate we remove the migration from the $migrationsToRun list.
         // so if we get to a point where we dont have any more $migrationsToRun break
         // this is to avoid any further mutations by other migrations not in the list.
         if (empty($migrationsToRun)) {
             break;
         }
         $run = ArrayHelper::hasKey($migrationsToRun, $migName);
         if ($run) {
             $states[$migName] = $state->deepClone();
             unset($migrationsToRun[$migName]);
         }
         // $run will be false if the migration is not in the $migrationsToRun list
         // so there is not need to preserve state else if its in the list we need to  we will get a new state object
         // that has been altered by the migration.
         // we do this because we need the object stored in the states array in the condition it was right before
         // the migration was applied.
         // remember in PHP objects are passed by reference.
         $state = $migration->updateState($state, $run);
     }
     // Phase 2 -- Run the migrations
     foreach ($plan as $mName => $migrationMeta) {
         if ($migrationMeta['unapply']) {
             $this->unApplyMigration($states[$mName], $migrationMeta['migration'], $fake);
         } else {
             $this->applyMigration($states[$mName], $migrationMeta['migration'], $fake);
         }
     }
 }