Example #1
0
 /**
  * @throws WrongArgumentException
  * @return DBSchema
  **/
 public function addTable(DBTable $table)
 {
     $name = $table->getName();
     Assert::isFalse(isset($this->tables[$name]), "table '{$name}' already exist");
     $this->tables[$table->getName()] = $table;
     $this->order[] = $name;
     return $this;
 }
Example #2
0
 /**
  * @throws ObjectNotFoundException
  * @return DBTable
  **/
 public function getTableInfo($table)
 {
     static $types = ['time' => DataType::TIME, 'date' => DataType::DATE, 'timestamp' => DataType::TIMESTAMP, 'timestamptz' => DataType::TIMESTAMPTZ, 'timestamp with time zone' => DataType::TIMESTAMPTZ, 'bool' => DataType::BOOLEAN, 'int2' => DataType::SMALLINT, 'int4' => DataType::INTEGER, 'int8' => DataType::BIGINT, 'numeric' => DataType::NUMERIC, 'float4' => DataType::REAL, 'float8' => DataType::DOUBLE, 'varchar' => DataType::VARCHAR, 'bpchar' => DataType::CHAR, 'text' => DataType::TEXT, 'bytea' => DataType::BINARY, 'ip4' => DataType::IP, 'inet' => DataType::IP, 'ip4r' => DataType::IP_RANGE, 'hstore' => DataType::HSTORE, 'uuid' => DataType::UUID, 'json' => DataType::JSON, 'jsonb' => DataType::JSONB, 'tsvector' => null, 'ltree' => null];
     try {
         $res = pg_meta_data($this->link, $table);
     } catch (BaseException $e) {
         throw new ObjectNotFoundException("unknown table '{$table}'");
     }
     $table = new DBTable($table);
     foreach ($res as $name => $info) {
         Assert::isTrue(array_key_exists($info['type'], $types), 'unknown type "' . $types[$info['type']] . '" found in column "' . $name . '"');
         if (empty($types[$info['type']])) {
             continue;
         }
         $column = new DBColumn(DataType::create($types[$info['type']])->setNull(!$info['not null']), $name);
         $table->addColumn($column);
     }
     return $table;
 }
Example #3
0
 public static function findDifferences(Dialect $dialect, DBTable $source, DBTable $target)
 {
     $out = [];
     $head = 'ALTER TABLE ' . $dialect->quoteTable($target->getName());
     $sourceColumns = $source->getColumns();
     $targetColumns = $target->getColumns();
     foreach ($sourceColumns as $name => $column) {
         if (isset($targetColumns[$name])) {
             if ($column->getType()->getId() != $targetColumns[$name]->getType()->getId()) {
                 $targetColumn = $targetColumns[$name];
                 $out[] = $head . ' ALTER COLUMN ' . $dialect->quoteField($name) . ' TYPE ' . $targetColumn->getType()->toString() . ($targetColumn->getType()->hasSize() ? '(' . $targetColumn->getType()->getSize() . ($targetColumn->getType()->hasPrecision() ? ', ' . $targetColumn->getType()->getPrecision() : null) . ')' : null) . (in_array($targetColumn->getType()->getId(), array(DataType::JSON, DataType::JSONB)) ? ' USING NULL' : '') . ';';
             }
             if ($column->getType()->isNull() != $targetColumns[$name]->getType()->isNull()) {
                 $out[] = $head . ' ALTER COLUMN ' . $dialect->quoteField($name) . ' ' . ($targetColumns[$name]->getType()->isNull() ? 'DROP' : 'SET') . ' NOT NULL;';
             }
         } else {
             $out[] = $head . ' DROP COLUMN ' . $dialect->quoteField($name) . ';';
         }
     }
     foreach ($targetColumns as $name => $column) {
         if (!isset($sourceColumns[$name])) {
             $out[] = $head . ' ADD COLUMN ' . $column->toDialectString($dialect) . ';';
             if ($column->hasReference()) {
                 $out[] = 'CREATE INDEX ' . $dialect->quoteField($name . '_idx') . ' ON ' . $dialect->quoteTable($target->getName()) . '(' . $dialect->quoteField($name) . ');';
             }
         }
     }
     return $out;
 }
