/**
  * {@inheritdoc}
  */
 public function alterColumn(AbstractTable $table, AbstractColumn $initial, AbstractColumn $column)
 {
     $query = "ALTER TABLE {table} CHANGE {column} {statement}";
     $query = \Spiral\interpolate($query, ['table' => $table->getName(true), 'column' => $initial->getName(true), 'statement' => $column->sqlStatement()]);
     $this->run($query);
     return $this;
 }
 /**
  * {@inheritdoc}
  */
 public function alterColumn(AbstractTable $table, AbstractColumn $initial, AbstractColumn $column)
 {
     if (!$initial instanceof ColumnSchema || !$column instanceof ColumnSchema) {
         throw new SchemaException("Postgres commander can work only with Postgres columns.");
     }
     //Rename is separate operation
     if ($column->getName() != $initial->getName()) {
         $this->renameColumn($table, $initial, $column);
         //This call is required to correctly built set of alter operations
         $initial->setName($column->getName());
     }
     //Postgres columns should be altered using set of operations
     if (!($operations = $column->alteringOperations($initial))) {
         return $this;
     }
     //Postgres columns should be altered using set of operations
     $query = \Spiral\interpolate('ALTER TABLE {table} {operations}', ['table' => $table->getName(true), 'operations' => trim(join(', ', $operations), ', ')]);
     $this->run($query);
     return $this;
 }
 /**
  * Cast (specify) column schema based on provided column definition. Column definition are
  * compatible with database Migrations, AbstractColumn types and Record schema.
  *
  * @param AbstractTable  $table
  * @param AbstractColumn $column
  * @param string         $definition
  * @return AbstractColumn
  * @throws DefinitionException
  * @throws \Spiral\Database\Exceptions\SchemaException
  */
 private function castColumn(AbstractTable $table, AbstractColumn $column, $definition)
 {
     //Expression used to declare column type, easy to read
     $pattern = '/(?P<type>[a-z]+)(?: *\\((?P<options>[^\\)]+)\\))?(?: *, *(?P<nullable>null(?:able)?))?/i';
     if (!preg_match($pattern, $definition, $type)) {
         throw new DefinitionException("Invalid column type definition in '{$this}'.'{$column->getName()}'.");
     }
     if (!empty($type['options'])) {
         //Exporting and trimming
         $type['options'] = array_map('trim', explode(',', $type['options']));
     }
     //We are forcing every column to be NOT NULL by default, DEFAULT value should fix potential
     //problems, nullable flag must be applied before type was set (some types do not want
     //null values to be allowed)
     $column->nullable(!empty($type['nullable']));
     //Bypassing call to AbstractColumn->__call method (or specialized column method)
     call_user_func_array([$column, $type['type']], !empty($type['options']) ? $type['options'] : []);
     //Default value
     if (!$column->hasDefaultValue() && !$column->isNullable()) {
         //Ouch, columns like that can break synchronization!
         $column->defaultValue($this->castDefault($table, $column));
     }
     return $column;
 }
Exemple #4
0
 /**
  * Export default value from column schema into scalar form (which we can store in cache).
  *
  * @param AbstractColumn $column
  * @return mixed|null
  */
 private function exportDefault(AbstractColumn $column)
 {
     if (in_array($column->getName(), $this->tableSchema->getPrimaryKeys())) {
         //Column declared as primary key, nothing to do with default values
         return null;
     }
     $defaultValue = $column->getDefaultValue();
     if ($defaultValue instanceof FragmentInterface) {
         //We can't cache values like that
         return null;
     }
     if (is_null($defaultValue) && !$column->isNullable()) {
         return $this->castDefault($column);
     }
     return $defaultValue;
 }
Exemple #5
0
 /**
  * {@inheritdoc}
  */
 protected function doColumnChange(AbstractColumn $column, AbstractColumn $dbColumn)
 {
     $query = \Spiral\interpolate("ALTER TABLE {table} CHANGE {column} {statement}", ['table' => $this->getName(true), 'column' => $dbColumn->getName(true), 'statement' => $column->sqlStatement()]);
     $this->driver->statement($query);
 }
