Ejemplo n.º 1
0
 /**
  * @param AbstractTable $table
  * @param RecordSchema  $record
  */
 public function __construct(AbstractTable $table, RecordSchema $record)
 {
     $altered = [];
     foreach ($table->alteredColumns() as $column) {
         $altered[] = $column->getName();
     }
     parent::__construct(\Spiral\interpolate('Passive table "{database}"."{table}" ({record}), were altered, columns: {columns}', ['database' => $record->getDatabase(), 'table' => $table->getName(), 'record' => $record, 'columns' => join(', ', $altered)]));
 }
Ejemplo n.º 2
0
 /**
  * Cast default value based on column type. Required to prevent conflicts when not nullable
  * column added to existed table with data in.
  *
  * @param AbstractColumn $column
  * @return bool|float|int|mixed|string
  */
 private function castDefault(AbstractColumn $column)
 {
     if ($column->abstractType() == 'timestamp' || $column->abstractType() == 'datetime') {
         $driver = $this->tableSchema->driver();
         return $driver::DEFAULT_DATETIME;
     }
     if ($column->abstractType() == 'enum') {
         //We can use first enum value as default
         return $column->getEnumValues()[0];
     }
     if ($column->abstractType() == 'json') {
         return '{}';
     }
     switch ($column->phpType()) {
         case 'int':
             return 0;
             break;
         case 'float':
             return 0.0;
             break;
         case 'bool':
             return false;
             break;
     }
     return '';
 }
Ejemplo n.º 3
0
 /**
  * @param Driver            $driver Parent driver.
  * @param AbstractCommander $commander
  * @param string            $name   Table name, must include table prefix.
  * @param string            $prefix Database specific table prefix.
  */
 public function __construct(Driver $driver, AbstractCommander $commander, $name, $prefix)
 {
     parent::__construct($driver, $commander, $name, $prefix);
     //Let's load table type, just for fun
     if ($this->exists()) {
         $query = $driver->query('SHOW TABLE STATUS WHERE Name = ?', [$name]);
         $this->engine = $query->fetch()['Engine'];
     }
 }
Ejemplo n.º 4
0
 /**
  * Index sql creation syntax.
  *
  * @param bool $includeTable Include table ON statement (not required for inline index
  *                           creation).
  * @return string
  */
 public function sqlStatement($includeTable = true)
 {
     $statement = [];
     $statement[] = $this->type . ($this->type == self::UNIQUE ? ' INDEX' : '');
     $statement[] = $this->getName(true);
     if ($includeTable) {
         $statement[] = 'ON ' . $this->table->getName(true);
     }
     $statement[] = '(' . join(', ', array_map([$this->table->driver(), 'identifier'], $this->columns)) . ')';
     return join(' ', $statement);
 }
Ejemplo n.º 5
0
 /**
  * Foreign key creation syntax.
  *
  * @return string
  */
 public function sqlStatement()
 {
     $statement = [];
     $statement[] = 'CONSTRAINT';
     $statement[] = $this->getName(true);
     $statement[] = 'FOREIGN KEY';
     $statement[] = '(' . $this->table->driver()->identifier($this->column) . ')';
     $statement[] = 'REFERENCES ' . $this->table->driver()->identifier($this->foreignTable);
     $statement[] = '(' . $this->table->driver()->identifier($this->foreignKey) . ')';
     $statement[] = "ON DELETE {$this->deleteRule}";
     $statement[] = "ON UPDATE {$this->updateRule}";
     return join(" ", $statement);
 }
Ejemplo n.º 6
0
 /**
  * @param AbstractTable $schema
  * @return AbstractColumn
  * @throws ColumnException
  */
 protected function declareColumn(AbstractTable $schema)
 {
     $column = $schema->column($this->name);
     //Type configuring
     if (method_exists($column, $this->type)) {
         $arguments = [];
         $method = new \ReflectionMethod($column, $this->type);
         foreach ($method->getParameters() as $parameter) {
             if ($this->hasOption($parameter->getName())) {
                 $arguments[] = $this->getOption($parameter->getName());
             } elseif (!$parameter->isOptional()) {
                 throw new ColumnException("Option '{$parameter->getName()}' are required to define column with type '{$this->type}'");
             } else {
                 $arguments[] = $parameter->getDefaultValue();
             }
         }
         call_user_func_array([$column, $this->type], $arguments);
     } else {
         $column->setType($this->type);
     }
     $column->nullable($this->getOption('nullable', false));
     $column->defaultValue($this->getOption('default', null));
     return $column;
 }
