/** * 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; }
/** * 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; }