123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- <?php
- namespace Illuminate\Tests\Database;
- use BadMethodCallException;
- use Illuminate\Container\Container;
- use Illuminate\Database\Capsule\Manager as DB;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Database\Schema\Grammars\MySqlGrammar;
- use Illuminate\Database\Schema\Grammars\PostgresGrammar;
- use Illuminate\Database\Schema\Grammars\SQLiteGrammar;
- use Illuminate\Database\Schema\Grammars\SqlServerGrammar;
- use Illuminate\Support\Facades\Facade;
- use PHPUnit\Framework\TestCase;
- class DatabaseSchemaBlueprintIntegrationTest extends TestCase
- {
- protected $db;
- /**
- * Bootstrap Eloquent.
- *
- * @return void
- */
- protected function setUp(): void
- {
- $this->db = $db = new DB;
- $db->addConnection([
- 'driver' => 'sqlite',
- 'database' => ':memory:',
- ]);
- $db->setAsGlobal();
- $container = new Container;
- $container->instance('db', $db->getDatabaseManager());
- Facade::setFacadeApplication($container);
- }
- protected function tearDown(): void
- {
- Facade::clearResolvedInstances();
- Facade::setFacadeApplication(null);
- }
- public function testRenamingAndChangingColumnsWork()
- {
- $this->db->connection()->getSchemaBuilder()->create('users', function ($table) {
- $table->string('name');
- $table->string('age');
- });
- $blueprint = new Blueprint('users', function ($table) {
- $table->renameColumn('name', 'first_name');
- $table->integer('age')->change();
- });
- $queries = $blueprint->toSql($this->db->connection(), new SQLiteGrammar);
- // Expect one of the following two query sequences to be present...
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name, age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) NOT NULL COLLATE BINARY, age INTEGER NOT NULL)',
- 'INSERT INTO users (name, age) SELECT name, age FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name, age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (age VARCHAR(255) NOT NULL COLLATE BINARY, first_name VARCHAR(255) NOT NULL)',
- 'INSERT INTO users (first_name, age) SELECT name, age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name, age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) NOT NULL COLLATE BINARY, age INTEGER NOT NULL)',
- 'INSERT INTO users (name, age) SELECT name, age FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name, age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (first_name VARCHAR(255) NOT NULL, age VARCHAR(255) NOT NULL COLLATE BINARY)',
- 'INSERT INTO users (first_name, age) SELECT name, age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name, age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) NOT NULL COLLATE "BINARY", age INTEGER NOT NULL)',
- 'INSERT INTO users (name, age) SELECT name, age FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name, age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (first_name VARCHAR(255) NOT NULL, age VARCHAR(255) NOT NULL COLLATE "BINARY")',
- 'INSERT INTO users (first_name, age) SELECT name, age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- ];
- $this->assertTrue(in_array($queries, $expected));
- }
- public function testChangingColumnWithCollationWorks()
- {
- $this->db->connection()->getSchemaBuilder()->create('users', function ($table) {
- $table->string('age');
- });
- $blueprint = new Blueprint('users', function ($table) {
- $table->integer('age')->collation('RTRIM')->change();
- });
- $blueprint2 = new Blueprint('users', function ($table) {
- $table->integer('age')->collation('NOCASE')->change();
- });
- $queries = $blueprint->toSql($this->db->connection(), new SQLiteGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (age INTEGER NOT NULL COLLATE RTRIM)',
- 'INSERT INTO users (age) SELECT age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (age INTEGER NOT NULL COLLATE "RTRIM")',
- 'INSERT INTO users (age) SELECT age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- ];
- $this->assertContains($queries, $expected);
- $queries = $blueprint2->toSql($this->db->connection(), new SQLiteGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (age INTEGER NOT NULL COLLATE NOCASE)',
- 'INSERT INTO users (age) SELECT age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT age FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (age INTEGER NOT NULL COLLATE "NOCASE")',
- 'INSERT INTO users (age) SELECT age FROM __temp__users',
- 'DROP TABLE __temp__users',
- ],
- ];
- $this->assertContains($queries, $expected);
- }
- public function testRenameIndexWorks()
- {
- $this->db->connection()->getSchemaBuilder()->create('users', function ($table) {
- $table->string('name');
- $table->string('age');
- });
- $this->db->connection()->getSchemaBuilder()->table('users', function ($table) {
- $table->index(['name'], 'index1');
- });
- $blueprint = new Blueprint('users', function ($table) {
- $table->renameIndex('index1', 'index2');
- });
- $queries = $blueprint->toSql($this->db->connection(), new SQLiteGrammar);
- $expected = [
- 'DROP INDEX index1',
- 'CREATE INDEX index2 ON users (name)',
- ];
- $this->assertEquals($expected, $queries);
- $queries = $blueprint->toSql($this->db->connection(), new SqlServerGrammar);
- $expected = [
- 'sp_rename N\'"users"."index1"\', "index2", N\'INDEX\'',
- ];
- $this->assertEquals($expected, $queries);
- $queries = $blueprint->toSql($this->db->connection(), new MySqlGrammar);
- $expected = [
- 'alter table `users` rename index `index1` to `index2`',
- ];
- $this->assertEquals($expected, $queries);
- $queries = $blueprint->toSql($this->db->connection(), new PostgresGrammar);
- $expected = [
- 'alter index "index1" rename to "index2"',
- ];
- $this->assertEquals($expected, $queries);
- }
- public function testAddUniqueIndexWithoutNameWorks()
- {
- $this->db->connection()->getSchemaBuilder()->create('users', function ($table) {
- $table->string('name')->nullable();
- });
- $blueprintMySql = new Blueprint('users', function ($table) {
- $table->string('name')->nullable()->unique()->change();
- });
- $queries = $blueprintMySql->toSql($this->db->connection(), new MySqlGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE BINARY)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table `users` add unique `users_name_unique`(`name`)',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE "BINARY")',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table `users` add unique `users_name_unique`(`name`)',
- ],
- ];
- $this->assertContains($queries, $expected);
- $blueprintPostgres = new Blueprint('users', function ($table) {
- $table->string('name')->nullable()->unique()->change();
- });
- $queries = $blueprintPostgres->toSql($this->db->connection(), new PostgresGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE BINARY)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table "users" add constraint "users_name_unique" unique ("name")',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE "BINARY")',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table "users" add constraint "users_name_unique" unique ("name")',
- ],
- ];
- $this->assertContains($queries, $expected);
- $blueprintSQLite = new Blueprint('users', function ($table) {
- $table->string('name')->nullable()->unique()->change();
- });
- $queries = $blueprintSQLite->toSql($this->db->connection(), new SQLiteGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE BINARY)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'create unique index "users_name_unique" on "users" ("name")',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE "BINARY")',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'create unique index "users_name_unique" on "users" ("name")',
- ],
- ];
- $this->assertContains($queries, $expected);
- $blueprintSqlServer = new Blueprint('users', function ($table) {
- $table->string('name')->nullable()->unique()->change();
- });
- $queries = $blueprintSqlServer->toSql($this->db->connection(), new SqlServerGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE BINARY)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'create unique index "users_name_unique" on "users" ("name")',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE "BINARY")',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'create unique index "users_name_unique" on "users" ("name")',
- ],
- ];
- $this->assertContains($queries, $expected);
- }
- public function testAddUniqueIndexWithNameWorks()
- {
- $this->db->connection()->getSchemaBuilder()->create('users', function ($table) {
- $table->string('name')->nullable();
- });
- $blueprintMySql = new Blueprint('users', function ($table) {
- $table->string('name')->nullable()->unique('index1')->change();
- });
- $queries = $blueprintMySql->toSql($this->db->connection(), new MySqlGrammar);
- $expected = [
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE BINARY)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table `users` add unique `index1`(`name`)',
- ],
- [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name VARCHAR(255) DEFAULT NULL COLLATE "BINARY")',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table `users` add unique `index1`(`name`)',
- ],
- ];
- $this->assertContains($queries, $expected);
- $blueprintPostgres = new Blueprint('users', function ($table) {
- $table->unsignedInteger('name')->nullable()->unique('index1')->change();
- });
- $queries = $blueprintPostgres->toSql($this->db->connection(), new PostgresGrammar);
- $expected = [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name INTEGER UNSIGNED DEFAULT NULL)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'alter table "users" add constraint "index1" unique ("name")',
- ];
- $this->assertEquals($expected, $queries);
- $blueprintSQLite = new Blueprint('users', function ($table) {
- $table->unsignedInteger('name')->nullable()->unique('index1')->change();
- });
- $queries = $blueprintSQLite->toSql($this->db->connection(), new SQLiteGrammar);
- $expected = [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name INTEGER UNSIGNED DEFAULT NULL)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'create unique index "index1" on "users" ("name")',
- ];
- $this->assertEquals($expected, $queries);
- $blueprintSqlServer = new Blueprint('users', function ($table) {
- $table->unsignedInteger('name')->nullable()->unique('index1')->change();
- });
- $queries = $blueprintSqlServer->toSql($this->db->connection(), new SqlServerGrammar);
- $expected = [
- 'CREATE TEMPORARY TABLE __temp__users AS SELECT name FROM users',
- 'DROP TABLE users',
- 'CREATE TABLE users (name INTEGER UNSIGNED DEFAULT NULL)',
- 'INSERT INTO users (name) SELECT name FROM __temp__users',
- 'DROP TABLE __temp__users',
- 'create unique index "index1" on "users" ("name")',
- ];
- $this->assertEquals($expected, $queries);
- }
- public function testItEnsuresDroppingMultipleColumnsIsAvailable()
- {
- $this->expectException(BadMethodCallException::class);
- $this->expectExceptionMessage("SQLite doesn't support multiple calls to dropColumn / renameColumn in a single modification.");
- $this->db->connection()->getSchemaBuilder()->table('users', function (Blueprint $table) {
- $table->dropColumn('name');
- $table->dropColumn('email');
- });
- }
- public function testItEnsuresRenamingMultipleColumnsIsAvailable()
- {
- $this->expectException(BadMethodCallException::class);
- $this->expectExceptionMessage("SQLite doesn't support multiple calls to dropColumn / renameColumn in a single modification.");
- $this->db->connection()->getSchemaBuilder()->table('users', function (Blueprint $table) {
- $table->renameColumn('name', 'first_name');
- $table->renameColumn('name2', 'last_name');
- });
- }
- public function testItEnsuresRenamingAndDroppingMultipleColumnsIsAvailable()
- {
- $this->expectException(BadMethodCallException::class);
- $this->expectExceptionMessage("SQLite doesn't support multiple calls to dropColumn / renameColumn in a single modification.");
- $this->db->connection()->getSchemaBuilder()->table('users', function (Blueprint $table) {
- $table->dropColumn('name');
- $table->renameColumn('name2', 'last_name');
- });
- }
- public function testItEnsuresDroppingForeignKeyIsAvailable()
- {
- $this->expectException(BadMethodCallException::class);
- $this->expectExceptionMessage("SQLite doesn't support dropping foreign keys (you would need to re-create the table).");
- $this->db->connection()->getSchemaBuilder()->table('users', function (Blueprint $table) {
- $table->dropForeign('something');
- });
- }
- }
|