Exemple #6
0
 /**
  * {@inheritdoc}
  */
 protected function doColumnChange(AbstractColumn $column, AbstractColumn $dbColumn)
 {
     /**
      * @var ColumnSchema $column
      */
     //Rename is separate operation
     if ($column->getName() != $dbColumn->getName()) {
         $this->driver->statement(\Spiral\interpolate('ALTER TABLE {table} RENAME COLUMN {original} TO {column}', ['table' => $this->getName(true), 'column' => $column->getName(true), 'original' => $dbColumn->getName(true)]));
         $column->setName($dbColumn->getName());
     }
     //Postgres columns should be altered using set of operations
     if (!($operations = $column->alterOperations($dbColumn))) {
         return;
     }
     //Postgres columns should be altered using set of operations
     $query = \Spiral\interpolate('ALTER TABLE {table} {operations}', ['table' => $this->getName(true), 'operations' => trim(join(', ', $operations), ', ')]);
     $this->driver->statement($query);
 }
 /**
  * Driver specific column remove (drop) command.
  *
  * @param AbstractColumn $column
  */
 protected function doColumnDrop(AbstractColumn $column)
 {
     //We have to erase all associated constraints
     foreach ($column->getConstraints() as $constraint) {
         $this->doConstraintDrop($constraint);
     }
     if ($this->hasForeign($column->getName())) {
         $this->doForeignDrop($this->foreign($column->getName()));
     }
     $this->driver->statement("ALTER TABLE {$this->getName(true)} DROP COLUMN {$column->getName(true)}");
 }
Exemple #8
0
 /**
  * {@inheritdoc}
  */
 protected function doColumnChange(AbstractColumn $column, AbstractColumn $dbColumn)
 {
     /**
      * @var ColumnSchema $column
      * @var ColumnSchema $dbColumn
      */
     //Renaming is separate operation
     if ($column->getName() != $dbColumn->getName()) {
         $this->driver->statement("sp_rename ?, ?, 'COLUMN'", [$this->getName() . '.' . $dbColumn->getName(), $column->getName()]);
         $column->setName($dbColumn->getName());
     }
     //In SQLServer we have to drop ALL related indexes and foreign keys while
     //applying type change... yeah...
     $indexesBackup = [];
     $foreignBackup = [];
     foreach ($this->indexes as $index) {
         if (in_array($column->getName(), $index->getColumns())) {
             $indexesBackup[] = $index;
             $this->doIndexDrop($index);
         }
     }
     foreach ($this->references as $foreign) {
         if ($foreign->getColumn() == $column->getName()) {
             $foreignBackup[] = $foreign;
             $this->doForeignDrop($foreign);
         }
     }
     //Column will recreate needed constraints
     foreach ($column->getConstraints() as $constraint) {
         $this->doConstraintDrop($constraint);
     }
     foreach ($column->alterOperations($dbColumn) as $operation) {
         $query = \Spiral\interpolate('ALTER TABLE {table} {operation}', ['table' => $this->getName(true), 'operation' => $operation]);
         $this->driver->statement($query);
     }
     //Recreating indexes
     foreach ($indexesBackup as $index) {
         $this->doIndexAdd($index);
     }
     foreach ($foreignBackup as $foreign) {
         $this->doForeignAdd($foreign);
     }
 }
 /**
  * Driver specific column remove (drop) command.
  *
  * @param AbstractTable  $table
  * @param AbstractColumn $column
  * @return self
  */
 public function dropColumn(AbstractTable $table, AbstractColumn $column)
 {
     foreach ($column->getConstraints() as $constraint) {
         //We have to erase all associated constraints
         $this->dropConstrain($table, $constraint);
     }
     $this->run("ALTER TABLE {$table->getName(true)} DROP COLUMN {$column->getName(true)}");
     return $this;
 }
 /**
  * Register new column element.
  *
  * @param AbstractColumn $column
  * @return AbstractColumn
  */
 protected function registerColumn(AbstractColumn $column)
 {
     $this->columns[$column->getName()] = $column;
     return $column;
 }