public function build() { $path = '.'; if (isset($this->_options['directory'])) { $path = $this->_options['directory']; } $config = $this->_getConfig($path . '/'); $modelsDir = $config->application->modelsDir; $forceProcess = $this->_options['force']; if (isset($this->_options['defineRelations'])) { $defineRelations = $this->_options['defineRelations']; } else { $defineRelations = false; } if (isset($this->_options['foreignKeys'])) { $defineForeignKeys = $this->_options['foreignKeys']; } else { $defineForeignKeys = false; } if (isset($this->_options['genSettersGetters'])) { $genSettersGetters = $this->_options['genSettersGetters']; } else { $genSettersGetters = false; } $adapter = $config->database->adapter; $this->isSupportedAdapter($adapter); if (isset($config->database->adapter)) { $adapter = $config->database->adapter; } else { $adapter = 'Mysql'; } if (is_object($config->database)) { $configArray = $config->database->toArray(); } else { $configArray = $config->database; } $adapterName = 'Phalcon\\Db\\Adapter\\Pdo\\' . $adapter; unset($configArray['adapter']); /** * @var $db \Phalcon\Db\Adapter\Pdo */ $db = new $adapterName($configArray); if (isset($this->_options['schema'])) { $schema = $this->_options['schema']; } elseif ($adapter == 'Postgresql') { $schema = 'public'; } else { $schema = isset($config->database->schema) ? $config->database->schema : $config->database->dbname; } $hasMany = array(); $belongsTo = array(); $foreignKeys = array(); if ($defineRelations || $defineForeignKeys) { foreach ($db->listTables($schema) as $name) { if ($defineRelations) { if (!isset($hasMany[$name])) { $hasMany[$name] = array(); } if (!isset($belongsTo[$name])) { $belongsTo[$name] = array(); } } if ($defineForeignKeys) { $foreignKeys[$name] = array(); } $camelCaseName = Utils::camelize($name); $refSchema = $adapter != 'Postgresql' ? $schema : $config->database->dbname; foreach ($db->describeReferences($name, $schema) as $reference) { $columns = $reference->getColumns(); $referencedColumns = $reference->getReferencedColumns(); $referencedModel = Utils::camelize($reference->getReferencedTable()); if ($defineRelations) { if ($reference->getReferencedSchema() == $refSchema) { if (count($columns) == 1) { $belongsTo[$name][] = array('referencedModel' => $referencedModel, 'fields' => $columns[0], 'relationFields' => $referencedColumns[0], 'options' => $defineForeignKeys ? array('foreignKey' => true) : NULL); $hasMany[$reference->getReferencedTable()][] = array('camelizedName' => $camelCaseName, 'fields' => $referencedColumns[0], 'relationFields' => $columns[0]); } } } } } } else { foreach ($db->listTables($schema) as $name) { if ($defineRelations) { $hasMany[$name] = array(); $belongsTo[$name] = array(); $foreignKeys[$name] = array(); } } } foreach ($db->listTables($schema) as $name) { $className = Utils::camelize($name); if (!file_exists($modelsDir . '/' . $className . '.php') || $forceProcess) { if (isset($hasMany[$name])) { $hasManyModel = $hasMany[$name]; } else { $hasManyModel = array(); } if (isset($belongsTo[$name])) { $belongsToModel = $belongsTo[$name]; } else { $belongsToModel = array(); } if (isset($foreignKeys[$name])) { $foreignKeysModel = $foreignKeys[$name]; } else { $foreignKeysModel = array(); } $modelBuilder = new \Phalcon\Builder\Model(array('name' => $name, 'schema' => $schema, 'extends' => isset($this->_options['extends']) ? $this->_options['extends'] : null, 'namespace' => $this->_options['namespace'], 'force' => $forceProcess, 'hasMany' => $hasManyModel, 'belongsTo' => $belongsToModel, 'foreignKeys' => $foreignKeysModel, 'genSettersGetters' => $genSettersGetters, 'directory' => $this->_options['directory'])); $modelBuilder->build(); } else { if ($this->isConsole()) { print Color::info("Skipping model \"{$name}\" because it already exist"); } else { $this->exist[] = $name; } } } }
public function build() { if ($this->options->contains('directory')) { $this->path->setRootPath($this->options->get('directory')); } $this->options->offsetSet('directory', $this->path->getRootPath()); $config = $this->getConfig(); if (!($modelsDir = $this->options->get('modelsDir'))) { if (!isset($config->application->modelsDir)) { throw new BuilderException("Builder doesn't know where is the models directory."); } $modelsDir = $config->application->modelsDir; } $modelsDir = rtrim($modelsDir, '/\\') . DIRECTORY_SEPARATOR; $modelPath = $modelsDir; if (false == $this->isAbsolutePath($modelsDir)) { $modelPath = $this->path->getRootPath($modelsDir); } $this->options->offsetSet('modelsDir', $modelPath); $forceProcess = $this->options->get('force'); $defineRelations = $this->options->get('defineRelations', false); $defineForeignKeys = $this->options->get('foreignKeys', false); $genSettersGetters = $this->options->get('genSettersGetters', false); $mapColumn = $this->options->get('mapColumn', null); $adapter = $config->database->adapter; $this->isSupportedAdapter($adapter); $adapter = 'Mysql'; if (isset($config->database->adapter)) { $adapter = $config->database->adapter; } if (is_object($config->database)) { $configArray = $config->database->toArray(); } else { $configArray = $config->database; } $adapterName = 'Phalcon\\Db\\Adapter\\Pdo\\' . $adapter; unset($configArray['adapter']); /** * @var $db \Phalcon\Db\Adapter\Pdo */ $db = new $adapterName($configArray); if ($this->options->contains('schema')) { $schema = $this->options->get('schema'); } elseif ($adapter == 'Postgresql') { $schema = 'public'; } else { $schema = isset($config->database->schema) ? $config->database->schema : $config->database->dbname; } $hasMany = array(); $belongsTo = array(); $foreignKeys = array(); if ($defineRelations || $defineForeignKeys) { foreach ($db->listTables($schema) as $name) { if ($defineRelations) { if (!isset($hasMany[$name])) { $hasMany[$name] = array(); } if (!isset($belongsTo[$name])) { $belongsTo[$name] = array(); } } if ($defineForeignKeys) { $foreignKeys[$name] = array(); } $camelCaseName = Utils::camelize($name); $refSchema = $adapter != 'Postgresql' ? $schema : $config->database->dbname; foreach ($db->describeReferences($name, $schema) as $reference) { $columns = $reference->getColumns(); $referencedColumns = $reference->getReferencedColumns(); $referencedModel = Utils::camelize($reference->getReferencedTable()); if ($defineRelations) { if ($reference->getReferencedSchema() == $refSchema) { if (count($columns) == 1) { $belongsTo[$name][] = array('referencedModel' => $referencedModel, 'fields' => $columns[0], 'relationFields' => $referencedColumns[0], 'options' => $defineForeignKeys ? array('foreignKey' => true) : null); $hasMany[$reference->getReferencedTable()][] = array('camelizedName' => $camelCaseName, 'fields' => $referencedColumns[0], 'relationFields' => $columns[0]); } } } } } } else { foreach ($db->listTables($schema) as $name) { if ($defineRelations) { $hasMany[$name] = array(); $belongsTo[$name] = array(); $foreignKeys[$name] = array(); } } } foreach ($db->listTables($schema) as $name) { $className = $this->options->contains('abstract') ? 'Abstract' : ''; $className .= Utils::camelize($name); if (!file_exists($modelPath . $className . '.php') || $forceProcess) { if (isset($hasMany[$name])) { $hasManyModel = $hasMany[$name]; } else { $hasManyModel = array(); } if (isset($belongsTo[$name])) { $belongsToModel = $belongsTo[$name]; } else { $belongsToModel = array(); } if (isset($foreignKeys[$name])) { $foreignKeysModel = $foreignKeys[$name]; } else { $foreignKeysModel = array(); } $modelBuilder = new Model(array('name' => $name, 'schema' => $schema, 'extends' => $this->options->get('extends'), 'namespace' => $this->options->get('namespace'), 'force' => $forceProcess, 'hasMany' => $hasManyModel, 'belongsTo' => $belongsToModel, 'foreignKeys' => $foreignKeysModel, 'genSettersGetters' => $genSettersGetters, 'directory' => $this->options->get('directory'), 'modelsDir' => $this->options->get('modelsDir'), 'mapColumn' => $mapColumn, 'abstract' => $this->options->get('abstract'))); $modelBuilder->build(); } else { if ($this->isConsole()) { print Color::info(sprintf('Skipping model "%s" because it already exist', Utils::camelize($name))); } else { $this->exist[] = $name; } } } }
/** * Run migrations * * @param array $options * * @throws Exception * @throws ModelException * @throws ScriptException * */ public static function run(array $options) { // Define versioning type to be used if (true === $options['tsBased']) { VersionCollection::setType(VersionCollection::TYPE_TIMESTAMPED); } else { VersionCollection::setType(VersionCollection::TYPE_INCREMENTAL); } $migrationsDir = rtrim($options['migrationsDir'], '/'); if (!file_exists($migrationsDir)) { throw new ModelException('Migrations directory was not found.'); } /** @var Config $config */ $config = $options['config']; if (!$config instanceof Config) { throw new ModelException('Internal error. Config should be an instance of \\Phalcon\\Config'); } // Init ModelMigration if (!isset($config->database)) { throw new ScriptException('Cannot load database configuration'); } $finalVersion = null; if (isset($options['version']) && $options['version'] !== null) { $finalVersion = VersionCollection::createItem($options['version']); } $tableName = 'all'; if (isset($options['tableName'])) { $tableName = $options['tableName']; } $versionItems = ModelMigration::scanForVersions($migrationsDir); if (!isset($versionItems[0])) { throw new ModelException('Migrations were not found at ' . $migrationsDir); } // Set default final version if ($finalVersion === null) { $finalVersion = VersionCollection::maximum($versionItems); } ModelMigration::setup($config->database); ModelMigration::setMigrationPath($migrationsDir); self::connectionSetup($options); $initialVersion = self::getCurrentVersion($options); $completedVersions = self::getCompletedVersions($options); // Everything is up to date if ($initialVersion->getStamp() === $finalVersion->getStamp()) { print Color::info('Everything is up to date'); exit(0); } $direction = ModelMigration::DIRECTION_FORWARD; if ($finalVersion->getStamp() < $initialVersion->getStamp()) { $direction = ModelMigration::DIRECTION_BACK; } if (ModelMigration::DIRECTION_FORWARD === $direction) { // If we migrate up, we should go from the beginning to run some migrations which may have been missed $versionItemsTmp = VersionCollection::sortAsc(array_merge($versionItems, [$initialVersion])); $initialVersion = $versionItemsTmp[0]; } else { // If we migrate downs, we should go from the last migration to revert some migrations which may have been missed $versionItemsTmp = VersionCollection::sortDesc(array_merge($versionItems, [$initialVersion])); $initialVersion = $versionItemsTmp[0]; } // Run migration $versionsBetween = VersionCollection::between($initialVersion, $finalVersion, $versionItems); foreach ($versionsBetween as $versionItem) { if (ModelMigration::DIRECTION_FORWARD === $direction && isset($completedVersions[(string) $versionItem])) { print Color::info('Version ' . (string) $versionItem . ' was already applied'); continue; } elseif (ModelMigration::DIRECTION_BACK === $direction && !isset($completedVersions[(string) $versionItem])) { print Color::info('Version ' . (string) $versionItem . ' was already rolled back'); continue; } if ($versionItem->getVersion() === $finalVersion->getVersion() && ModelMigration::DIRECTION_BACK === $direction) { break; } $migrationStartTime = date("'Y-m-d H:i:s'"); if ($tableName === 'all') { $iterator = new DirectoryIterator($migrationsDir . DIRECTORY_SEPARATOR . $versionItem->getVersion()); foreach ($iterator as $fileInfo) { if (!$fileInfo->isFile() || 0 !== strcasecmp($fileInfo->getExtension(), 'php')) { continue; } ModelMigration::migrate($initialVersion, $versionItem, $fileInfo->getBasename('.php'), $direction); } } else { ModelMigration::migrate($initialVersion, $versionItem, $tableName, $direction); } if (ModelMigration::DIRECTION_FORWARD == $direction) { self::addCurrentVersion($options, (string) $versionItem, $migrationStartTime); print Color::success('Version ' . $versionItem . ' was successfully migrated'); } else { self::removeCurrentVersion($options, (string) $versionItem); print Color::success('Version ' . $versionItem . ' was successfully rolled back'); } $initialVersion = $versionItem; } }