Example #4
0
 /**
  * @return MetaConfiguration
  **/
 public function buildSchemaChanges()
 {
     $out = $this->getOutput();
     $out->newLine()->infoLine('Suggested DB-schema changes: ');
     require HESPER_META_AUTO_DIR . 'schema.php';
     foreach ($this->classes as $class) {
         if ($class->getTypeId() == MetaClassType::CLASS_ABSTRACT || $class->getPattern() instanceof EnumerationClassPattern || $class->getPattern() instanceof EnumClassPattern || $class->getPattern() instanceof RegistryClassPattern) {
             continue;
         }
         try {
             $target = $schema->getTableByName($class->getTableName());
         } catch (MissingElementException $e) {
             // dropped or tableless
             continue;
         }
         try {
             $db = DBPool::me()->getLink($class->getSourceLink());
         } catch (BaseException $e) {
             $out->errorLine('Can not connect using source link in \'' . $class->getName() . '\' class, skipping this step.');
             break;
         }
         try {
             $source = $db->getTableInfo($class->getTableName());
         } catch (UnsupportedMethodException $e) {
             $out->errorLine(get_class($db) . ' does not support tables introspection yet.', true);
             break;
         } catch (ObjectNotFoundException $e) {
             $out->errorLine("table '{$class->getTableName()}' not found, skipping.");
             continue;
         }
         $diff = DBTable::findDifferences($db->getDialect(), $source, $target);
         if ($diff) {
             foreach ($diff as $line) {
                 $out->warningLine($line);
             }
             $out->newLine();
         }
     }
     return $this;
 }
Example #5
0
 public function getTableInfo($table)
 {
     static $types = ['tinyint' => DataType::SMALLINT, 'smallint' => DataType::SMALLINT, 'int' => DataType::INTEGER, 'mediumint' => DataType::INTEGER, 'bigint' => DataType::BIGINT, 'double' => DataType::DOUBLE, 'decimal' => DataType::NUMERIC, 'char' => DataType::CHAR, 'varchar' => DataType::VARCHAR, 'text' => DataType::TEXT, 'tinytext' => DataType::TEXT, 'mediumtext' => DataType::TEXT, 'date' => DataType::DATE, 'time' => DataType::TIME, 'timestamp' => DataType::TIMESTAMP, 'datetime' => DataType::TIMESTAMP, 'set' => null, 'enum' => null, 'year' => null];
     try {
         $result = $this->queryRaw('SHOW COLUMNS FROM ' . $table);
     } catch (BaseException $e) {
         throw new ObjectNotFoundException("unknown table '{$table}'");
     }
     $table = new DBTable($table);
     while ($row = mysqli_fetch_array($result)) {
         $name = strtolower($row['Field']);
         $matches = [];
         $info = ['type' => null, 'extra' => null];
         if (preg_match('~(\\w+)(\\((\\d+?)\\)){0,1}\\s*(\\w*)~', strtolower($row['Type']), $matches)) {
             $info['type'] = $matches[1];
             $info['size'] = $matches[3];
             $info['extra'] = $matches[4];
         }
         Assert::isTrue(array_key_exists($info['type'], $types), 'unknown type "' . $types[$info['type']] . '" found in column "' . $name . '"');
         if (empty($types[$info['type']])) {
             continue;
         }
         $column = DBColumn::create(DataType::create($types[$info['type']])->setUnsigned(strtolower($info['extra']) == 'unsigned')->setNull(strtolower($row['Null']) == 'yes'), $name)->setAutoincrement(strtolower($row['Extra']) == 'auto_increment')->setPrimaryKey(strtolower($row['Key']) == 'pri');
         if ($row['Default']) {
             $column->setDefault($row['Default']);
         }
         $table->addColumn($column);
     }
     return $table;
 }