Ejemplo n.º 7
0
 /**
  * {@inheritdoc}
  */
 public function dropForeign(AbstractTable $table, AbstractReference $foreign)
 {
     $this->run("ALTER TABLE {$table->getName(true)} DROP FOREIGN KEY {$foreign->getName(true)}");
     return $this;
 }
Ejemplo n.º 8
0
 /**
  * Must return driver specific default value.
  *
  * @return string
  */
 protected function prepareDefault()
 {
     if (($defaultValue = $this->getDefaultValue()) === null) {
         return 'NULL';
     }
     if ($defaultValue instanceof SQLFragmentInterface) {
         return $defaultValue->sqlStatement();
     }
     if ($this->phpType() == 'bool') {
         return $defaultValue ? 'TRUE' : 'FALSE';
     }
     if ($this->phpType() == 'float') {
         return sprintf('%F', $defaultValue);
     }
     if ($this->phpType() == 'int') {
         return $defaultValue;
     }
     return $this->table->driver()->getPDO()->quote($defaultValue);
 }
Ejemplo n.º 9
0
 /**
  * Copy table data to another location.
  *
  * @see http://stackoverflow.com/questions/4007014/alter-column-in-sqlite
  * @param AbstractTable $temporary
  * @param array         $mapping Association between old and new columns (quoted).
  */
 private function copyData(AbstractTable $temporary, array $mapping)
 {
     $this->logger()->debug("Copying table data from {source} to {table} using mapping ({columns}) => ({target}).", ['source' => $this->driver->identifier($this->initial->getName()), 'table' => $temporary->getName(true), 'columns' => join(', ', $mapping), 'target' => join(', ', array_keys($mapping))]);
     $query = \Spiral\interpolate("INSERT INTO {table} ({target}) SELECT {columns} FROM {source}", ['source' => $this->driver->identifier($this->initial->getName()), 'table' => $temporary->getName(true), 'columns' => join(', ', $mapping), 'target' => join(', ', array_keys($mapping))]);
     //Let's go
     $this->driver->statement($query);
 }
Ejemplo n.º 10
0
 /**
  * {@inheritdoc}
  */
 protected function createSchema($execute = true)
 {
     $statement = parent::createSchema(false);
     //Additional table options
     $options = "ENGINE = {engine}";
     $statement = $statement . ' ' . \Spiral\interpolate($options, ['engine' => $this->engine]);
     if ($execute) {
         $this->driver->statement($statement);
         //Not all databases support adding index while table creation, so we can do it after
         foreach ($this->indexes as $index) {
             $this->doIndexAdd($index);
         }
     }
     return $statement;
 }
Ejemplo n.º 11
0
 /**
  * Get statement needed to create table.
  *
  * @param AbstractTable $table
  * @return string
  */
 protected function createStatement(AbstractTable $table)
 {
     $statement = ["CREATE TABLE {$table->getName(true)} ("];
     $innerStatement = [];
     //Columns
     foreach ($table->getColumns() as $column) {
         $innerStatement[] = $column->sqlStatement();
     }
     //Primary key
     if (!empty($table->getPrimaryKeys())) {
         $primaryKeys = array_map([$this, 'quote'], $table->getPrimaryKeys());
         $innerStatement[] = 'PRIMARY KEY (' . join(', ', $primaryKeys) . ')';
     }
     //Constraints and foreign keys
     foreach ($table->getForeigns() as $reference) {
         $innerStatement[] = $reference->sqlStatement();
     }
     $statement[] = "    " . join(",\n    ", $innerStatement);
     $statement[] = ')';
     return join("\n", $statement);
 }
Ejemplo n.º 12
0
 /**
  * Table aliases associated with given table schema.
  *
  * @param AbstractTable $table
  * @return string
  * @throws SchemaException
  */
 public function tableAlias(AbstractTable $table)
 {
     foreach ($this->aliases as $item) {
         if ($item['schema'] === $table) {
             return $item['table'];
         }
     }
     throw new SchemaException("Unable to resolve table alias for table '{$table->getName()}'");
 }
Ejemplo n.º 13
0
 /**
  * @param AbstractTable $table
  * @param ColumnSchema  $initial
  * @param ColumnSchema  $column
  */
 private function renameColumn(AbstractTable $table, ColumnSchema $initial, ColumnSchema $column)
 {
     $statement = \Spiral\interpolate('ALTER TABLE {table} RENAME COLUMN {column} TO {name}', ['table' => $table->getName(true), 'column' => $initial->getName(true), 'name' => $column->getName(true)]);
     $this->run($statement);
 }