connection = $connection; $this->grammar = $connection->getSchemaGrammar(); } /** * Set the default string length for migrations. * * @param int $length * @return void */ public static function defaultStringLength($length) { static::$defaultStringLength = $length; } /** * Set the default morph key type for migrations. * * @param string $type * @return void * * @throws \InvalidArgumentException */ public static function defaultMorphKeyType(string $type) { if (! in_array($type, ['int', 'uuid', 'ulid'])) { throw new InvalidArgumentException("Morph key type must be 'int', 'uuid', or 'ulid'."); } static::$defaultMorphKeyType = $type; } /** * Set the default morph key type for migrations to UUIDs. * * @return void */ public static function morphUsingUuids() { return static::defaultMorphKeyType('uuid'); } /** * Set the default morph key type for migrations to ULIDs. * * @return void */ public static function morphUsingUlids() { return static::defaultMorphKeyType('ulid'); } /** * Create a database in the schema. * * @param string $name * @return bool * * @throws \LogicException */ public function createDatabase($name) { throw new LogicException('This database driver does not support creating databases.'); } /** * Drop a database from the schema if the database exists. * * @param string $name * @return bool * * @throws \LogicException */ public function dropDatabaseIfExists($name) { throw new LogicException('This database driver does not support dropping databases.'); } /** * Determine if the given table exists. * * @param string $table * @return bool */ public function hasTable($table) { $table = $this->connection->getTablePrefix().$table; foreach ($this->getTables(false) as $value) { if (strtolower($table) === strtolower($value['name'])) { return true; } } return false; } /** * Determine if the given view exists. * * @param string $view * @return bool */ public function hasView($view) { $view = $this->connection->getTablePrefix().$view; foreach ($this->getViews() as $value) { if (strtolower($view) === strtolower($value['name'])) { return true; } } return false; } /** * Get the tables that belong to the database. * * @return array */ public function getTables() { return $this->connection->getPostProcessor()->processTables( $this->connection->selectFromWriteConnection($this->grammar->compileTables()) ); } /** * Get the names of the tables that belong to the database. * * @return array */ public function getTableListing() { return array_column($this->getTables(), 'name'); } /** * Get the views that belong to the database. * * @return array */ public function getViews() { return $this->connection->getPostProcessor()->processViews( $this->connection->selectFromWriteConnection($this->grammar->compileViews()) ); } /** * Get the user-defined types that belong to the database. * * @return array */ public function getTypes() { throw new LogicException('This database driver does not support user-defined types.'); } /** * Determine if the given table has a given column. * * @param string $table * @param string $column * @return bool */ public function hasColumn($table, $column) { return in_array( strtolower($column), array_map('strtolower', $this->getColumnListing($table)) ); } /** * Determine if the given table has given columns. * * @param string $table * @param array $columns * @return bool */ public function hasColumns($table, array $columns) { $tableColumns = array_map('strtolower', $this->getColumnListing($table)); foreach ($columns as $column) { if (! in_array(strtolower($column), $tableColumns)) { return false; } } return true; } /** * Execute a table builder callback if the given table has a given column. * * @param string $table * @param string $column * @param \Closure $callback * @return void */ public function whenTableHasColumn(string $table, string $column, Closure $callback) { if ($this->hasColumn($table, $column)) { $this->table($table, fn (Blueprint $table) => $callback($table)); } } /** * Execute a table builder callback if the given table doesn't have a given column. * * @param string $table * @param string $column * @param \Closure $callback * @return void */ public function whenTableDoesntHaveColumn(string $table, string $column, Closure $callback) { if (! $this->hasColumn($table, $column)) { $this->table($table, fn (Blueprint $table) => $callback($table)); } } /** * Get the data type for the given column name. * * @param string $table * @param string $column * @param bool $fullDefinition * @return string */ public function getColumnType($table, $column, $fullDefinition = false) { $columns = $this->getColumns($table); foreach ($columns as $value) { if (strtolower($value['name']) === $column) { return $fullDefinition ? $value['type'] : $value['type_name']; } } throw new InvalidArgumentException("There is no column with name '$column' on table '$table'."); } /** * Get the column listing for a given table. * * @param string $table * @return array */ public function getColumnListing($table) { return array_column($this->getColumns($table), 'name'); } /** * Get the columns for a given table. * * @param string $table * @return array */ public function getColumns($table) { $table = $this->connection->getTablePrefix().$table; return $this->connection->getPostProcessor()->processColumns( $this->connection->selectFromWriteConnection($this->grammar->compileColumns($table)) ); } /** * Get the indexes for a given table. * * @param string $table * @return array */ public function getIndexes($table) { $table = $this->connection->getTablePrefix().$table; return $this->connection->getPostProcessor()->processIndexes( $this->connection->selectFromWriteConnection($this->grammar->compileIndexes($table)) ); } /** * Get the names of the indexes for a given table. * * @param string $table * @return array */ public function getIndexListing($table) { return array_column($this->getIndexes($table), 'name'); } /** * Determine if the given table has a given index. * * @param string $table * @param string|array $index * @param string|null $type * @return bool */ public function hasIndex($table, $index, $type = null) { $type = is_null($type) ? $type : strtolower($type); foreach ($this->getIndexes($table) as $value) { $typeMatches = is_null($type) || ($type === 'primary' && $value['primary']) || ($type === 'unique' && $value['unique']) || $type === $value['type']; if (($value['name'] === $index || $value['columns'] === $index) && $typeMatches) { return true; } } return false; } /** * Get the foreign keys for a given table. * * @param string $table * @return array */ public function getForeignKeys($table) { $table = $this->connection->getTablePrefix().$table; return $this->connection->getPostProcessor()->processForeignKeys( $this->connection->selectFromWriteConnection($this->grammar->compileForeignKeys($table)) ); } /** * Modify a table on the schema. * * @param string $table * @param \Closure $callback * @return void */ public function table($table, Closure $callback) { $this->build($this->createBlueprint($table, $callback)); } /** * Create a new table on the schema. * * @param string $table * @param \Closure $callback * @return void */ public function create($table, Closure $callback) { $this->build(tap($this->createBlueprint($table), function ($blueprint) use ($callback) { $blueprint->create(); $callback($blueprint); })); } /** * Drop a table from the schema. * * @param string $table * @return void */ public function drop($table) { $this->build(tap($this->createBlueprint($table), function ($blueprint) { $blueprint->drop(); })); } /** * Drop a table from the schema if it exists. * * @param string $table * @return void */ public function dropIfExists($table) { $this->build(tap($this->createBlueprint($table), function ($blueprint) { $blueprint->dropIfExists(); })); } /** * Drop columns from a table schema. * * @param string $table * @param string|array $columns * @return void */ public function dropColumns($table, $columns) { $this->table($table, function (Blueprint $blueprint) use ($columns) { $blueprint->dropColumn($columns); }); } /** * Drop all tables from the database. * * @return void * * @throws \LogicException */ public function dropAllTables() { throw new LogicException('This database driver does not support dropping all tables.'); } /** * Drop all views from the database. * * @return void * * @throws \LogicException */ public function dropAllViews() { throw new LogicException('This database driver does not support dropping all views.'); } /** * Drop all types from the database. * * @return void * * @throws \LogicException */ public function dropAllTypes() { throw new LogicException('This database driver does not support dropping all types.'); } /** * Rename a table on the schema. * * @param string $from * @param string $to * @return void */ public function rename($from, $to) { $this->build(tap($this->createBlueprint($from), function ($blueprint) use ($to) { $blueprint->rename($to); })); } /** * Enable foreign key constraints. * * @return bool */ public function enableForeignKeyConstraints() { return $this->connection->statement( $this->grammar->compileEnableForeignKeyConstraints() ); } /** * Disable foreign key constraints. * * @return bool */ public function disableForeignKeyConstraints() { return $this->connection->statement( $this->grammar->compileDisableForeignKeyConstraints() ); } /** * Disable foreign key constraints during the execution of a callback. * * @param \Closure $callback * @return mixed */ public function withoutForeignKeyConstraints(Closure $callback) { $this->disableForeignKeyConstraints(); try { return $callback(); } finally { $this->enableForeignKeyConstraints(); } } /** * Execute the blueprint to build / modify the table. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @return void */ protected function build(Blueprint $blueprint) { $blueprint->build($this->connection, $this->grammar); } /** * Create a new command set with a Closure. * * @param string $table * @param \Closure|null $callback * @return \Illuminate\Database\Schema\Blueprint */ protected function createBlueprint($table, ?Closure $callback = null) { $prefix = $this->connection->getConfig('prefix_indexes') ? $this->connection->getConfig('prefix') : ''; if (isset($this->resolver)) { return call_user_func($this->resolver, $table, $callback, $prefix); } return Container::getInstance()->make(Blueprint::class, compact('table', 'callback', 'prefix')); } /** * Get the database connection instance. * * @return \Illuminate\Database\Connection */ public function getConnection() { return $this->connection; } /** * Set the database connection instance. * * @param \Illuminate\Database\Connection $connection * @return $this */ public function setConnection(Connection $connection) { $this->connection = $connection; return $this; } /** * Set the Schema Blueprint resolver callback. * * @param \Closure $resolver * @return void */ public function blueprintResolver(Closure $resolver) { $this->resolver = $resolver; } }