From 51146b81e3cc0dd2c36c59093498803bf9a8acbc Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Wed, 3 Apr 2024 22:10:46 +0800 Subject: [PATCH 001/111] Laravel 10 changes Co-authored-by: Luke Towers --- .github/workflows/tests.yml | 2 +- composer.json | 12 ++-- src/Cache/CacheManager.php | 19 ++++++ src/Console/Traits/HandlesCleanup.php | 6 +- src/Database/Concerns/HasAttributes.php | 34 ++++++++++ src/Database/Model.php | 1 + .../Relations/Concerns/DeferOneOrMany.php | 9 ++- src/Flash/FlashBag.php | 7 +- src/Foundation/Application.php | 7 +- src/Foundation/Http/Kernel.php | 2 +- src/Halcyon/Builder.php | 5 +- src/Halcyon/Model.php | 6 +- src/Support/Facades/DB.php | 2 +- src/Support/Facades/Mail.php | 2 +- src/Translation/FileLoader.php | 67 ++++++++++--------- tests/Database/ModelTest.php | 2 +- tests/Database/UpdaterTest.php | 2 +- tests/Foundation/ApplicationTest.php | 2 +- tests/Html/BlockBuilderTest.php | 2 +- tests/Support/EventFakeTest.php | 2 +- tests/Support/MailFakeTest.php | 9 ++- tests/Translation/FileLoaderTest.php | 1 + 22 files changed, 137 insertions(+), 64 deletions(-) create mode 100644 src/Cache/CacheManager.php create mode 100644 src/Database/Concerns/HasAttributes.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fb3073e65..c6c5c7cd1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,7 +18,7 @@ jobs: max-parallel: 6 matrix: operatingSystem: [ubuntu-latest, windows-latest] - phpVersion: ['8.0', '8.1', '8.2'] + phpVersion: ['8.1', '8.2'] fail-fast: false runs-on: ${{ matrix.operatingSystem }} name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }} diff --git a/composer.json b/composer.json index dca52f738..d0e7e8913 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": "^8.0.2", + "php": "^8.1", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -36,15 +36,15 @@ "ext-zip": "*", "assetic/framework": "~3.0", - "doctrine/dbal": "^2.6", + "doctrine/dbal": "^3.0", "enshrined/svg-sanitize": "~0.16", - "laravel/framework": "^9.1", - "laravel/tinker": "^2.7", + "laravel/framework": "^10.0", + "laravel/tinker": "^2.8.1", "league/csv": "~9.1", "nesbot/carbon": "^2.0", "nikic/php-parser": "^4.10", "scssphp/scssphp": "~1.0", - "symfony/console": ">=6.0.9 <6.3.0", + "symfony/console": "^6.3", "symfony/yaml": "^6.0", "twig/twig": "~3.0", "wikimedia/less.php": "~3.0", @@ -59,7 +59,7 @@ "meyfa/phpunit-assert-gd": "^2.0.0|^3.0.0", "dms/phpunit-arraysubset-asserts": "^0.1.0|^0.2.1", "larastan/larastan": "^2.8.1", - "orchestra/testbench": "^7.1.0" + "orchestra/testbench": "^8.0.0" }, "suggest": { "ext-pdo_dblib": "Required to use MS SQL Server databases", diff --git a/src/Cache/CacheManager.php b/src/Cache/CacheManager.php new file mode 100644 index 000000000..6d0375d71 --- /dev/null +++ b/src/Cache/CacheManager.php @@ -0,0 +1,19 @@ + 'datetime', + * ]; + * ``` + * + * @return array + */ + public function getDates() + { + if (! $this->usesTimestamps()) { + return $this->dates; + } + + $defaults = [ + $this->getCreatedAtColumn(), + $this->getUpdatedAtColumn(), + ]; + + return array_unique(array_merge($this->dates, $defaults)); + } +} diff --git a/src/Database/Model.php b/src/Database/Model.php index 403905965..57ae23c65 100644 --- a/src/Database/Model.php +++ b/src/Database/Model.php @@ -22,6 +22,7 @@ */ class Model extends EloquentModel implements ModelInterface { + use Concerns\HasAttributes; use Concerns\GuardsAttributes; use Concerns\HasRelationships; use Concerns\HidesAttributes; diff --git a/src/Database/Relations/Concerns/DeferOneOrMany.php b/src/Database/Relations/Concerns/DeferOneOrMany.php index 519c9d8ba..4db33a2e8 100644 --- a/src/Database/Relations/Concerns/DeferOneOrMany.php +++ b/src/Database/Relations/Concerns/DeferOneOrMany.php @@ -94,8 +94,8 @@ public function withDeferred($sessionKey) ->where('master_type', get_class($this->parent)) ->where('session_key', $sessionKey) ->where('is_bind', 0) - ->whereRaw(DbDongle::parse('id > ifnull((select max(id) from '.DbDongle::getTablePrefix().'deferred_bindings where - slave_id = '.$this->getWithDeferredQualifiedKeyName().' and + ->whereRaw(DbDongle::parse('id > ifnull((select max(id) from ' . DbDongle::getTablePrefix() . 'deferred_bindings where + slave_id = ' . $this->getWithDeferredQualifiedKeyName() . ' and master_field = ? and master_type = ? and session_key = ? and @@ -122,13 +122,12 @@ public function withDeferred($sessionKey) /** * Returns the related "slave id" key in a database friendly format. - * @return \Illuminate\Database\Query\Expression */ - protected function getWithDeferredQualifiedKeyName() + protected function getWithDeferredQualifiedKeyName(): string { return $this->parent->getConnection()->raw(DbDongle::cast( DbDongle::getTablePrefix() . $this->related->getQualifiedKeyName(), 'TEXT' - )); + ))->getValue($this->parent->getGrammar()); } } diff --git a/src/Flash/FlashBag.php b/src/Flash/FlashBag.php index 61abb1f39..bdcacfb6d 100644 --- a/src/Flash/FlashBag.php +++ b/src/Flash/FlashBag.php @@ -166,15 +166,16 @@ public function store() /** * Removes an object with a specified key or erases the flash data. + * * @param string $key Specifies a key to remove, optional + * @return $this */ public function forget($key = null) { if ($key === null) { $this->newMessages = $this->messages = []; $this->purge(); - } - else { + } else { if (isset($this->messages[$key])) { unset($this->messages[$key]); } @@ -185,6 +186,8 @@ public function forget($key = null) $this->store(); } + + return $this; } /* diff --git a/src/Foundation/Application.php b/src/Foundation/Application.php index 2bccf1e5f..ef8b633bf 100644 --- a/src/Foundation/Application.php +++ b/src/Foundation/Application.php @@ -68,11 +68,12 @@ public function version() /** * Get the path to the public / web directory. * + * @param string $path * @return string */ - public function publicPath() + public function publicPath($path = '') { - return $this->basePath; + return $this->joinPaths($this->basePath, $path); } /** @@ -479,7 +480,7 @@ public function registerCoreContainerAliases() $aliases = [ 'app' => [\Winter\Storm\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class], 'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class], - 'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class], + 'cache' => [\Winter\Storm\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class], 'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class], 'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class], 'cookie' => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class], diff --git a/src/Foundation/Http/Kernel.php b/src/Foundation/Http/Kernel.php index 1c4218cfc..e314e8a9b 100644 --- a/src/Foundation/Http/Kernel.php +++ b/src/Foundation/Http/Kernel.php @@ -31,7 +31,7 @@ class Kernel extends HttpKernel /** * {@inheritDoc} */ - protected $routeMiddleware = [ + protected $middlewareAliases = [ // 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, // 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, diff --git a/src/Halcyon/Builder.php b/src/Halcyon/Builder.php index 2abd7f19a..2df827548 100644 --- a/src/Halcyon/Builder.php +++ b/src/Halcyon/Builder.php @@ -699,12 +699,11 @@ protected function isCacheBusted($result) /** * Get the cache object with tags assigned, if applicable. * - * @return \Illuminate\Contracts\Cache\Repository + * @return \Illuminate\Cache\Repository */ protected function getCache() { - /** @var \Illuminate\Cache\Repository */ - $cache = $this->model->getCacheManager()->driver($this->cacheDriver); + $cache = $this->model->getCacheManager()->store($this->cacheDriver); return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache; } diff --git a/src/Halcyon/Model.php b/src/Halcyon/Model.php index f51c3ac47..1458906ae 100644 --- a/src/Halcyon/Model.php +++ b/src/Halcyon/Model.php @@ -109,7 +109,7 @@ class Model extends Extendable implements ModelInterface, ArrayAccess, Arrayable /** * The cache manager instance. * - * @var \Illuminate\Cache\CacheManager|null + * @var \Winter\Storm\Cache\CacheManager|null */ protected static $cache; @@ -1512,7 +1512,7 @@ public static function unsetEventDispatcher() /** * Get the cache manager instance. * - * @return \Illuminate\Cache\CacheManager|null + * @return \Winter\Storm\Cache\CacheManager|null */ public static function getCacheManager() { @@ -1522,7 +1522,7 @@ public static function getCacheManager() /** * Set the cache manager instance. * - * @param \Illuminate\Cache\CacheManager $cache + * @param \Winter\Storm\Cache\CacheManager $cache * @return void */ public static function setCacheManager($cache) diff --git a/src/Support/Facades/DB.php b/src/Support/Facades/DB.php index d2c0bb8bf..15bbc8c51 100644 --- a/src/Support/Facades/DB.php +++ b/src/Support/Facades/DB.php @@ -5,7 +5,7 @@ /** * @method static \Doctrine\DBAL\Driver\PDOConnection getPdo() * @method static \Illuminate\Database\Connection connection(string $name = null) - * @method static \Winter\Storm\Database\QueryBuilder table(string $table, string $as = null) + * @method static \Winter\Storm\Database\QueryBuilder table(\Closure|\Illuminate\Database\Query\Builder|\Illuminate\Contracts\Database\Query\Expression|string $table, string|null $as = null) * @method static \Illuminate\Database\Query\Expression raw($value) * @method static array getQueryLog() * @method static array prepareBindings(array $bindings) diff --git a/src/Support/Facades/Mail.php b/src/Support/Facades/Mail.php index 047147133..8a394e07d 100755 --- a/src/Support/Facades/Mail.php +++ b/src/Support/Facades/Mail.php @@ -34,7 +34,7 @@ class Mail extends Facade */ public static function fake() { - static::swap($fake = new MailFake); + static::swap($fake = new MailFake(static::getFacadeRoot())); return $fake; } diff --git a/src/Translation/FileLoader.php b/src/Translation/FileLoader.php index 86e65954d..3dba1cc13 100644 --- a/src/Translation/FileLoader.php +++ b/src/Translation/FileLoader.php @@ -18,26 +18,31 @@ class FileLoader extends FileLoaderBase */ protected function loadNamespaceOverrides(array $lines, $locale, $group, $namespace) { - $namespace = str_replace('.', '/', $namespace); + return collect($this->paths) + ->reduce(function ($output, $path) use ($lines, $locale, $group, $namespace) { + $winterNamespace = str_replace('.', '/', $namespace); - $file = "{$this->path}/{$locale}/{$namespace}/{$group}.php"; + // Look for a Winter-managed namespace + $file = "{$path}/{$locale}/{$winterNamespace}/{$group}.php"; + if ($this->files->exists($file)) { + return array_replace_recursive($lines, $this->files->getRequire($file)); + } - if ($this->files->exists($file)) { - return array_replace_recursive($lines, $this->files->getRequire($file)); - } + // Look for a Winter-managed namespace with a Winter-formatted locale (xx-xx instead of xx_XX) + $dashLocale = str_replace('_', '-', strtolower($locale)); + $dashFile = "{$path}/{$dashLocale}/{$winterNamespace}/{$group}.php"; + if ($dashFile !== $file && $this->files->exists($dashFile)) { + return array_replace_recursive($lines, $this->files->getRequire($dashFile)); + } - // Try "xx-xx" format - $locale = str_replace('_', '-', strtolower($locale)); + // Look for a vendor-managed namespace + $file = "{$path}/vendor/{$namespace}/{$locale}/{$group}.php"; + if ($this->files->exists($file)) { + return array_replace_recursive($lines, $this->files->getRequire($file)); + } - if ("{$this->path}/{$locale}/{$namespace}/{$group}.php" !== $file) { - $file = "{$this->path}/{$locale}/{$namespace}/{$group}.php"; - - if ($this->files->exists($file)) { - return array_replace_recursive($lines, $this->files->getRequire($file)); - } - } - - return $lines; + return $lines; + }, []); } /** @@ -46,26 +51,28 @@ protected function loadNamespaceOverrides(array $lines, $locale, $group, $namesp * This is an override from the base Laravel functionality that allows "xx-xx" locale format * files as well as "xx_XX" locale format files. The "xx_XX" format is considered authorative. * - * @param string $path + * @param array $paths * @param string $locale * @param string $group * @return array */ - protected function loadPath($path, $locale, $group) + protected function loadPaths(array $paths, $locale, $group) { - if ($this->files->exists($full = "{$path}/{$locale}/{$group}.php")) { - return $this->files->getRequire($full); - } - - // Try "xx-xx" format - $locale = str_replace('_', '-', strtolower($locale)); + return collect($paths) + ->reduce(function ($output, $path) use ($locale, $group) { + $file = "{$path}/{$locale}/{$group}.php"; + if ($this->files->exists($file)) { + return array_replace_recursive($output, $this->files->getRequire($file)); + } - if ("{$path}/{$locale}/{$group}.php" !== $full) { - if ($this->files->exists($full = "{$path}/{$locale}/{$group}.php")) { - return $this->files->getRequire($full); - } - } + // Try "xx-xx" format + $dashLocale = str_replace('_', '-', strtolower($locale)); + $dashFile = "{$path}/{$dashLocale}/{$group}.php"; + if ($dashFile !== $file && $this->files->exists($dashFile)) { + return $this->files->getRequire($dashFile); + } - return []; + return $output; + }, []); } } diff --git a/tests/Database/ModelTest.php b/tests/Database/ModelTest.php index 276384ed8..93c6d61d5 100644 --- a/tests/Database/ModelTest.php +++ b/tests/Database/ModelTest.php @@ -471,7 +471,7 @@ public function testAddCasts() public function testStringIsTrimmed() { $name = "Name"; - $nameWithSpace = " ${name} "; + $nameWithSpace = " {$name} "; $model = new TestModelGuarded(); $model->name = $nameWithSpace; diff --git a/tests/Database/UpdaterTest.php b/tests/Database/UpdaterTest.php index ef60d4573..eb94125e1 100644 --- a/tests/Database/UpdaterTest.php +++ b/tests/Database/UpdaterTest.php @@ -4,7 +4,7 @@ class UpdaterTest extends TestCase { - protected Updater $updater; + protected ?Updater $updater = null; public function setUp(): void { diff --git a/tests/Foundation/ApplicationTest.php b/tests/Foundation/ApplicationTest.php index f138de05a..7f5127e6b 100644 --- a/tests/Foundation/ApplicationTest.php +++ b/tests/Foundation/ApplicationTest.php @@ -5,7 +5,7 @@ class ApplicationTest extends TestCase { - protected string $basePath; + protected string $basePath = ''; protected function setUp(): void { diff --git a/tests/Html/BlockBuilderTest.php b/tests/Html/BlockBuilderTest.php index a2e1fc6ab..c39f5df92 100644 --- a/tests/Html/BlockBuilderTest.php +++ b/tests/Html/BlockBuilderTest.php @@ -4,7 +4,7 @@ class BlockBuilderTest extends TestCase { - protected BlockBuilder $Block; + protected ?BlockBuilder $Block = null; public function setUp(): void { diff --git a/tests/Support/EventFakeTest.php b/tests/Support/EventFakeTest.php index 5e74b6805..403551fdb 100644 --- a/tests/Support/EventFakeTest.php +++ b/tests/Support/EventFakeTest.php @@ -5,7 +5,7 @@ class EventFakeTest extends TestCase { - protected EventFake $faker; + protected ?EventFake $faker = null; public function setUp(): void { diff --git a/tests/Support/MailFakeTest.php b/tests/Support/MailFakeTest.php index 144a1452c..b777d2e83 100644 --- a/tests/Support/MailFakeTest.php +++ b/tests/Support/MailFakeTest.php @@ -1,17 +1,24 @@ andReturn('en/US'); - Mail::swap(new MailFake()); + $this->manager = m::mock(MailManager::class); + Mail::swap(new MailFake($this->manager)); $this->recipient = 'fake@localhost'; $this->subject = 'MailFake test'; diff --git a/tests/Translation/FileLoaderTest.php b/tests/Translation/FileLoaderTest.php index 6b9fa3491..0f1848db5 100644 --- a/tests/Translation/FileLoaderTest.php +++ b/tests/Translation/FileLoaderTest.php @@ -31,6 +31,7 @@ public function testLoadMethodWithNamespacesProperlyCallsLoader() $loader = new FileLoader($files = m::mock(Filesystem::class), __DIR__); $files->shouldReceive('exists')->once()->with('bar/en/foo.php')->andReturn(true); $files->shouldReceive('exists')->once()->with(__DIR__.'/en/namespace/foo.php')->andReturn(false); + $files->shouldReceive('exists')->once()->with(__DIR__.'/vendor/namespace/en/foo.php')->andReturn(false); $files->shouldReceive('getRequire')->once()->with('bar/en/foo.php')->andReturn(['foo' => 'bar']); $loader->addNamespace('namespace', 'bar'); From 0a6b24e1fd0d14454ec899b93a31536ac02e9cb6 Mon Sep 17 00:00:00 2001 From: wverhoogt Date: Wed, 3 Apr 2024 16:32:12 +0200 Subject: [PATCH 002/111] Laravel 10 changes Co-authored-by: Wim Verhoogt Co-authored-by: Ben Thomson --- .github/workflows/code-analysis.yaml | 15 ++++++++ .github/workflows/code-quality.yaml | 2 -- .github/workflows/tests.yml | 4 +-- .gitignore | 1 + composer.json | 8 ++--- src/Auth/Models/Throttle.php | 9 +++-- src/Database/Concerns/HasRelationships.php | 17 ++++++--- src/Database/Model.php | 1 - src/Database/QueryBuilder.php | 2 +- .../Relations/Concerns/DeferOneOrMany.php | 3 +- src/Database/Relations/MorphToMany.php | 14 ++++---- src/Database/Traits/Revisionable.php | 3 +- src/Foundation/Application.php | 2 +- .../Middleware/CheckForMaintenanceMode.php | 35 +++++++++---------- src/Support/Facades/Flash.php | 2 +- src/Support/Facades/Mail.php | 6 ++-- 16 files changed, 76 insertions(+), 48 deletions(-) diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml index 9a4c87c4e..0cfd2511d 100644 --- a/.github/workflows/code-analysis.yaml +++ b/.github/workflows/code-analysis.yaml @@ -23,6 +23,21 @@ jobs: - name: Checkout changes uses: actions/checkout@v4 + - name: Setup extension cache + id: extcache + uses: shivammathur/cache-extensions@v1 + with: + php-version: '8.2' + extensions: ${{ env.extensions }} + key: ${{ env.key }} + + - name: Cache extensions + uses: actions/cache@v2 + with: + path: ${{ steps.extcache.outputs.dir }} + key: ${{ steps.extcache.outputs.key }} + restore-keys: ${{ steps.extcache.outputs.key }} + - name: Install PHP uses: shivammathur/setup-php@v2 with: diff --git a/.github/workflows/code-quality.yaml b/.github/workflows/code-quality.yaml index 065447d76..840f47e5f 100644 --- a/.github/workflows/code-quality.yaml +++ b/.github/workflows/code-quality.yaml @@ -4,8 +4,6 @@ on: pull_request: push: branches: - - 1.0 - - 1.1 - develop concurrency: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c6c5c7cd1..0625b7c3f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,8 +3,6 @@ name: Tests on: push: branches: - - "1.0" - - "1.1" - develop pull_request: @@ -15,7 +13,7 @@ concurrency: jobs: unitTests: strategy: - max-parallel: 6 + max-parallel: 4 matrix: operatingSystem: [ubuntu-latest, windows-latest] phpVersion: ['8.1', '8.2'] diff --git a/.gitignore b/.gitignore index bdee57b0e..06c24a826 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ composer.lock # Editor files .idea .vscode +*.code-workspace # Other files .DS_Store diff --git a/composer.json b/composer.json index d0e7e8913..7c0260ada 100644 --- a/composer.json +++ b/composer.json @@ -36,9 +36,9 @@ "ext-zip": "*", "assetic/framework": "~3.0", - "doctrine/dbal": "^3.0", + "doctrine/dbal": "^3.6", "enshrined/svg-sanitize": "~0.16", - "laravel/framework": "^10.0", + "laravel/framework": "^10.1", "laravel/tinker": "^2.8.1", "league/csv": "~9.1", "nesbot/carbon": "^2.0", @@ -58,8 +58,8 @@ "php-parallel-lint/php-parallel-lint": "^1.0", "meyfa/phpunit-assert-gd": "^2.0.0|^3.0.0", "dms/phpunit-arraysubset-asserts": "^0.1.0|^0.2.1", - "larastan/larastan": "^2.8.1", - "orchestra/testbench": "^8.0.0" + "nunomaduro/larastan": "2.x-dev", + "orchestra/testbench": "^8.4" }, "suggest": { "ext-pdo_dblib": "Required to use MS SQL Server databases", diff --git a/src/Auth/Models/Throttle.php b/src/Auth/Models/Throttle.php index a4cdbea58..ba03df86c 100644 --- a/src/Auth/Models/Throttle.php +++ b/src/Auth/Models/Throttle.php @@ -37,10 +37,13 @@ class Throttle extends Model /** * The attributes that should be mutated to dates. * - * @var array + * @var array */ - protected $dates = ['last_attempt_at', 'suspended_at', 'banned_at']; - + protected $casts = [ + 'suspended_at' => 'datetime', + 'last_attempt_at' => 'datetime', + 'banned_at' => 'datetime', + ]; /** * @var int Attempt limit. */ diff --git a/src/Database/Concerns/HasRelationships.php b/src/Database/Concerns/HasRelationships.php index 069c8e943..bdae519f7 100644 --- a/src/Database/Concerns/HasRelationships.php +++ b/src/Database/Concerns/HasRelationships.php @@ -340,7 +340,7 @@ protected function handleRelation($relationName) case 'morphToMany': $relation = $this->validateRelationArgs($relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps'], ['name']); - $relationObj = $this->$relationType($relation[0], $relation['name'], $relation['table'], $relation['key'], $relation['otherKey'], $relation['parentKey'], $relation['relatedKey'], false, $relationName); + $relationObj = $this->$relationType($relation[0], $relation['name'], $relation['table'], $relation['key'], $relation['otherKey'], $relation['parentKey'], $relation['relatedKey'], $relationName, false); if (isset($relation['pivotModel'])) { $relationObj->using($relation['pivotModel']); @@ -667,9 +667,18 @@ public function belongsToMany($related, $table = null, $primaryKey = null, $fore /** * Define a polymorphic many-to-many relationship. * This code is almost a duplicate of Eloquent but uses a Storm relation class. + * @param string $related + * @param string $name + * @param string|null $table + * @param string|null $primaryKey + * @param string|null $foreignKey + * @param string|null $parentKey + * @param string|null $relatedKey + * @param string|null $relationName + * @param bool $inverse * @return \Winter\Storm\Database\Relations\MorphToMany */ - public function morphToMany($related, $name, $table = null, $primaryKey = null, $foreignKey = null, $parentKey = null, $relatedKey = null, $inverse = false, $relationName = null) + public function morphToMany($related, $name, $table = null, $primaryKey = null, $foreignKey = null, $parentKey = null, $relatedKey = null, $relationName = null, $inverse = false) { if (is_null($relationName)) { $relationName = $this->getRelationCaller(); @@ -720,8 +729,8 @@ public function morphedByMany($related, $name, $table = null, $primaryKey = null $foreignKey, $parentKey, $relatedKey, - true, - $relationName + $relationName, + true ); } diff --git a/src/Database/Model.php b/src/Database/Model.php index 57ae23c65..5e3d9fcee 100644 --- a/src/Database/Model.php +++ b/src/Database/Model.php @@ -106,7 +106,6 @@ public function isDatabaseReady(): bool } // Resolver hasn't been set yet - /** @phpstan-ignore-next-line */ if (!static::getConnectionResolver()) { return false; } diff --git a/src/Database/QueryBuilder.php b/src/Database/QueryBuilder.php index 14289c59c..bad7d16f7 100644 --- a/src/Database/QueryBuilder.php +++ b/src/Database/QueryBuilder.php @@ -463,7 +463,7 @@ protected function runPaginationCountQuery($columns = ['*']) } return $this->newQuery() - ->from(new Expression('(' . $clone->toSql() . ') as ' . $this->grammar->wrap('aggregate_table'))) + ->from($clone, $this->grammar->wrap('aggregate_table')) ->mergeBindings($clone) ->setAggregate('count', $this->withoutSelectAliases($columns)) ->get() diff --git a/src/Database/Relations/Concerns/DeferOneOrMany.php b/src/Database/Relations/Concerns/DeferOneOrMany.php index 4db33a2e8..bfb8bb3a6 100644 --- a/src/Database/Relations/Concerns/DeferOneOrMany.php +++ b/src/Database/Relations/Concerns/DeferOneOrMany.php @@ -1,5 +1,6 @@ where('session_key', $sessionKey) ->where('is_bind', 0) ->whereRaw(DbDongle::parse('id > ifnull((select max(id) from ' . DbDongle::getTablePrefix() . 'deferred_bindings where - slave_id = ' . $this->getWithDeferredQualifiedKeyName() . ' and + slave_id = ' . $this->getWithDeferredQualifiedKeyName()->getValue(new Grammar) . ' and master_field = ? and master_type = ? and session_key = ? and diff --git a/src/Database/Relations/MorphToMany.php b/src/Database/Relations/MorphToMany.php index 2487139c4..58b20399d 100644 --- a/src/Database/Relations/MorphToMany.php +++ b/src/Database/Relations/MorphToMany.php @@ -27,8 +27,10 @@ class MorphToMany extends BaseMorphToMany * @param \Illuminate\Database\Eloquent\Model $parent * @param string $name * @param string $table - * @param string $foreignKey - * @param string $otherKey + * @param string $foreignPivotKey + * @param string $relatedPivotKey + * @param string $parentKey + * @param string $relatedKey * @param string $relationName * @param bool $inverse * @return void @@ -38,8 +40,8 @@ public function __construct( Model $parent, $name, $table, - $foreignKey, - $otherKey, + $foreignPivotKey, + $relatedPivotKey, $parentKey, $relatedKey, $relationName = null, @@ -50,8 +52,8 @@ public function __construct( $parent, $name, $table, - $foreignKey, - $otherKey, + $foreignPivotKey, + $relatedPivotKey, $parentKey, $relatedKey, $relationName, diff --git a/src/Database/Traits/Revisionable.php b/src/Database/Traits/Revisionable.php index 9dcdc459f..4e2b5763a 100644 --- a/src/Database/Traits/Revisionable.php +++ b/src/Database/Traits/Revisionable.php @@ -157,7 +157,8 @@ protected function revisionableCleanUp() protected function revisionableGetCastType($attribute) { - if (in_array($attribute, $this->getDates())) { + // dates property deprecated in Laravel 10, no longer used in getDates() + if (in_array($attribute, $this->getDates()) || $this->isDateCastable($attribute) || in_array($attribute, $this->dates)) { return 'date'; } diff --git a/src/Foundation/Application.php b/src/Foundation/Application.php index ef8b633bf..6f5943454 100644 --- a/src/Foundation/Application.php +++ b/src/Foundation/Application.php @@ -428,7 +428,7 @@ public function registerConfiguredProviders($isRetry = false) }); if (Config::get('app.loadDiscoveredPackages', false)) { - $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]); + $providers->splice(1, 0, $this->make(PackageManifest::class)->providers()); } $filesystem = new Filesystem; diff --git a/src/Foundation/Http/Middleware/CheckForMaintenanceMode.php b/src/Foundation/Http/Middleware/CheckForMaintenanceMode.php index 6a82797bf..76a452b3e 100644 --- a/src/Foundation/Http/Middleware/CheckForMaintenanceMode.php +++ b/src/Foundation/Http/Middleware/CheckForMaintenanceMode.php @@ -23,26 +23,25 @@ public function handle($request, Closure $next) { try { return parent::handle($request, $next); - } catch (\Illuminate\Foundation\Http\Exceptions\MaintenanceModeException $ex) { - // Smoothly handle AJAX requests - if (request()->ajax()) { - return Response::make(Lang::get('system::lang.page.maintenance.help') . "\r\n" . $ex->getMessage(), 503); - } + } catch (\Symfony\Component\HttpKernel\Exception\HttpException $ex) { + if ($ex->getStatusCode() === 503) { + // Smoothly handle AJAX requests + if (request()->ajax()) { + return Response::make(Lang::get('system::lang.page.maintenance.help') . "\r\n" . $ex->getMessage(), 503); + } - // Check if there is a project level view to override the system one - View::addNamespace('base', base_path()); - if (View::exists('base::maintenance')) { - $view = 'base::maintenance'; - } else { - $view = 'system::maintenance'; - } + // Check if there is a project level view to override the system one + View::addNamespace('base', base_path()); + if (View::exists('base::maintenance')) { + $view = 'base::maintenance'; + } else { + $view = 'system::maintenance'; + } - return Response::make(View::make($view, [ - 'message' => $ex->getMessage(), - 'wentDownAt' => $ex->wentDownAt, - 'retryAfter' => $ex->retryAfter, - 'willBeAvailableAt' => $ex->willBeAvailableAt, - ]), 503); + return Response::make(View::make($view, [ + 'message' => $ex->getMessage() + ]), 503); + } } } } diff --git a/src/Support/Facades/Flash.php b/src/Support/Facades/Flash.php index 7e1e1b305..b5df487f7 100644 --- a/src/Support/Facades/Flash.php +++ b/src/Support/Facades/Flash.php @@ -12,7 +12,7 @@ * @method static array|\Winter\Storm\Flash\FlashBag info(string $message = null) * @method static \Winter\Storm\Flash\FlashBag add(string $key, string $message) * @method static void store() - * @method static void forget(string $key = null) + * @method static \Winter\Storm\Flash\FlashBag forget(string $key = null) * @method static void purge(); * * @see \Winter\Storm\Flash\FlashBag diff --git a/src/Support/Facades/Mail.php b/src/Support/Facades/Mail.php index 8a394e07d..f9e04c4ba 100755 --- a/src/Support/Facades/Mail.php +++ b/src/Support/Facades/Mail.php @@ -1,5 +1,6 @@ Date: Wed, 3 Apr 2024 10:38:21 -0400 Subject: [PATCH 003/111] apply latest changes done by @bennothommo to fix code analysis --- .github/workflows/code-analysis.yaml | 11 ----------- .github/workflows/tests.yml | 11 ----------- phpstan.neon | 2 ++ 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml index 0cfd2511d..0432f6f6b 100644 --- a/.github/workflows/code-analysis.yaml +++ b/.github/workflows/code-analysis.yaml @@ -45,17 +45,6 @@ jobs: extensions: ${{ env.extensions }} coverage: none - - name: Setup dependency cache - id: composercache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composercache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install Composer dependencies run: composer install --no-interaction --no-progress --no-scripts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0625b7c3f..87d2e7a28 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,17 +34,6 @@ jobs: extensions: ${{ env.extensions }} coverage: none - - name: Setup dependency cache - id: composercache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composercache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install Composer dependencies run: composer install --no-interaction --no-progress --no-scripts diff --git a/phpstan.neon b/phpstan.neon index 54338d865..a7a8abc05 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,6 +10,8 @@ parameters: # Exclude PHP Parser files - src/Parse/PHP/ArrayFile.php - src/Parse/PHP/ArrayPrinter.php + - src/Foundation/Console/KeyGenerateCommand.php + disableSchemaScan: true databaseMigrationsPath: - src/Auth/Migrations - src/Database/Migrations From 416c6b31a545a724923261270d74f14bb8dbd6b3 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 10:47:36 -0400 Subject: [PATCH 004/111] restore initial larastan package --- composer.json | 2 +- src/Cache/CacheManager.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 7c0260ada..6e80c5145 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "php-parallel-lint/php-parallel-lint": "^1.0", "meyfa/phpunit-assert-gd": "^2.0.0|^3.0.0", "dms/phpunit-arraysubset-asserts": "^0.1.0|^0.2.1", - "nunomaduro/larastan": "2.x-dev", + "larastan/larastan": "^2.8.1", "orchestra/testbench": "^8.4" }, "suggest": { diff --git a/src/Cache/CacheManager.php b/src/Cache/CacheManager.php index 6d0375d71..0c1de974a 100644 --- a/src/Cache/CacheManager.php +++ b/src/Cache/CacheManager.php @@ -16,4 +16,4 @@ public function store($name = null) { return parent::store($name); } -} \ No newline at end of file +} From 4c7a7afd22a0544c5eb5ba6f2a8b42e8026dcc23 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 11:06:02 -0400 Subject: [PATCH 005/111] adjust $fillable signature --- src/Database/Attach/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Attach/File.php b/src/Database/Attach/File.php index 45c56f2a7..af476ee14 100644 --- a/src/Database/Attach/File.php +++ b/src/Database/Attach/File.php @@ -40,7 +40,7 @@ class File extends Model ]; /** - * @var string[] The attributes that are mass assignable. + * @var array The attributes that are mass assignable. */ protected $fillable = [ 'file_name', From d58d3146926cf5988b9a7ab076709ad30dbe7935 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 11:06:36 -0400 Subject: [PATCH 006/111] adjust store() method return type --- src/Cache/CacheManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cache/CacheManager.php b/src/Cache/CacheManager.php index 0c1de974a..0a2249fd1 100644 --- a/src/Cache/CacheManager.php +++ b/src/Cache/CacheManager.php @@ -10,7 +10,7 @@ class CacheManager extends BaseCacheManager * Get a cache store instance by name, wrapped in a repository. * * @param string|null $name - * @return \Illuminate\Cache\Repository + * @return \Illuminate\Contracts\Cache\Repository */ public function store($name = null) { From 3c4013c936c5c54fc1750b55788a0406fd53fc72 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 11:35:33 -0400 Subject: [PATCH 007/111] fix getCache() return type --- src/Halcyon/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Halcyon/Builder.php b/src/Halcyon/Builder.php index 2df827548..de7313be3 100644 --- a/src/Halcyon/Builder.php +++ b/src/Halcyon/Builder.php @@ -699,11 +699,11 @@ protected function isCacheBusted($result) /** * Get the cache object with tags assigned, if applicable. * - * @return \Illuminate\Cache\Repository + * @return \Illuminate\Contracts\Cache\Repository */ protected function getCache() { - $cache = $this->model->getCacheManager()->store($this->cacheDriver); + $cache = $this->model->getCacheManager()->driver($this->cacheDriver); return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache; } From f5e4b94f55c69f91d819423955df234950e01996 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 11:36:00 -0400 Subject: [PATCH 008/111] remove invalid getValue() call --- src/Database/Relations/Concerns/DeferOneOrMany.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Relations/Concerns/DeferOneOrMany.php b/src/Database/Relations/Concerns/DeferOneOrMany.php index bfb8bb3a6..3bd9cc66e 100644 --- a/src/Database/Relations/Concerns/DeferOneOrMany.php +++ b/src/Database/Relations/Concerns/DeferOneOrMany.php @@ -96,7 +96,7 @@ public function withDeferred($sessionKey) ->where('session_key', $sessionKey) ->where('is_bind', 0) ->whereRaw(DbDongle::parse('id > ifnull((select max(id) from ' . DbDongle::getTablePrefix() . 'deferred_bindings where - slave_id = ' . $this->getWithDeferredQualifiedKeyName()->getValue(new Grammar) . ' and + slave_id = ' . $this->getWithDeferredQualifiedKeyName() . ' and master_field = ? and master_type = ? and session_key = ? and From 00513c966af69680759a7d135f3427badd5afc33 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:13:27 -0400 Subject: [PATCH 009/111] migrate phpunit xml config --- phpunit.xml.dist | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5db8edbf7..504abbbd5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,23 +1,13 @@ - - - - ./src/ - - - - - ./tests - - + + + + ./tests + + + + + ./src/ + + From 3a86f6c2e02aedeeac8f560ae1fa4c1a7b024d4e Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:13:52 -0400 Subject: [PATCH 010/111] update dependencies for laravel 11 --- composer.json | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 6e80c5145..bbb5b8e00 100644 --- a/composer.json +++ b/composer.json @@ -35,32 +35,37 @@ "ext-pdo": "*", "ext-zip": "*", - "assetic/framework": "~3.0", + "assetic/framework": "dev-master", "doctrine/dbal": "^3.6", "enshrined/svg-sanitize": "~0.16", - "laravel/framework": "^10.1", + "laravel/framework": "^11.0", "laravel/tinker": "^2.8.1", "league/csv": "~9.1", "nesbot/carbon": "^2.0", "nikic/php-parser": "^4.10", "scssphp/scssphp": "~1.0", - "symfony/console": "^6.3", - "symfony/yaml": "^6.0", + "symfony/console": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", "twig/twig": "~3.0", "wikimedia/less.php": "~3.0", "wikimedia/minify": "~2.2", "winter/laravel-config-writer": "^1.0.1" }, "require-dev": { - "phpunit/phpunit": "^9.5.8", - "mockery/mockery": "^1.4.4", "squizlabs/php_codesniffer": "^3.2", "php-parallel-lint/php-parallel-lint": "^1.0", - "meyfa/phpunit-assert-gd": "^2.0.0|^3.0.0", - "dms/phpunit-arraysubset-asserts": "^0.1.0|^0.2.1", - "larastan/larastan": "^2.8.1", - "orchestra/testbench": "^8.4" + "meyfa/phpunit-assert-gd": "^4.0", + "dms/phpunit-arraysubset-asserts": "^0.5", + "orchestra/testbench": "^9.0", + "larastan/larastan": "^2.8.1" }, + "repositories": [ + { + "type": "path", + "url": "vendor/assetic/framework" + } + ], + "suggest": { "ext-pdo_dblib": "Required to use MS SQL Server databases", "ext-pdo_mysql": "Required to use MySQL databases", From ea41b896f8516e2274cdd446b378dc6f3f0134c3 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:14:37 -0400 Subject: [PATCH 011/111] allign with new Authenticatable contract --- src/Auth/Models/User.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Auth/Models/User.php b/src/Auth/Models/User.php index 3865d0a9f..64f6246e2 100644 --- a/src/Auth/Models/User.php +++ b/src/Auth/Models/User.php @@ -110,6 +110,13 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable */ protected $rememberTokenName = 'persist_code'; + /** + * The column name of the password field using during authentication. + * + * @var string + */ + protected $authPasswordName = 'password'; + /** * @var array The user merged permissions. */ @@ -248,7 +255,7 @@ public function attemptActivation($activationCode) */ public function checkPassword($password) { - return Hash::check($password, $this->password); + return Hash::check($password, $this->getAuthPassword()); } /** @@ -285,7 +292,7 @@ public function checkResetPasswordCode($resetCode) public function attemptResetPassword($resetCode, $newPassword) { if ($this->checkResetPasswordCode($resetCode)) { - $this->password = $newPassword; + $this->{$this->getAuthPasswordName()} = $newPassword; $this->reset_password_code = null; return $this->forceSave(); } @@ -600,13 +607,23 @@ public function getAuthIdentifier() return $this->{$this->getAuthIdentifierName()}; } + /** + * Get the name of the password attribute for the user. + * + * @return string + */ + public function getAuthPasswordName() + { + return $this->authPasswordName; + } + /** * Get the password for the user. * @return string */ public function getAuthPassword() { - return $this->password; + return $this->{$this->getAuthPasswordName()}; } /** From 3f5e612ead375da44662dee970b317bba9577052 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:16:05 -0400 Subject: [PATCH 012/111] match symfony SignalableCommandInterface signature --- src/Console/Traits/HandlesCleanup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Console/Traits/HandlesCleanup.php b/src/Console/Traits/HandlesCleanup.php index 641f5cb4d..a4bd72cf4 100644 --- a/src/Console/Traits/HandlesCleanup.php +++ b/src/Console/Traits/HandlesCleanup.php @@ -39,7 +39,7 @@ public function getSubscribedSignals(): array /** * Handle the provided Unix process signal */ - public function handleSignal(int $signal): int|false + public function handleSignal(int $signal, int|false $previousExitCode = 0): int|false { // Handle the signal if (method_exists($this, 'handleCleanup')) { From 9f9dc7a6ff27bbd5a2a4f95d8cb329d7f6a69af5 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:16:41 -0400 Subject: [PATCH 013/111] match new builder paginate signature --- src/Database/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Builder.php b/src/Database/Builder.php index f42dcf2a2..cd7c632d3 100644 --- a/src/Database/Builder.php +++ b/src/Database/Builder.php @@ -128,12 +128,12 @@ protected function searchWhereInternal($term, $columns, $mode, $boolean) * @param string|int|null $pageName * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function paginate($perPage = null, $currentPage = null, $columns = ['*'], $pageName = 'page') + public function paginate($perPage = null, $currentPage = null, $columns = ['*'], $pageName = 'page', $total = 0) { /* * Engage Laravel signature support * - * paginate($perPage, $columns, $pageName, $currentPage) + * paginate($perPage, $columns, $pageName, $currentPage, $total) */ if (is_array($currentPage)) { $_columns = $columns; From da18666015c3af0c87b71f5d44f8d243f913ede6 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:17:35 -0400 Subject: [PATCH 014/111] update CacheManager signature --- src/Halcyon/MemoryCacheManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Halcyon/MemoryCacheManager.php b/src/Halcyon/MemoryCacheManager.php index ccb5ea9c8..62422cdca 100644 --- a/src/Halcyon/MemoryCacheManager.php +++ b/src/Halcyon/MemoryCacheManager.php @@ -7,9 +7,9 @@ class MemoryCacheManager extends CacheManager { - public function repository(Store $store) + public function repository(Store $store, array $config = []) { - return new MemoryRepository($store); + return new MemoryRepository($store, $config); } public static function isEnabled() From b18d3e52aa3c5155fbf143f1db13c20803189bb2 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:20:24 -0400 Subject: [PATCH 015/111] fix assetic/framework dependency --- composer.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/composer.json b/composer.json index bbb5b8e00..ebac1a444 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "ext-pdo": "*", "ext-zip": "*", - "assetic/framework": "dev-master", + "assetic/framework": "^3.1", "doctrine/dbal": "^3.6", "enshrined/svg-sanitize": "~0.16", "laravel/framework": "^11.0", @@ -59,12 +59,6 @@ "orchestra/testbench": "^9.0", "larastan/larastan": "^2.8.1" }, - "repositories": [ - { - "type": "path", - "url": "vendor/assetic/framework" - } - ], "suggest": { "ext-pdo_dblib": "Required to use MS SQL Server databases", From 98b0e6afaf985528e40e36041b271a3f9548fa75 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:51:00 -0400 Subject: [PATCH 016/111] fix mockery dependency --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index ebac1a444..3c9638db7 100644 --- a/composer.json +++ b/composer.json @@ -55,6 +55,7 @@ "squizlabs/php_codesniffer": "^3.2", "php-parallel-lint/php-parallel-lint": "^1.0", "meyfa/phpunit-assert-gd": "^4.0", + "mockery/mockery": "^1.6|^2.0", "dms/phpunit-arraysubset-asserts": "^0.5", "orchestra/testbench": "^9.0", "larastan/larastan": "^2.8.1" From 7aee65986ba5dbe6b1b2f0d6c04761cb69d48a78 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 13:51:44 -0400 Subject: [PATCH 017/111] replace setMethods() with add/onlyMethods() --- src/Support/Testing/MocksClassLoader.php | 2 +- tests/Database/QueryBuilderTest.php | 5 ++++- .../Http/Middleware/CheckForTrustedHostTest.php | 2 +- .../Http/Middleware/CheckForTrustedProxiesTest.php | 2 +- tests/Halcyon/HalcyonModelTest.php | 9 ++++++--- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Support/Testing/MocksClassLoader.php b/src/Support/Testing/MocksClassLoader.php index f22912092..46f756f83 100644 --- a/src/Support/Testing/MocksClassLoader.php +++ b/src/Support/Testing/MocksClassLoader.php @@ -49,7 +49,7 @@ protected function registerMockClassLoader($basePath = null, $manifestPath = nul protected function mockClassLoader($class) { $subject = $this->getMockBuilder($class) - ->setMethods(['extensionGetClassLoader']) + ->onlyMethods(['extensionGetClassLoader']) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Database/QueryBuilderTest.php b/tests/Database/QueryBuilderTest.php index 0d2387ce9..4018e5846 100644 --- a/tests/Database/QueryBuilderTest.php +++ b/tests/Database/QueryBuilderTest.php @@ -105,9 +105,10 @@ protected function getConnection($connection = null, $table = null) ->disableOriginalClone() ->disableArgumentCloning() ->disallowMockingUnknownTypes() - ->setMethods([ + ->onlyMethods([ 'table', 'raw', + 'scalar', 'selectOne', 'select', 'cursor', @@ -125,6 +126,8 @@ protected function getConnection($connection = null, $table = null) 'transactionLevel', 'pretend', 'getDatabaseName', + ]) + ->addMethods([ 'getConfig', ]) ->getMock(); diff --git a/tests/Foundation/Http/Middleware/CheckForTrustedHostTest.php b/tests/Foundation/Http/Middleware/CheckForTrustedHostTest.php index 758a4b288..d1bb6ff7a 100644 --- a/tests/Foundation/Http/Middleware/CheckForTrustedHostTest.php +++ b/tests/Foundation/Http/Middleware/CheckForTrustedHostTest.php @@ -182,7 +182,7 @@ protected function createUrlGenerator($trustedHosts = [], $headers = [], $server { $middleware = $this->getMockBuilder(CheckForTrustedHost::class) ->disableOriginalConstructor() - ->setMethods(['hosts', 'shouldSpecifyTrustedHosts']) + ->onlyMethods(['hosts', 'shouldSpecifyTrustedHosts']) ->getMock(); $middleware->expects($this->any()) diff --git a/tests/Foundation/Http/Middleware/CheckForTrustedProxiesTest.php b/tests/Foundation/Http/Middleware/CheckForTrustedProxiesTest.php index cbde74f1f..8f0cb5495 100644 --- a/tests/Foundation/Http/Middleware/CheckForTrustedProxiesTest.php +++ b/tests/Foundation/Http/Middleware/CheckForTrustedProxiesTest.php @@ -432,7 +432,7 @@ protected function createTrustedProxyMock($trustedProxies = [], $trustedHeaders { $middleware = $this->getMockBuilder(CheckForTrustedProxies::class) ->disableOriginalConstructor() - ->setMethods(['proxies', 'headers']) + ->onlyMethods(['proxies', 'headers']) ->getMock(); $middleware->expects($this->any()) diff --git a/tests/Halcyon/HalcyonModelTest.php b/tests/Halcyon/HalcyonModelTest.php index 2bee0deec..6813750c8 100644 --- a/tests/Halcyon/HalcyonModelTest.php +++ b/tests/Halcyon/HalcyonModelTest.php @@ -377,13 +377,16 @@ protected function setDatasourceResolver() protected function setValidatorOnModel() { - $translator = $this->getMockBuilder('Illuminate\Contracts\Translation\Translator')->setMethods([ + $translator = $this->getMockBuilder('Illuminate\Contracts\Translation\Translator') + ->onlyMethods([ 'get', 'choice', - 'trans', - 'transChoice', 'setLocale', 'getLocale' + ]) + ->addMethods([ + 'trans', + 'transChoice', ])->getMock(); $translator->expects($this->any())->method('get')->will($this->returnArgument(0)); From 79e2747c9dbd229abcbd309518111055d9eaca43 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 14:07:46 -0400 Subject: [PATCH 018/111] fix deprecation errors --- tests/Filesystem/FilesystemTest.php | 2 +- tests/Parse/MarkdownTest.php | 28 ++++++++++++------------ tests/Router/RoutingUrlGeneratorTest.php | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/Filesystem/FilesystemTest.php b/tests/Filesystem/FilesystemTest.php index 3ffa36362..8b85a1475 100644 --- a/tests/Filesystem/FilesystemTest.php +++ b/tests/Filesystem/FilesystemTest.php @@ -25,7 +25,7 @@ public function testIsAbsolutePath($path, $expectedResult) $this->assertEquals($expectedResult, $result); } - public function providePathsForIsAbsolutePath() + public static function providePathsForIsAbsolutePath() { return [ ['/var/lib', true], diff --git a/tests/Parse/MarkdownTest.php b/tests/Parse/MarkdownTest.php index 82fb24416..9f87d0de0 100644 --- a/tests/Parse/MarkdownTest.php +++ b/tests/Parse/MarkdownTest.php @@ -7,7 +7,7 @@ class MarkdownTest extends TestCase /** * Test fixtures that should be skipped by the data provider. */ - protected array $specialTests = [ + protected static array $specialTests = [ 'front_matter', ]; @@ -20,15 +20,15 @@ class MarkdownTest extends TestCase */ public function testParse($name, $markdown, $html) { - $this->assertEquals($html, $this->removeLineEndings(Markdown::parse($markdown)), 'Markdown test case "' . $name . '" failed'); + $this->assertEquals($html, static::removeLineEndings(Markdown::parse($markdown)), 'Markdown test case "' . $name . '" failed'); } public function testParseSafe() { $markdown = file_get_contents(dirname(__DIR__) . '/fixtures/markdown/code_block.md'); - $html = $this->removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/code_block_disabled.html')); + $html = static::removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/code_block_disabled.html')); - $this->assertEquals($html, $this->removeLineEndings(Markdown::parseSafe($markdown))); + $this->assertEquals($html, static::removeLineEndings(Markdown::parseSafe($markdown))); } public function testDisableAndEnableMethods() @@ -36,16 +36,16 @@ public function testDisableAndEnableMethods() $parser = Markdown::disableAutolinking()->disableTables(); $markdown = file_get_contents(dirname(__DIR__) . '/fixtures/markdown/table_inline_markdown.md'); - $html = $this->removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/table_inline_markdown_disabled.html')); + $html = static::removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/table_inline_markdown_disabled.html')); - $this->assertEquals($html, $this->removeLineEndings($parser->parse($markdown))); + $this->assertEquals($html, static::removeLineEndings($parser->parse($markdown))); // Re-enable tables and autolinking $parser->enableAutolinking()->enableTables(); - $html = $this->removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/table_inline_markdown.html')); + $html = static::removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/table_inline_markdown.html')); - $this->assertEquals($html, $this->removeLineEndings($parser->parse($markdown))); + $this->assertEquals($html, static::removeLineEndings($parser->parse($markdown))); } public function testFrontMatter() @@ -53,9 +53,9 @@ public function testFrontMatter() $parser = Markdown::enableFrontMatter(); $markdown = file_get_contents(dirname(__DIR__) . '/fixtures/markdown/front_matter.md'); - $html = $this->removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/front_matter.html')); + $html = static::removeLineEndings(file_get_contents(dirname(__DIR__) . '/fixtures/markdown/front_matter.html')); - $this->assertEquals($html, $this->removeLineEndings($parser->parse($markdown))); + $this->assertEquals($html, static::removeLineEndings($parser->parse($markdown))); $this->assertEquals([ 'title' => 'My document', 'group' => 'Documents', @@ -75,7 +75,7 @@ public function testFrontMatter() * * @return array */ - public function markdownData() + public static function markdownData() { $dirName = dirname(__DIR__) . '/fixtures/markdown'; $dir = new DirectoryIterator($dirName); @@ -87,19 +87,19 @@ public function markdownData() if ($name === 'README') { continue; } - if (in_array($name, $this->specialTests)) { + if (in_array($name, static::$specialTests)) { continue; } $markdown = file_get_contents($dirName . DIRECTORY_SEPARATOR . $name . '.md'); - $html = $this->removeLineEndings(file_get_contents($dirName . DIRECTORY_SEPARATOR . $name . '.html')); + $html = static::removeLineEndings(file_get_contents($dirName . DIRECTORY_SEPARATOR . $name . '.html')); yield [$name, $markdown, $html]; } } } - protected function removeLineEndings(string $text) + protected static function removeLineEndings(string $text) { return str_replace(["\r\n", "\r", "\n"], '', $text); } diff --git a/tests/Router/RoutingUrlGeneratorTest.php b/tests/Router/RoutingUrlGeneratorTest.php index e3d55892d..b28f926c6 100644 --- a/tests/Router/RoutingUrlGeneratorTest.php +++ b/tests/Router/RoutingUrlGeneratorTest.php @@ -526,7 +526,7 @@ public function testRoutesWithDomainsThroughProxy() $this->assertSame('http://sub.foo.com/foo/bar', $url->route('foo')); } - public function providerRouteParameters() + public static function providerRouteParameters() { return [ [['test' => 123]], @@ -555,7 +555,7 @@ public function testUrlGenerationForControllersRequiresPassingOfRequiredParamete $this->assertSame('http://www.foo.com:8080/foo?test=123', $url->route('foo', $parameters)); } - public function provideParametersAndExpectedMeaningfulExceptionMessages() + public static function provideParametersAndExpectedMeaningfulExceptionMessages() { return [ 'Missing parameters "one", "two" and "three"' => [ From 7b588e2eab5e2009793384cbbc183f9e043d938f Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 14:19:56 -0400 Subject: [PATCH 019/111] we need to extend TestCase now --- tests/fixtures/events/EventTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/fixtures/events/EventTest.php b/tests/fixtures/events/EventTest.php index 91b016959..1774b07a8 100644 --- a/tests/fixtures/events/EventTest.php +++ b/tests/fixtures/events/EventTest.php @@ -1,5 +1,8 @@ Date: Wed, 3 Apr 2024 14:23:18 -0400 Subject: [PATCH 020/111] call parent constructor --- tests/fixtures/events/EventTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fixtures/events/EventTest.php b/tests/fixtures/events/EventTest.php index 1774b07a8..002ddb208 100644 --- a/tests/fixtures/events/EventTest.php +++ b/tests/fixtures/events/EventTest.php @@ -4,5 +4,6 @@ class EventTest extends TestCase { public function __construct() { + parent::__construct("dummy"); } } From 16d43fa9c51a45e51dcaf8189bf4513aca2f6de3 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 14:59:01 -0400 Subject: [PATCH 021/111] return class instance --- src/Auth/Manager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Auth/Manager.php b/src/Auth/Manager.php index fe4ff7549..57cecad18 100644 --- a/src/Auth/Manager.php +++ b/src/Auth/Manager.php @@ -171,9 +171,10 @@ public function hasUser() * Sets the user * @phpstan-param Models\User $user */ - public function setUser(Authenticatable $user) + public function setUser(Authenticatable $user) : self { $this->user = $user; + return $this; } /** From 397081980876b607d0402f6b7a9bf9d0e6292335 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 14:59:16 -0400 Subject: [PATCH 022/111] Remove argument removed in Laravel 11 --- src/Support/helpers-array.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Support/helpers-array.php b/src/Support/helpers-array.php index e07c42f03..d5af63742 100644 --- a/src/Support/helpers-array.php +++ b/src/Support/helpers-array.php @@ -333,7 +333,7 @@ function array_set(&$array, $key, $value) */ function array_shuffle($array, $seed = null) { - return Arr::shuffle($array, $seed); + return Arr::shuffle($array); } } From 148ea7ccc84aa50528d3c09a7e9cfffb4368a12b Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 15:00:20 -0400 Subject: [PATCH 023/111] PDO driver classes removed in Laravel 11 --- src/Database/Connections/MySqlConnection.php | 11 ----------- src/Database/Connections/PostgresConnection.php | 11 ----------- src/Database/Connections/SQLiteConnection.php | 11 ----------- src/Database/Connections/SqlServerConnection.php | 11 ----------- 4 files changed, 44 deletions(-) diff --git a/src/Database/Connections/MySqlConnection.php b/src/Database/Connections/MySqlConnection.php index 2458a9ee6..39185ad46 100644 --- a/src/Database/Connections/MySqlConnection.php +++ b/src/Database/Connections/MySqlConnection.php @@ -1,7 +1,6 @@ Date: Wed, 3 Apr 2024 15:08:11 -0400 Subject: [PATCH 024/111] try to make EventTest work --- tests/fixtures/events/EventTest.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/fixtures/events/EventTest.php b/tests/fixtures/events/EventTest.php index 002ddb208..07de92141 100644 --- a/tests/fixtures/events/EventTest.php +++ b/tests/fixtures/events/EventTest.php @@ -4,6 +4,11 @@ class EventTest extends TestCase { public function __construct() { - parent::__construct("dummy"); + parent::__construct("testDummy"); + } + + public function testDummy() + { + $this->assertTrue(true, true); } } From 5bddeb65800d73daa860ada73c4a81afd16d19c5 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 15:11:49 -0400 Subject: [PATCH 025/111] remove upload test artifact --- .github/workflows/tests.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 87d2e7a28..04d34c84a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,11 +43,3 @@ jobs: - name: Run tests run: ./vendor/bin/phpunit ./tests - - - name: Upload test artifacts on failure - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ResizerTest-${{ matrix.operatingSystem }}-PHP${{ matrix.phpVersion }} - path: tests/artifacts/ResizerTest/ - if-no-files-found: error From 88f16390c652641a8341edb2334536ac71bbb06b Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Apr 2024 15:16:42 -0400 Subject: [PATCH 026/111] update php test versions --- .github/workflows/tests.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 04d34c84a..cc94e8ba4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: max-parallel: 4 matrix: operatingSystem: [ubuntu-latest, windows-latest] - phpVersion: ['8.1', '8.2'] + phpVersion: ['8.2', '8.3'] fail-fast: false runs-on: ${{ matrix.operatingSystem }} name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }} @@ -37,9 +37,5 @@ jobs: - name: Install Composer dependencies run: composer install --no-interaction --no-progress --no-scripts - - name: Setup problem matchers for PHPUnit - if: matrix.phpVersion == '8.2' - run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - name: Run tests run: ./vendor/bin/phpunit ./tests From cccf1b6a5839362950e5c7185f038fb617644888 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Thu, 4 Apr 2024 15:03:36 -0400 Subject: [PATCH 027/111] add comment about deprecated $dates property; remove doctrine/dbal --- composer.json | 1 - src/Database/Model.php | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3c9638db7..27cd5cc24 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,6 @@ "ext-zip": "*", "assetic/framework": "^3.1", - "doctrine/dbal": "^3.6", "enshrined/svg-sanitize": "~0.16", "laravel/framework": "^11.0", "laravel/tinker": "^2.8.1", diff --git a/src/Database/Model.php b/src/Database/Model.php index 5e3d9fcee..be501ddb8 100644 --- a/src/Database/Model.php +++ b/src/Database/Model.php @@ -78,6 +78,8 @@ class Model extends EloquentModel implements ModelInterface */ public function __construct(array $attributes = []) { + //$dates property has been removed in Laravel 11 + //$this->casts = array_merge($this->casts ?? [], $this->dates); parent::__construct(); $this->bootNicerEvents(); From ec6d8a66e297a60864b31e50b3736e212618b28e Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Thu, 4 Apr 2024 15:56:16 -0400 Subject: [PATCH 028/111] remove unnecessary override of Illuminate\Cache\CacheManager --- composer.json | 1 + src/Cache/CacheManager.php | 10 ---------- src/Foundation/Application.php | 2 +- src/Halcyon/Builder.php | 2 +- src/Halcyon/Model.php | 6 +++--- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 27cd5cc24..b8787c1e3 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,7 @@ "ext-zip": "*", "assetic/framework": "^3.1", + "doctrine/dbal": "^3.6", "enshrined/svg-sanitize": "~0.16", "laravel/framework": "^11.0", "laravel/tinker": "^2.8.1", diff --git a/src/Cache/CacheManager.php b/src/Cache/CacheManager.php index 0a2249fd1..b6b40d720 100644 --- a/src/Cache/CacheManager.php +++ b/src/Cache/CacheManager.php @@ -6,14 +6,4 @@ class CacheManager extends BaseCacheManager { - /** - * Get a cache store instance by name, wrapped in a repository. - * - * @param string|null $name - * @return \Illuminate\Contracts\Cache\Repository - */ - public function store($name = null) - { - return parent::store($name); - } } diff --git a/src/Foundation/Application.php b/src/Foundation/Application.php index 6f5943454..b8e97e4ce 100644 --- a/src/Foundation/Application.php +++ b/src/Foundation/Application.php @@ -480,7 +480,7 @@ public function registerCoreContainerAliases() $aliases = [ 'app' => [\Winter\Storm\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class], 'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class], - 'cache' => [\Winter\Storm\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class], + 'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class], 'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class], 'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class], 'cookie' => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class], diff --git a/src/Halcyon/Builder.php b/src/Halcyon/Builder.php index de7313be3..0b0f729ed 100644 --- a/src/Halcyon/Builder.php +++ b/src/Halcyon/Builder.php @@ -703,7 +703,7 @@ protected function isCacheBusted($result) */ protected function getCache() { - $cache = $this->model->getCacheManager()->driver($this->cacheDriver); + $cache = $this->model->getCacheManager()->store($this->cacheDriver); return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache; } diff --git a/src/Halcyon/Model.php b/src/Halcyon/Model.php index 1458906ae..f51c3ac47 100644 --- a/src/Halcyon/Model.php +++ b/src/Halcyon/Model.php @@ -109,7 +109,7 @@ class Model extends Extendable implements ModelInterface, ArrayAccess, Arrayable /** * The cache manager instance. * - * @var \Winter\Storm\Cache\CacheManager|null + * @var \Illuminate\Cache\CacheManager|null */ protected static $cache; @@ -1512,7 +1512,7 @@ public static function unsetEventDispatcher() /** * Get the cache manager instance. * - * @return \Winter\Storm\Cache\CacheManager|null + * @return \Illuminate\Cache\CacheManager|null */ public static function getCacheManager() { @@ -1522,7 +1522,7 @@ public static function getCacheManager() /** * Set the cache manager instance. * - * @param \Winter\Storm\Cache\CacheManager $cache + * @param \Illuminate\Cache\CacheManager $cache * @return void */ public static function setCacheManager($cache) From 388fe35193b2528f458c96611be2d58591848e55 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Thu, 4 Apr 2024 16:16:19 -0400 Subject: [PATCH 029/111] no need to add dates to cast, this is handled in HasAttribute trait --- src/Database/Model.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Database/Model.php b/src/Database/Model.php index be501ddb8..5e3d9fcee 100644 --- a/src/Database/Model.php +++ b/src/Database/Model.php @@ -78,8 +78,6 @@ class Model extends EloquentModel implements ModelInterface */ public function __construct(array $attributes = []) { - //$dates property has been removed in Laravel 11 - //$this->casts = array_merge($this->casts ?? [], $this->dates); parent::__construct(); $this->bootNicerEvents(); From f71ad1ea68d298b679a8691a185fe72ba3692148 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Thu, 4 Apr 2024 16:46:25 -0400 Subject: [PATCH 030/111] ignore phpstan error on abstract base class --- composer.json | 1 - phpstan-baseline.neon | 5 +++++ src/Halcyon/Builder.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index b8787c1e3..27cd5cc24 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,6 @@ "ext-zip": "*", "assetic/framework": "^3.1", - "doctrine/dbal": "^3.6", "enshrined/svg-sanitize": "~0.16", "laravel/framework": "^11.0", "laravel/tinker": "^2.8.1", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ace12018d..d85ee361f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -764,3 +764,8 @@ parameters: message: "#^Call to function is_null\\(\\) with Closure will always evaluate to false\\.$#" count: 1 path: src/Validation/Factory.php + + - + message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository\\:\\:tags\\(\\).$#" + count: 1 + path: src/Halcyon/Builder.php diff --git a/src/Halcyon/Builder.php b/src/Halcyon/Builder.php index 0b0f729ed..de7313be3 100644 --- a/src/Halcyon/Builder.php +++ b/src/Halcyon/Builder.php @@ -703,7 +703,7 @@ protected function isCacheBusted($result) */ protected function getCache() { - $cache = $this->model->getCacheManager()->store($this->cacheDriver); + $cache = $this->model->getCacheManager()->driver($this->cacheDriver); return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache; } From 60f676f1bf8df3047b07e586708926163062dbee Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Thu, 4 Apr 2024 16:50:20 -0400 Subject: [PATCH 031/111] remove ignore rule --- phpstan-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d85ee361f..ace12018d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -764,8 +764,3 @@ parameters: message: "#^Call to function is_null\\(\\) with Closure will always evaluate to false\\.$#" count: 1 path: src/Validation/Factory.php - - - - message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository\\:\\:tags\\(\\).$#" - count: 1 - path: src/Halcyon/Builder.php From 8dcf119b3480b5aed79470b11cac4fae4410824c Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 5 Apr 2024 17:15:02 -0400 Subject: [PATCH 032/111] restore migration behavior --- src/Database/Connections/MySqlConnection.php | 3 +- .../Connections/PostgresConnection.php | 3 +- src/Database/Connections/SQLiteConnection.php | 3 +- .../Connections/SqlServerConnection.php | 3 +- src/Database/Connectors/ConnectionFactory.php | 3 + .../Schema/Grammars/MariaDbGrammar.php | 7 + src/Database/Schema/Grammars/MySqlGrammar.php | 55 + .../Schema/Grammars/PostgresGrammar.php | 53 + .../Schema/Grammars/SQLiteGrammar.php | 117 ++ .../Schema/Grammars/SqlServerGrammar.php | 49 + .../Grammars/MySqlSchemaGrammarTest.php | 1459 +++++++++++++++++ .../Grammars/PostgresSchemaGrammarTest.php | 1238 ++++++++++++++ .../Grammars/SQLiteSchemaGrammarTest.php | 937 +++++++++++ .../Grammars/SqlServerSchemaGrammarTest.php | 932 +++++++++++ 14 files changed, 4858 insertions(+), 4 deletions(-) create mode 100755 src/Database/Schema/Grammars/MariaDbGrammar.php create mode 100755 src/Database/Schema/Grammars/MySqlGrammar.php create mode 100755 src/Database/Schema/Grammars/PostgresGrammar.php create mode 100755 src/Database/Schema/Grammars/SQLiteGrammar.php create mode 100755 src/Database/Schema/Grammars/SqlServerGrammar.php create mode 100644 tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php create mode 100644 tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php create mode 100644 tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php create mode 100644 tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php diff --git a/src/Database/Connections/MySqlConnection.php b/src/Database/Connections/MySqlConnection.php index 39185ad46..e8f809014 100644 --- a/src/Database/Connections/MySqlConnection.php +++ b/src/Database/Connections/MySqlConnection.php @@ -3,7 +3,8 @@ use PDO; use Illuminate\Database\Schema\MySqlBuilder; use Illuminate\Database\Query\Processors\MySqlProcessor; -use Illuminate\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; + +use Winter\Storm\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; use Winter\Storm\Database\Query\Grammars\MySqlGrammar as QueryGrammar; /** diff --git a/src/Database/Connections/PostgresConnection.php b/src/Database/Connections/PostgresConnection.php index 16bc05243..e1b11dc0b 100644 --- a/src/Database/Connections/PostgresConnection.php +++ b/src/Database/Connections/PostgresConnection.php @@ -2,8 +2,9 @@ use Illuminate\Database\Schema\PostgresBuilder; use Illuminate\Database\Query\Processors\PostgresProcessor; + use Winter\Storm\Database\Query\Grammars\PostgresGrammar as QueryGrammar; -use Illuminate\Database\Schema\Grammars\PostgresGrammar as SchemaGrammar; +use Winter\Storm\Database\Schema\Grammars\PostgresGrammar as SchemaGrammar; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar diff --git a/src/Database/Connections/SQLiteConnection.php b/src/Database/Connections/SQLiteConnection.php index cda9f3952..0e22ff93d 100644 --- a/src/Database/Connections/SQLiteConnection.php +++ b/src/Database/Connections/SQLiteConnection.php @@ -2,8 +2,9 @@ use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Database\Query\Processors\SQLiteProcessor; + use Winter\Storm\Database\Query\Grammars\SQLiteGrammar as QueryGrammar; -use Illuminate\Database\Schema\Grammars\SQLiteGrammar as SchemaGrammar; +use Winter\Storm\Database\Schema\Grammars\SQLiteGrammar as SchemaGrammar; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar diff --git a/src/Database/Connections/SqlServerConnection.php b/src/Database/Connections/SqlServerConnection.php index 1a764669c..640e3181a 100644 --- a/src/Database/Connections/SqlServerConnection.php +++ b/src/Database/Connections/SqlServerConnection.php @@ -5,7 +5,8 @@ use Throwable; use Illuminate\Database\Schema\SqlServerBuilder; use Illuminate\Database\Query\Processors\SqlServerProcessor; -use Illuminate\Database\Schema\Grammars\SqlServerGrammar as SchemaGrammar; + +use Winter\Storm\Database\Schema\Grammars\SqlServerGrammar as SchemaGrammar; use Winter\Storm\Database\Query\Grammars\SqlServerGrammar as QueryGrammar; /** diff --git a/src/Database/Connectors/ConnectionFactory.php b/src/Database/Connectors/ConnectionFactory.php index 629630037..d9be1dc6c 100644 --- a/src/Database/Connectors/ConnectionFactory.php +++ b/src/Database/Connectors/ConnectionFactory.php @@ -3,6 +3,7 @@ use Illuminate\Support\Arr; use Illuminate\Database\Connectors\ConnectionFactory as ConnectionFactoryBase; use Winter\Storm\Database\Connections\Connection; +use Winter\Storm\Database\Connections\MariaDbConnection; use Winter\Storm\Database\Connections\MySqlConnection; use Winter\Storm\Database\Connections\SQLiteConnection; use Winter\Storm\Database\Connections\PostgresConnection; @@ -57,6 +58,8 @@ protected function createConnection($driver, $connection, $database, $prefix = ' } switch ($driver) { + case 'mariadb': + return new MariaDbConnection($connection, $database, $prefix, $config); case 'mysql': return new MySqlConnection($connection, $database, $prefix, $config); case 'pgsql': diff --git a/src/Database/Schema/Grammars/MariaDbGrammar.php b/src/Database/Schema/Grammars/MariaDbGrammar.php new file mode 100755 index 000000000..9a574623e --- /dev/null +++ b/src/Database/Schema/Grammars/MariaDbGrammar.php @@ -0,0 +1,7 @@ +getSchemaBuilder()->getColumns($blueprint->getTable())); + + foreach ($blueprint->getChangedColumns() as $column) { + $sql = sprintf('%s %s%s %s', + is_null($column->renameTo) ? 'modify' : 'change', + $this->wrap($column), + is_null($column->renameTo) ? '' : ' '.$this->wrap($column->renameTo), + $this->getType($column) + ); + + $oldColum = new Fluent($prevColumns->where('name', $name)->first()); + $columns[] = $this->addLegacyModifiers($sql, $blueprint, $column, $oldColumn); + } + + return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); + } + + protected function addLegacyModifiers($sql, Blueprint $blueprint, Fluent $column, Fluent $oldColumn) + { + foreach ($this->modifiers as $modifier) { + if (method_exists($this, $method = "modify{$modifier}")) { + $mod = strtolower($modifier); + $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $sql .= $this->{$method}($blueprint, $col); + } + } + + return $sql; + } + +} diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php new file mode 100755 index 000000000..e1f1d0b7c --- /dev/null +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -0,0 +1,53 @@ +getSchemaBuilder()->getColumns($blueprint->getTable())); + + foreach ($blueprint->getChangedColumns() as $column) { + $changes = ['type '.$this->getType($column).$this->modifyCollate($blueprint, $column)]; + + $oldColum = new Fluent($prevColumns->where('name', $name)->first()); + foreach ($this->modifiers as $modifier) { + if ($modifier === 'Collate') { + continue; + } + + if (method_exists($this, $method = "modify{$modifier}")) { + $mod = strtolower($modifier); + $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $constraints = (array) $this->{$method}($blueprint, $col); + + foreach ($constraints as $constraint) { + $changes[] = $constraint; + } + } + } + + $columns[] = implode(', ', $this->prefixArray('alter column '.$this->wrap($column), $changes)); + } + + return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); + } + +} diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php new file mode 100755 index 000000000..f411649cf --- /dev/null +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -0,0 +1,117 @@ +getSchemaBuilder(); + $table = $blueprint->getTable(); + + $changedColumns = collect($blueprint->getChangedColumns()); + $columnNames = []; + $autoIncrementColumn = null; + + $columns = collect($schema->getColumns($table)) + ->map(function ($column) use ($blueprint, $changedColumns, &$columnNames, &$autoIncrementColumn) { + $column = $changedColumns->first(fn ($col) => $col->name === $column['name'], $column); + + if ($column instanceof Fluent) { + $name = $this->wrap($column); + $autoIncrementColumn = $column->autoIncrement ? $column->name : $autoIncrementColumn; + + if (is_null($column->virtualAs) && is_null($column->virtualAsJson) && + is_null($column->storedAs) && is_null($column->storedAsJson)) { + $columnNames[] = $name; + } + + return $this->addModifiers($name.' '.$this->getType($column), $blueprint, $column); + } else { + $name = $this->wrap($column['name']); + $autoIncrementColumn = $column['auto_increment'] ? $column['name'] : $autoIncrementColumn; + $isGenerated = ! is_null($column['generation']); + + if (! $isGenerated) { + $columnNames[] = $name; + } + + return $this->addModifiers($name.' '.$column['type'], $blueprint, + new ColumnDefinition([ + 'change' => true, + 'type' => $column['type_name'], + 'nullable' => $column['nullable'], + 'default' => $column['default'] ? new Expression($column['default']) : null, + 'autoIncrement' => $column['auto_increment'], + 'collation' => $column['collation'], + 'comment' => $column['comment'], + 'virtualAs' => $isGenerated && $column['generation']['type'] === 'virtual' + ? $column['generation']['expression'] : null, + 'storedAs' => $isGenerated && $column['generation']['type'] === 'stored' + ? $column['generation']['expression'] : null, + ]) + ); + } + })->all(); + + $foreignKeys = collect($schema->getForeignKeys($table))->map(fn ($foreignKey) => new ForeignKeyDefinition([ + 'columns' => $foreignKey['columns'], + 'on' => $foreignKey['foreign_table'], + 'references' => $foreignKey['foreign_columns'], + 'onUpdate' => $foreignKey['on_update'], + 'onDelete' => $foreignKey['on_delete'], + ]))->all(); + + [$primary, $indexes] = collect($schema->getIndexes($table))->map(fn ($index) => new IndexDefinition([ + 'name' => match (true) { + $index['primary'] => 'primary', + $index['unique'] => 'unique', + default => 'index', + }, + 'index' => $index['name'], + 'columns' => $index['columns'], + ]))->partition(fn ($index) => $index->name === 'primary'); + + $indexes = collect($indexes)->reject(fn ($index) => str_starts_with('sqlite_', $index->index))->map( + fn ($index) => $this->{'compile'.ucfirst($index->name)}($blueprint, $index) + )->all(); + + $tempTable = $this->wrap('__temp__'.$blueprint->getPrefix().$table); + $table = $this->wrapTable($blueprint); + $columnNames = implode(', ', $columnNames); + + $foreignKeyConstraintsEnabled = $connection->scalar('pragma foreign_keys'); + + return array_filter(array_merge([ + $foreignKeyConstraintsEnabled ? $this->compileDisableForeignKeyConstraints() : null, + sprintf('create table %s (%s%s%s)', + $tempTable, + implode(', ', $columns), + $this->addForeignKeys($foreignKeys), + $autoIncrementColumn ? '' : $this->addPrimaryKeys($primary->first()) + ), + sprintf('insert into %s (%s) select %s from %s', $tempTable, $columnNames, $columnNames, $table), + sprintf('drop table %s', $table), + sprintf('alter table %s rename to %s', $tempTable, $table), + ], $indexes, [$foreignKeyConstraintsEnabled ? $this->compileEnableForeignKeyConstraints() : null])); + } +} diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php new file mode 100755 index 000000000..01c885c78 --- /dev/null +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -0,0 +1,49 @@ +compileDropDefaultConstraint($blueprint, $command)]; + $oldColumns = collect($connection->getSchemaBuilder()->getColumns($blueprint->getTable())); + + foreach ($blueprint->getChangedColumns() as $column) { + $sql = sprintf('alter table %s alter column %s %s', + $this->wrapTable($blueprint), + $this->wrap($column), + $this->getType($column) + ); + + $oldColum = new Fluent($prevColumns->where('name', $name)->first()); + + foreach ($this->modifiers as $modifier) { + if (method_exists($this, $method = "modify{$modifier}")) { + $mod = strtolower($modifier); + $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $sql .= $this->{$method}($blueprint, $col); + } + } + + $changes[] = $sql; + } + + return $changes; + } +} diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php new file mode 100644 index 000000000..167637c75 --- /dev/null +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -0,0 +1,1459 @@ +create(); + $blueprint->increments('id'); + $blueprint->string('email'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $blueprint->string('email'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key, add `email` varchar(255) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->uuid('id')->primary(); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table `users` (`id` char(36) not null, primary key (`id`))', $statements[0]); + } + + public function testAutoIncrementStartingValue() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id')->startingValue(1000); + $blueprint->string('email'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); + $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]); + } + + public function testAddColumnsWithMultipleAutoIncrementStartingValue() + { + $blueprint = new Blueprint('users'); + $blueprint->id()->from(100); + $blueprint->string('name')->from(200); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertEquals([ + 'alter table `users` add `id` bigint unsigned not null auto_increment primary key, add `name` varchar(255) not null', + 'alter table `users` auto_increment = 100', + ], $statements); + } + + public function testEngineCreateTable() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $blueprint->engine('InnoDB'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn('InnoDB'); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB", $statements[0]); + } + + public function testCharsetCollationCreateTable() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $blueprint->charset('utf8mb4'); + $blueprint->collation('utf8mb4_unicode_ci'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci'", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email')->charset('utf8mb4')->collation('utf8mb4_unicode_ci'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) character set utf8mb4 collate 'utf8mb4_unicode_ci' not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); + } + + public function testBasicCreateTableWithPrefix() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $grammar = $this->getGrammar(); + $grammar->setTablePrefix('prefix_'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame('create table `prefix_users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]); + } + + public function testCreateTemporaryTable() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->temporary(); + $blueprint->increments('id'); + $blueprint->string('email'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create temporary table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]); + } + + public function testDropTable() + { + $blueprint = new Blueprint('users'); + $blueprint->drop(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table `users`', $statements[0]); + } + + public function testDropTableIfExists() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIfExists(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table if exists `users`', $statements[0]); + } + + public function testDropColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->dropColumn('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop `foo`', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropColumn(['foo', 'bar']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropColumn('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]); + } + + public function testDropPrimary() + { + $blueprint = new Blueprint('users'); + $blueprint->dropPrimary(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop primary key', $statements[0]); + } + + public function testDropUnique() + { + $blueprint = new Blueprint('users'); + $blueprint->dropUnique('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop index `foo`', $statements[0]); + } + + public function testDropIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIndex('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop index `foo`', $statements[0]); + } + + public function testDropSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->dropSpatialIndex(['coordinates']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` drop index `geo_coordinates_spatialindex`', $statements[0]); + } + + public function testDropForeign() + { + $blueprint = new Blueprint('users'); + $blueprint->dropForeign('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop foreign key `foo`', $statements[0]); + } + + public function testDropTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->dropTimestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]); + } + + public function testDropTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dropTimestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]); + } + + public function testDropMorphs() + { + $blueprint = new Blueprint('photos'); + $blueprint->dropMorphs('imageable'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('alter table `photos` drop index `photos_imageable_type_imageable_id_index`', $statements[0]); + $this->assertSame('alter table `photos` drop `imageable_type`, drop `imageable_id`', $statements[1]); + } + + public function testRenameTable() + { + $blueprint = new Blueprint('users'); + $blueprint->rename('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('rename table `users` to `foo`', $statements[0]); + } + + public function testRenameIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->renameIndex('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` rename index `foo` to `bar`', $statements[0]); + } + + public function testAddingPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->primary('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add primary key (`foo`)', $statements[0]); + } + + public function testAddingPrimaryKeyWithAlgorithm() + { + $blueprint = new Blueprint('users'); + $blueprint->primary('foo', 'bar', 'hash'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add primary key using hash(`foo`)', $statements[0]); + } + + public function testAddingUniqueKey() + { + $blueprint = new Blueprint('users'); + $blueprint->unique('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add unique `bar`(`foo`)', $statements[0]); + } + + public function testAddingIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->index(['foo', 'bar'], 'baz'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add index `baz`(`foo`, `bar`)', $statements[0]); + } + + public function testAddingIndexWithAlgorithm() + { + $blueprint = new Blueprint('users'); + $blueprint->index(['foo', 'bar'], 'baz', 'hash'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add index `baz` using hash(`foo`, `bar`)', $statements[0]); + } + + public function testAddingFulltextIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->fulltext('body'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add fulltext `users_body_fulltext`(`body`)', $statements[0]); + } + + public function testAddingSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->spatialIndex('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[0]); + } + + public function testAddingFluentSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point')->spatialIndex(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[1]); + } + + public function testAddingRawIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->rawIndex('(function(column))', 'raw_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add index `raw_index`((function(column)))', $statements[0]); + } + + public function testAddingForeignKey() + { + $blueprint = new Blueprint('users'); + $blueprint->foreign('foo_id')->references('id')->on('orders'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnDelete(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on delete cascade', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnUpdate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on update cascade', $statements[0]); + } + + public function testAddingIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key', $statements[0]); + } + + public function testAddingSmallIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->smallIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `id` smallint unsigned not null auto_increment primary key', $statements[0]); + } + + public function testAddingID() + { + $blueprint = new Blueprint('users'); + $blueprint->id(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->id('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` bigint unsigned not null auto_increment primary key', $statements[0]); + } + + public function testAddingForeignID() + { + $blueprint = new Blueprint('users'); + $foreignId = $blueprint->foreignId('foo'); + $blueprint->foreignId('company_id')->constrained(); + $blueprint->foreignId('laravel_idea_id')->constrained(); + $blueprint->foreignId('team_id')->references('id')->on('teams'); + $blueprint->foreignId('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); + $this->assertSame([ + 'alter table `users` add `foo` bigint unsigned not null, add `company_id` bigint unsigned not null, add `laravel_idea_id` bigint unsigned not null, add `team_id` bigint unsigned not null, add `team_column_id` bigint unsigned not null', + 'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)', + 'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)', + 'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)', + 'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)', + ], $statements); + } + + public function testAddingForeignIdSpecifyingIndexNameInConstraint() + { + $blueprint = new Blueprint('users'); + $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertSame([ + 'alter table `users` add `company_id` bigint unsigned not null', + 'alter table `users` add constraint `my_index` foreign key (`company_id`) references `companies` (`id`)', + ], $statements); + } + + public function testAddingBigIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->bigIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]); + } + + public function testAddingColumnInTableFirst() + { + $blueprint = new Blueprint('users'); + $blueprint->string('name')->first(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `name` varchar(255) not null first', $statements[0]); + } + + public function testAddingColumnAfterAnotherColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->string('name')->after('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `name` varchar(255) not null after `foo`', $statements[0]); + } + + public function testAddingMultipleColumnsAfterAnotherColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->after('foo', function ($blueprint) { + $blueprint->string('one'); + $blueprint->string('two'); + }); + $blueprint->string('three'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `one` varchar(255) not null after `foo`, add `two` varchar(255) not null after `one`, add `three` varchar(255) not null', $statements[0]); + } + + public function testAddingGeneratedColumn() + { + $blueprint = new Blueprint('products'); + $blueprint->integer('price'); + $blueprint->integer('discounted_virtual')->virtualAs('price - 5'); + $blueprint->integer('discounted_stored')->storedAs('price - 5'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5), add `discounted_stored` int as (price - 5) stored', $statements[0]); + + $blueprint = new Blueprint('products'); + $blueprint->integer('price'); + $blueprint->integer('discounted_virtual')->virtualAs('price - 5')->nullable(false); + $blueprint->integer('discounted_stored')->storedAs('price - 5')->nullable(false); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5) not null, add `discounted_stored` int as (price - 5) stored not null', $statements[0]); + } + + public function testAddingGeneratedColumnWithCharset() + { + $blueprint = new Blueprint('links'); + $blueprint->string('url', 2083)->charset('ascii'); + $blueprint->string('url_hash_virtual', 64)->virtualAs('sha2(url, 256)')->charset('ascii'); + $blueprint->string('url_hash_stored', 64)->storedAs('sha2(url, 256)')->charset('ascii'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `links` add `url` varchar(2083) character set ascii not null, add `url_hash_virtual` varchar(64) character set ascii as (sha2(url, 256)), add `url_hash_stored` varchar(64) character set ascii as (sha2(url, 256)) stored', $statements[0]); + } + + public function testAddingGeneratedColumnByExpression() + { + $blueprint = new Blueprint('products'); + $blueprint->integer('price'); + $blueprint->integer('discounted_virtual')->virtualAs(new Expression('price - 5')); + $blueprint->integer('discounted_stored')->storedAs(new Expression('price - 5')); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5), add `discounted_stored` int as (price - 5) stored', $statements[0]); + } + + public function testAddingInvisibleColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->string('secret', 64)->nullable(false)->invisible(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `secret` varchar(64) not null invisible', $statements[0]); + } + + public function testAddingString() + { + $blueprint = new Blueprint('users'); + $blueprint->string('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` varchar(255) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` varchar(100) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100)->nullable()->default('bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` varchar(100) null default \'bar\'', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100)->nullable()->default(new Expression('CURRENT TIMESTAMP')); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` varchar(100) null default CURRENT TIMESTAMP', $statements[0]); + } + + public function testAddingText() + { + $blueprint = new Blueprint('users'); + $blueprint->text('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` text not null', $statements[0]); + } + + public function testAddingBigInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` bigint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` bigint not null auto_increment primary key', $statements[0]); + } + + public function testAddingInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->integer('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` int not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->integer('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` int not null auto_increment primary key', $statements[0]); + } + + public function testAddingIncrementsWithStartingValues() + { + $blueprint = new Blueprint('users'); + $blueprint->id()->startingValue(1000); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]); + $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]); + } + + public function testAddingMediumInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` mediumint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` mediumint not null auto_increment primary key', $statements[0]); + } + + public function testAddingSmallInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` smallint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` smallint not null auto_increment primary key', $statements[0]); + } + + public function testAddingTinyInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` tinyint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` tinyint not null auto_increment primary key', $statements[0]); + } + + public function testAddingFloat() + { + $blueprint = new Blueprint('users'); + $blueprint->float('foo', 5); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` float(5) not null', $statements[0]); + } + + public function testAddingDouble() + { + $blueprint = new Blueprint('users'); + $blueprint->double('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` double not null', $statements[0]); + } + + public function testAddingDecimal() + { + $blueprint = new Blueprint('users'); + $blueprint->decimal('foo', 5, 2); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` decimal(5, 2) not null', $statements[0]); + } + + public function testAddingBoolean() + { + $blueprint = new Blueprint('users'); + $blueprint->boolean('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` tinyint(1) not null', $statements[0]); + } + + public function testAddingEnum() + { + $blueprint = new Blueprint('users'); + $blueprint->enum('role', ['member', 'admin']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `role` enum(\'member\', \'admin\') not null', $statements[0]); + } + + public function testAddingSet() + { + $blueprint = new Blueprint('users'); + $blueprint->set('role', ['member', 'admin']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `role` set(\'member\', \'admin\') not null', $statements[0]); + } + + public function testAddingJson() + { + $blueprint = new Blueprint('users'); + $blueprint->json('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` json not null', $statements[0]); + } + + public function testAddingJsonb() + { + $blueprint = new Blueprint('users'); + $blueprint->jsonb('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` json not null', $statements[0]); + } + + public function testAddingDate() + { + $blueprint = new Blueprint('users'); + $blueprint->date('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` date not null', $statements[0]); + } + + public function testAddingYear() + { + $blueprint = new Blueprint('users'); + $blueprint->year('birth_year'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `birth_year` year not null', $statements[0]); + } + + public function testAddingDateTime() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dateTime('foo', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]); + } + + public function testAddingDateTimeWithDefaultCurrent() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('foo')->useCurrent(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP', $statements[0]); + } + + public function testAddingDateTimeWithOnUpdateCurrent() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('foo')->useCurrentOnUpdate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime not null on update CURRENT_TIMESTAMP', $statements[0]); + } + + public function testAddingDateTimeWithDefaultCurrentAndOnUpdateCurrent() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('foo')->useCurrent()->useCurrentOnUpdate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP', $statements[0]); + } + + public function testAddingDateTimeWithDefaultCurrentOnUpdateCurrentAndPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('foo', 3)->useCurrent()->useCurrentOnUpdate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime(3) not null default CURRENT_TIMESTAMP(3) on update CURRENT_TIMESTAMP(3)', $statements[0]); + } + + public function testAddingDateTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('foo', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]); + } + + public function testAddingTime() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]); + } + + public function testAddingTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]); + } + + public function testAddingTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]); + } + + public function testAddingTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]); + } + + public function testAddingTimestamp() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]); + } + + public function testAddingTimestampWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]); + } + + public function testAddingTimestampWithDefault() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at')->default('2015-07-22 11:43:17'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame("alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'", $statements[0]); + } + + public function testAddingTimestampWithDefaultCurrentSpecifyingPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1)->useCurrent(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1)', $statements[0]); + } + + public function testAddingTimestampWithOnUpdateCurrentSpecifyingPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1)->useCurrentOnUpdate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp(1) not null on update CURRENT_TIMESTAMP(1)', $statements[0]); + } + + public function testAddingTimestampWithDefaultCurrentAndOnUpdateCurrentSpecifyingPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1)->useCurrent()->useCurrentOnUpdate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1) on update CURRENT_TIMESTAMP(1)', $statements[0]); + } + + public function testAddingTimestampTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]); + } + + public function testAddingTimestampTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]); + } + + public function testAddingTimeStampTzWithDefault() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at')->default('2015-07-22 11:43:17'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame("alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'", $statements[0]); + } + + public function testAddingTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp null, add `updated_at` timestamp null', $statements[0]); + } + + public function testAddingTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `created_at` timestamp null, add `updated_at` timestamp null', $statements[0]); + } + + public function testAddingRememberToken() + { + $blueprint = new Blueprint('users'); + $blueprint->rememberToken(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `remember_token` varchar(100) null', $statements[0]); + } + + public function testAddingBinary() + { + $blueprint = new Blueprint('users'); + $blueprint->binary('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` blob not null', $statements[0]); + } + + public function testAddingUuid() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` char(36) not null', $statements[0]); + } + + public function testAddingUuidDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `uuid` char(36) not null', $statements[0]); + } + + public function testAddingForeignUuid() + { + $blueprint = new Blueprint('users'); + $foreignUuid = $blueprint->foreignUuid('foo'); + $blueprint->foreignUuid('company_id')->constrained(); + $blueprint->foreignUuid('laravel_idea_id')->constrained(); + $blueprint->foreignUuid('team_id')->references('id')->on('teams'); + $blueprint->foreignUuid('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid); + $this->assertSame([ + 'alter table `users` add `foo` char(36) not null, add `company_id` char(36) not null, add `laravel_idea_id` char(36) not null, add `team_id` char(36) not null, add `team_column_id` char(36) not null', + 'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)', + 'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)', + 'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)', + 'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)', + ], $statements); + } + + public function testAddingIpAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` varchar(45) not null', $statements[0]); + } + + public function testAddingIpAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `ip_address` varchar(45) not null', $statements[0]); + } + + public function testAddingMacAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `foo` varchar(17) not null', $statements[0]); + } + + public function testAddingMacAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `mac_address` varchar(17) not null', $statements[0]); + } + + public function testAddingGeometry() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` geometry not null', $statements[0]); + } + + public function testAddingGeography() + { + $blueprint = new Blueprint('geo'); + $blueprint->geography('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` geometry srid 4326 not null', $statements[0]); + } + + public function testAddingPoint() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` point not null', $statements[0]); + } + + public function testAddingPointWithSrid() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point', 4326); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` point srid 4326 not null', $statements[0]); + } + + public function testAddingPointWithSridColumn() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point', 4326)->after('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` point srid 4326 not null after `id`', $statements[0]); + } + + public function testAddingLineString() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'linestring'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` linestring not null', $statements[0]); + } + + public function testAddingPolygon() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'polygon'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` polygon not null', $statements[0]); + } + + public function testAddingGeometryCollection() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'geometrycollection'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` geometrycollection not null', $statements[0]); + } + + public function testAddingMultiPoint() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'multipoint'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` multipoint not null', $statements[0]); + } + + public function testAddingMultiLineString() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'multilinestring'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` multilinestring not null', $statements[0]); + } + + public function testAddingMultiPolygon() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'multipolygon'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `geo` add `coordinates` multipolygon not null', $statements[0]); + } + + public function testAddingComment() + { + $blueprint = new Blueprint('users'); + $blueprint->string('foo')->comment("Escape ' when using words like it's"); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("alter table `users` add `foo` varchar(255) not null comment 'Escape \\' when using words like it\\'s'", $statements[0]); + } + + public function testCreateDatabase() + { + $connection = $this->getConnection(); + $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_foo'); + $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_foo'); + + $statement = $this->getGrammar()->compileCreateDatabase('my_database_a', $connection); + + $this->assertSame( + 'create database `my_database_a` default character set `utf8mb4_foo` default collate `utf8mb4_unicode_ci_foo`', + $statement + ); + + $connection = $this->getConnection(); + $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_bar'); + $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_bar'); + + $statement = $this->getGrammar()->compileCreateDatabase('my_database_b', $connection); + + $this->assertSame( + 'create database `my_database_b` default character set `utf8mb4_bar` default collate `utf8mb4_unicode_ci_bar`', + $statement + ); + } + + public function testCreateTableWithVirtualAsColumn() + { + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_column'); + $blueprint->string('my_other_column')->virtualAs('my_column'); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column)) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\"'))))", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\".\"nested\"'))))", $statements[0]); + } + + public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_json_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"foo\"[0][1]'))))", $statements[0]); + } + + public function testCreateTableWithStoredAsColumn() + { + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_column'); + $blueprint->string('my_other_column')->storedAs('my_column'); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column) stored) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\"'))) stored)", $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\".\"nested\"'))) stored)", $statements[0]); + } + + public function testDropDatabaseIfExists() + { + $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a'); + + $this->assertSame( + 'drop database if exists `my_database_a`', + $statement + ); + + $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b'); + + $this->assertSame( + 'drop database if exists `my_database_b`', + $statement + ); + } + + public function testDropAllTables() + { + $statement = $this->getGrammar()->compileDropAllTables(['alpha', 'beta', 'gamma']); + + $this->assertSame('drop table `alpha`,`beta`,`gamma`', $statement); + } + + public function testDropAllViews() + { + $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']); + + $this->assertSame('drop view `alpha`,`beta`,`gamma`', $statement); + } + + public function testGrammarsAreMacroable() + { + // compileReplace macro. + $this->getGrammar()::macro('compileReplace', function () { + return true; + }); + + $c = $this->getGrammar()::compileReplace(); + + $this->assertTrue($c); + } + + protected function getConnection() + { + return m::mock(Connection::class); + } + + public function getGrammar() + { + return new MySqlGrammar; + } +} diff --git a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php new file mode 100644 index 000000000..96b1222bf --- /dev/null +++ b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php @@ -0,0 +1,1238 @@ +create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $blueprint->string('name')->collation('nb_NO.utf8'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("id" serial not null primary key, "email" varchar(255) not null, "name" varchar(255) collate "nb_NO.utf8" not null)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" serial not null primary key, add column "email" varchar(255) not null', $statements[0]); + } + + public function testCreateTableWithAutoIncrementStartingValue() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id')->startingValue(1000); + $blueprint->string('email'); + $blueprint->string('name')->collation('nb_NO.utf8'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('create table "users" ("id" serial not null primary key, "email" varchar(255) not null, "name" varchar(255) collate "nb_NO.utf8" not null)', $statements[0]); + $this->assertSame('alter sequence users_id_seq restart with 1000', $statements[1]); + } + + public function testAddColumnsWithMultipleAutoIncrementStartingValue() + { + $blueprint = new Blueprint('users'); + $blueprint->id()->from(100); + $blueprint->increments('code')->from(200); + $blueprint->string('name')->from(300); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertEquals([ + 'alter table "users" add column "id" bigserial not null primary key, add column "code" serial not null primary key, add column "name" varchar(255) not null', + 'alter sequence users_id_seq restart with 100', + 'alter sequence users_code_seq restart with 200', + ], $statements); + } + + public function testCreateTableAndCommentColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email')->comment('my first comment'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('create table "users" ("id" serial not null primary key, "email" varchar(255) not null)', $statements[0]); + $this->assertSame('comment on column "users"."email" is \'my first comment\'', $statements[1]); + } + + public function testCreateTemporaryTable() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->temporary(); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create temporary table "users" ("id" serial not null primary key, "email" varchar(255) not null)', $statements[0]); + } + + public function testDropTable() + { + $blueprint = new Blueprint('users'); + $blueprint->drop(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table "users"', $statements[0]); + } + + public function testDropTableIfExists() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIfExists(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table if exists "users"', $statements[0]); + } + + public function testDropColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->dropColumn('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop column "foo"', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropColumn(['foo', 'bar']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop column "foo", drop column "bar"', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropColumn('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop column "foo", drop column "bar"', $statements[0]); + } + + public function testDropPrimary() + { + $blueprint = new Blueprint('users'); + $blueprint->dropPrimary(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop constraint "users_pkey"', $statements[0]); + } + + public function testDropUnique() + { + $blueprint = new Blueprint('users'); + $blueprint->dropUnique('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); + } + + public function testDropIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIndex('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "foo"', $statements[0]); + } + + public function testDropSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->dropSpatialIndex(['coordinates']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "geo_coordinates_spatialindex"', $statements[0]); + } + + public function testDropForeign() + { + $blueprint = new Blueprint('users'); + $blueprint->dropForeign('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); + } + + public function testDropTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->dropTimestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop column "created_at", drop column "updated_at"', $statements[0]); + } + + public function testDropTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dropTimestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop column "created_at", drop column "updated_at"', $statements[0]); + } + + public function testDropMorphs() + { + $blueprint = new Blueprint('photos'); + $blueprint->dropMorphs('imageable'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('drop index "photos_imageable_type_imageable_id_index"', $statements[0]); + $this->assertSame('alter table "photos" drop column "imageable_type", drop column "imageable_id"', $statements[1]); + } + + public function testRenameTable() + { + $blueprint = new Blueprint('users'); + $blueprint->rename('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" rename to "foo"', $statements[0]); + } + + public function testRenameIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->renameIndex('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter index "foo" rename to "bar"', $statements[0]); + } + + public function testAddingPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->primary('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add primary key ("foo")', $statements[0]); + } + + public function testAddingUniqueKey() + { + $blueprint = new Blueprint('users'); + $blueprint->unique('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add constraint "bar" unique ("foo")', $statements[0]); + } + + public function testAddingIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->index(['foo', 'bar'], 'baz'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "baz" on "users" ("foo", "bar")', $statements[0]); + } + + public function testAddingIndexWithAlgorithm() + { + $blueprint = new Blueprint('users'); + $blueprint->index(['foo', 'bar'], 'baz', 'hash'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "baz" on "users" using hash ("foo", "bar")', $statements[0]); + } + + public function testAddingFulltextIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->fulltext('body'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "users_body_fulltext" on "users" using gin ((to_tsvector(\'english\', "body")))', $statements[0]); + } + + public function testAddingFulltextIndexMultipleColumns() + { + $blueprint = new Blueprint('users'); + $blueprint->fulltext(['body', 'title']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "users_body_title_fulltext" on "users" using gin ((to_tsvector(\'english\', "body") || to_tsvector(\'english\', "title")))', $statements[0]); + } + + public function testAddingFulltextIndexWithLanguage() + { + $blueprint = new Blueprint('users'); + $blueprint->fulltext('body')->language('spanish'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "users_body_fulltext" on "users" using gin ((to_tsvector(\'spanish\', "body")))', $statements[0]); + } + + public function testAddingFulltextIndexWithFluency() + { + $blueprint = new Blueprint('users'); + $blueprint->string('body')->fulltext(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('create index "users_body_fulltext" on "users" using gin ((to_tsvector(\'english\', "body")))', $statements[1]); + } + + public function testAddingSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->spatialIndex('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "geo_coordinates_spatialindex" on "geo" using gist ("coordinates")', $statements[0]); + } + + public function testAddingFluentSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point')->spatialIndex(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('create index "geo_coordinates_spatialindex" on "geo" using gist ("coordinates")', $statements[1]); + } + + public function testAddingRawIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->rawIndex('(function(column))', 'raw_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "raw_index" on "users" ((function(column)))', $statements[0]); + } + + public function testAddingIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" serial not null primary key', $statements[0]); + } + + public function testAddingSmallIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->smallIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" smallserial not null primary key', $statements[0]); + } + + public function testAddingMediumIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" serial not null primary key', $statements[0]); + } + + public function testAddingID() + { + $blueprint = new Blueprint('users'); + $blueprint->id(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" bigserial not null primary key', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->id('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" bigserial not null primary key', $statements[0]); + } + + public function testAddingForeignID() + { + $blueprint = new Blueprint('users'); + $foreignId = $blueprint->foreignId('foo'); + $blueprint->foreignId('company_id')->constrained(); + $blueprint->foreignId('laravel_idea_id')->constrained(); + $blueprint->foreignId('team_id')->references('id')->on('teams'); + $blueprint->foreignId('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); + $this->assertSame([ + 'alter table "users" add column "foo" bigint not null, add column "company_id" bigint not null, add column "laravel_idea_id" bigint not null, add column "team_id" bigint not null, add column "team_column_id" bigint not null', + 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', + 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', + 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', + 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', + ], $statements); + } + + public function testAddingForeignIdSpecifyingIndexNameInConstraint() + { + $blueprint = new Blueprint('users'); + $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertSame([ + 'alter table "users" add column "company_id" bigint not null', + 'alter table "users" add constraint "my_index" foreign key ("company_id") references "companies" ("id")', + ], $statements); + } + + public function testAddingBigIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->bigIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" bigserial not null primary key', $statements[0]); + } + + public function testAddingString() + { + $blueprint = new Blueprint('users'); + $blueprint->string('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar(255) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar(100) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100)->nullable()->default('bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar(100) null default \'bar\'', $statements[0]); + } + + public function testAddingStringWithoutLengthLimit() + { + $blueprint = new Blueprint('users'); + $blueprint->string('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar(255) not null', $statements[0]); + + Builder::$defaultStringLength = null; + + $blueprint = new Blueprint('users'); + $blueprint->string('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + try { + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); + } finally { + Builder::$defaultStringLength = 255; + } + } + + public function testAddingCharWithoutLengthLimit() + { + $blueprint = new Blueprint('users'); + $blueprint->char('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" char(255) not null', $statements[0]); + + Builder::$defaultStringLength = null; + + $blueprint = new Blueprint('users'); + $blueprint->char('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + try { + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" char not null', $statements[0]); + } finally { + Builder::$defaultStringLength = 255; + } + } + + public function testAddingText() + { + $blueprint = new Blueprint('users'); + $blueprint->text('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); + } + + public function testAddingBigInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" bigint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" bigserial not null primary key', $statements[0]); + } + + public function testAddingInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->integer('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->integer('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" serial not null primary key', $statements[0]); + } + + public function testAddingMediumInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" serial not null primary key', $statements[0]); + } + + public function testAddingTinyInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" smallint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" smallserial not null primary key', $statements[0]); + } + + public function testAddingSmallInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" smallint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" smallserial not null primary key', $statements[0]); + } + + public function testAddingFloat() + { + $blueprint = new Blueprint('users'); + $blueprint->float('foo', 5); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" float(5) not null', $statements[0]); + } + + public function testAddingDouble() + { + $blueprint = new Blueprint('users'); + $blueprint->double('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" double precision not null', $statements[0]); + } + + public function testAddingDecimal() + { + $blueprint = new Blueprint('users'); + $blueprint->decimal('foo', 5, 2); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" decimal(5, 2) not null', $statements[0]); + } + + public function testAddingBoolean() + { + $blueprint = new Blueprint('users'); + $blueprint->boolean('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" boolean not null', $statements[0]); + } + + public function testAddingEnum() + { + $blueprint = new Blueprint('users'); + $blueprint->enum('role', ['member', 'admin']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "role" varchar(255) check ("role" in (\'member\', \'admin\')) not null', $statements[0]); + } + + public function testAddingDate() + { + $blueprint = new Blueprint('users'); + $blueprint->date('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" date not null', $statements[0]); + } + + public function testAddingYear() + { + $blueprint = new Blueprint('users'); + $blueprint->year('birth_year'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "birth_year" integer not null', $statements[0]); + } + + public function testAddingJson() + { + $blueprint = new Blueprint('users'); + $blueprint->json('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" json not null', $statements[0]); + } + + public function testAddingJsonb() + { + $blueprint = new Blueprint('users'); + $blueprint->jsonb('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" jsonb not null', $statements[0]); + } + + public function testAddingDateTime() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(0) without time zone not null', $statements[0]); + } + + public function testAddingDateTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(1) without time zone not null', $statements[0]); + } + + public function testAddingDateTimeWithNullPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at', null); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp without time zone not null', $statements[0]); + } + + public function testAddingDateTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(0) with time zone not null', $statements[0]); + } + + public function testAddingDateTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(1) with time zone not null', $statements[0]); + } + + public function testAddingDateTimeTzWithNullPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('created_at', null); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp with time zone not null', $statements[0]); + } + + public function testAddingTime() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time(0) without time zone not null', $statements[0]); + } + + public function testAddingTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time(1) without time zone not null', $statements[0]); + } + + public function testAddingTimeWithNullPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at', null); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time without time zone not null', $statements[0]); + } + + public function testAddingTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time(0) with time zone not null', $statements[0]); + } + + public function testAddingTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time(1) with time zone not null', $statements[0]); + } + + public function testAddingTimeTzWithNullPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at', null); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time with time zone not null', $statements[0]); + } + + public function testAddingTimestamp() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(0) without time zone not null', $statements[0]); + } + + public function testAddingTimestampWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(1) without time zone not null', $statements[0]); + } + + public function testAddingTimestampWithNullPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', null); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp without time zone not null', $statements[0]); + } + + public function testAddingTimestampTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(0) with time zone not null', $statements[0]); + } + + public function testAddingTimestampTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(1) with time zone not null', $statements[0]); + } + + public function testAddingTimestampTzWithNullPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at', null); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp with time zone not null', $statements[0]); + } + + public function testAddingTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(0) without time zone null, add column "updated_at" timestamp(0) without time zone null', $statements[0]); + } + + public function testAddingTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" timestamp(0) with time zone null, add column "updated_at" timestamp(0) with time zone null', $statements[0]); + } + + public function testAddingBinary() + { + $blueprint = new Blueprint('users'); + $blueprint->binary('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" bytea not null', $statements[0]); + } + + public function testAddingUuid() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" uuid not null', $statements[0]); + } + + public function testAddingUuidDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "uuid" uuid not null', $statements[0]); + } + + public function testAddingForeignUuid() + { + $blueprint = new Blueprint('users'); + $foreignUuid = $blueprint->foreignUuid('foo'); + $blueprint->foreignUuid('company_id')->constrained(); + $blueprint->foreignUuid('laravel_idea_id')->constrained(); + $blueprint->foreignUuid('team_id')->references('id')->on('teams'); + $blueprint->foreignUuid('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid); + $this->assertSame([ + 'alter table "users" add column "foo" uuid not null, add column "company_id" uuid not null, add column "laravel_idea_id" uuid not null, add column "team_id" uuid not null, add column "team_column_id" uuid not null', + 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', + 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', + 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', + 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', + ], $statements); + } + + public function testAddingGeneratedAs() + { + $blueprint = new Blueprint('users'); + $blueprint->increments('foo')->generatedAs(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null generated by default as identity primary key', $statements[0]); + // With always modifier + $blueprint = new Blueprint('users'); + $blueprint->increments('foo')->generatedAs()->always(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null generated always as identity primary key', $statements[0]); + // With sequence options + $blueprint = new Blueprint('users'); + $blueprint->increments('foo')->generatedAs('increment by 10 start with 100'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null generated by default as identity (increment by 10 start with 100) primary key', $statements[0]); + // Not a primary key + $blueprint = new Blueprint('users'); + $blueprint->integer('foo')->generatedAs(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null generated by default as identity', $statements[0]); + } + + public function testAddingVirtualAs() + { + $blueprint = new Blueprint('users'); + $blueprint->integer('foo')->nullable(); + $blueprint->boolean('bar')->virtualAs('foo is not null'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->integer('foo')->nullable(); + $blueprint->boolean('bar')->virtualAs(new Expression('foo is not null')); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null)', $statements[0]); + } + + public function testAddingStoredAs() + { + $blueprint = new Blueprint('users'); + $blueprint->integer('foo')->nullable(); + $blueprint->boolean('bar')->storedAs('foo is not null'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null) stored', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->integer('foo')->nullable(); + $blueprint->boolean('bar')->storedAs(new Expression('foo is not null')); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null) stored', $statements[0]); + } + + public function testAddingIpAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" inet not null', $statements[0]); + } + + public function testAddingIpAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "ip_address" inet not null', $statements[0]); + } + + public function testAddingMacAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" macaddr not null', $statements[0]); + } + + public function testAddingMacAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "mac_address" macaddr not null', $statements[0]); + } + + public function testCompileForeign() + { + $blueprint = new Blueprint('users'); + $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade deferrable', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable(false)->initiallyImmediate(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade not deferrable', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable()->initiallyImmediate(false); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade deferrable initially deferred', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable()->notValid(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade deferrable not valid', $statements[0]); + } + + public function testAddingGeometry() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry not null', $statements[0]); + } + + public function testAddingGeography() + { + $blueprint = new Blueprint('geo'); + $blueprint->geography('coordinates', 'pointzm', 4269); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geography(pointzm,4269) not null', $statements[0]); + } + + public function testAddingPoint() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(point) not null', $statements[0]); + } + + public function testAddingPointWithSrid() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point', 4269); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(point,4269) not null', $statements[0]); + } + + public function testAddingLineString() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'linestring'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(linestring) not null', $statements[0]); + } + + public function testAddingPolygon() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'polygon'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(polygon) not null', $statements[0]); + } + + public function testAddingGeometryCollection() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'geometrycollection'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(geometrycollection) not null', $statements[0]); + } + + public function testAddingMultiPoint() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'multipoint'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(multipoint) not null', $statements[0]); + } + + public function testAddingMultiLineString() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'multilinestring'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(multilinestring) not null', $statements[0]); + } + + public function testAddingMultiPolygon() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'multipolygon'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry(multipolygon) not null', $statements[0]); + } + + public function testCreateDatabase() + { + $connection = $this->getConnection(); + $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8_foo'); + $statement = $this->getGrammar()->compileCreateDatabase('my_database_a', $connection); + + $this->assertSame( + 'create database "my_database_a" encoding "utf8_foo"', + $statement + ); + + $connection = $this->getConnection(); + $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8_bar'); + $statement = $this->getGrammar()->compileCreateDatabase('my_database_b', $connection); + + $this->assertSame( + 'create database "my_database_b" encoding "utf8_bar"', + $statement + ); + } + + public function testDropDatabaseIfExists() + { + $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a'); + + $this->assertSame( + 'drop database if exists "my_database_a"', + $statement + ); + + $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b'); + + $this->assertSame( + 'drop database if exists "my_database_b"', + $statement + ); + } + + public function testDropAllTablesEscapesTableNames() + { + $statement = $this->getGrammar()->compileDropAllTables(['alpha', 'beta', 'gamma']); + + $this->assertSame('drop table "alpha","beta","gamma" cascade', $statement); + } + + public function testDropAllViewsEscapesTableNames() + { + $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']); + + $this->assertSame('drop view "alpha","beta","gamma" cascade', $statement); + } + + public function testDropAllTypesEscapesTableNames() + { + $statement = $this->getGrammar()->compileDropAllTypes(['alpha', 'beta', 'gamma']); + + $this->assertSame('drop type "alpha","beta","gamma" cascade', $statement); + } + + protected function getConnection() + { + return m::mock(Connection::class); + } + + public function getGrammar() + { + return new PostgresGrammar; + } + + public function testGrammarsAreMacroable() + { + // compileReplace macro. + $this->getGrammar()::macro('compileReplace', function () { + return true; + }); + + $c = $this->getGrammar()::compileReplace(); + + $this->assertTrue($c); + } +} diff --git a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php new file mode 100644 index 000000000..a120e88bf --- /dev/null +++ b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php @@ -0,0 +1,937 @@ +create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("id" integer primary key autoincrement not null, "email" varchar not null)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $expected = [ + 'alter table "users" add column "id" integer primary key autoincrement not null', + 'alter table "users" add column "email" varchar not null', + ]; + $this->assertEquals($expected, $statements); + } + + public function testCreateTemporaryTable() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->temporary(); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create temporary table "users" ("id" integer primary key autoincrement not null, "email" varchar not null)', $statements[0]); + } + + public function testDropTable() + { + $blueprint = new Blueprint('users'); + $blueprint->drop(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table "users"', $statements[0]); + } + + public function testDropTableIfExists() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIfExists(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table if exists "users"', $statements[0]); + } + + public function testDropUnique() + { + $blueprint = new Blueprint('users'); + $blueprint->dropUnique('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "foo"', $statements[0]); + } + + public function testDropIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIndex('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "foo"', $statements[0]); + } + + public function testDropColumn() + { + $db = new Manager; + + $db->addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => 'prefix_', + ]); + + $schema = $db->getConnection()->getSchemaBuilder(); + + $schema->create('users', function (Blueprint $table) { + $table->string('email'); + $table->string('name'); + }); + + $this->assertTrue($schema->hasTable('users')); + $this->assertTrue($schema->hasColumn('users', 'name')); + + $schema->table('users', function (Blueprint $table) { + $table->dropColumn('name'); + }); + + $this->assertFalse($schema->hasColumn('users', 'name')); + } + + public function testDropSpatialIndex() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The database driver in use does not support spatial indexes.'); + + $blueprint = new Blueprint('geo'); + $blueprint->dropSpatialIndex(['coordinates']); + $blueprint->toSql($this->getConnection(), $this->getGrammar()); + } + + public function testRenameTable() + { + $blueprint = new Blueprint('users'); + $blueprint->rename('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" rename to "foo"', $statements[0]); + } + + public function testRenameIndex() + { + $db = new Manager; + + $db->addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => 'prefix_', + ]); + + $schema = $db->getConnection()->getSchemaBuilder(); + + $schema->create('users', function (Blueprint $table) { + $table->string('name'); + $table->string('email'); + }); + + $schema->table('users', function (Blueprint $table) { + $table->index(['name', 'email'], 'index1'); + }); + + $indexes = $schema->getIndexListing('users'); + + $this->assertContains('index1', $indexes); + $this->assertNotContains('index2', $indexes); + + $schema->table('users', function (Blueprint $table) { + $table->renameIndex('index1', 'index2'); + }); + + $this->assertFalse($schema->hasIndex('users', 'index1')); + $this->assertTrue(collect($schema->getIndexes('users'))->contains( + fn ($index) => $index['name'] === 'index2' && $index['columns'] === ['name', 'email'] + )); + } + + public function testAddingPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('foo')->primary(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("foo" varchar not null, primary key ("foo"))', $statements[0]); + } + + public function testAddingForeignKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('foo')->primary(); + $blueprint->string('order_id'); + $blueprint->foreign('order_id')->references('id')->on('orders'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("foo" varchar not null, "order_id" varchar not null, foreign key("order_id") references "orders"("id"), primary key ("foo"))', $statements[0]); + } + + public function testAddingUniqueKey() + { + $blueprint = new Blueprint('users'); + $blueprint->unique('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create unique index "bar" on "users" ("foo")', $statements[0]); + } + + public function testAddingIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->index(['foo', 'bar'], 'baz'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "baz" on "users" ("foo", "bar")', $statements[0]); + } + + public function testAddingSpatialIndex() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The database driver in use does not support spatial indexes.'); + + $blueprint = new Blueprint('geo'); + $blueprint->spatialIndex('coordinates'); + $blueprint->toSql($this->getConnection(), $this->getGrammar()); + } + + public function testAddingFluentSpatialIndex() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The database driver in use does not support spatial indexes.'); + + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates')->spatialIndex(); + $blueprint->toSql($this->getConnection(), $this->getGrammar()); + } + + public function testAddingRawIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->rawIndex('(function(column))', 'raw_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "raw_index" on "users" ((function(column)))', $statements[0]); + } + + public function testAddingIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingSmallIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->smallIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingMediumIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingID() + { + $blueprint = new Blueprint('users'); + $blueprint->id(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->id('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingForeignID() + { + $blueprint = new Blueprint('users'); + $foreignId = $blueprint->foreignId('foo'); + $blueprint->foreignId('company_id')->constrained(); + $blueprint->foreignId('laravel_idea_id')->constrained(); + $blueprint->foreignId('team_id')->references('id')->on('teams'); + $blueprint->foreignId('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); + $this->assertSame([ + 'alter table "users" add column "foo" integer not null', + 'alter table "users" add column "company_id" integer not null', + 'alter table "users" add column "laravel_idea_id" integer not null', + 'alter table "users" add column "team_id" integer not null', + 'alter table "users" add column "team_column_id" integer not null', + ], $statements); + } + + public function testAddingForeignIdSpecifyingIndexNameInConstraint() + { + $blueprint = new Blueprint('users'); + $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertSame([ + 'alter table "users" add column "company_id" integer not null', + ], $statements); + } + + public function testAddingBigIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->bigIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingString() + { + $blueprint = new Blueprint('users'); + $blueprint->string('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100)->nullable()->default('bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar default \'bar\'', $statements[0]); + } + + public function testAddingText() + { + $blueprint = new Blueprint('users'); + $blueprint->text('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); + } + + public function testAddingBigInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->integer('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->integer('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingMediumInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingTinyInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingSmallInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); + } + + public function testAddingFloat() + { + $blueprint = new Blueprint('users'); + $blueprint->float('foo', 5); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" float not null', $statements[0]); + } + + public function testAddingDouble() + { + $blueprint = new Blueprint('users'); + $blueprint->double('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" double not null', $statements[0]); + } + + public function testAddingDecimal() + { + $blueprint = new Blueprint('users'); + $blueprint->decimal('foo', 5, 2); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" numeric not null', $statements[0]); + } + + public function testAddingBoolean() + { + $blueprint = new Blueprint('users'); + $blueprint->boolean('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" tinyint(1) not null', $statements[0]); + } + + public function testAddingEnum() + { + $blueprint = new Blueprint('users'); + $blueprint->enum('role', ['member', 'admin']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "role" varchar check ("role" in (\'member\', \'admin\')) not null', $statements[0]); + } + + public function testAddingJson() + { + $blueprint = new Blueprint('users'); + $blueprint->json('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); + } + + public function testAddingJsonb() + { + $blueprint = new Blueprint('users'); + $blueprint->jsonb('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); + } + + public function testAddingDate() + { + $blueprint = new Blueprint('users'); + $blueprint->date('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" date not null', $statements[0]); + } + + public function testAddingYear() + { + $blueprint = new Blueprint('users'); + $blueprint->year('birth_year'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "birth_year" integer not null', $statements[0]); + } + + public function testAddingDateTime() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingDateTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingDateTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingDateTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingTime() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); + } + + public function testAddingTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); + } + + public function testAddingTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); + } + + public function testAddingTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); + } + + public function testAddingTimestamp() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingTimestampWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingTimestampTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingTimestampTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); + } + + public function testAddingTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(2, $statements); + $this->assertEquals([ + 'alter table "users" add column "created_at" datetime', + 'alter table "users" add column "updated_at" datetime', + ], $statements); + } + + public function testAddingTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(2, $statements); + $this->assertEquals([ + 'alter table "users" add column "created_at" datetime', + 'alter table "users" add column "updated_at" datetime', + ], $statements); + } + + public function testAddingRememberToken() + { + $blueprint = new Blueprint('users'); + $blueprint->rememberToken(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "remember_token" varchar', $statements[0]); + } + + public function testAddingBinary() + { + $blueprint = new Blueprint('users'); + $blueprint->binary('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" blob not null', $statements[0]); + } + + public function testAddingUuid() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); + } + + public function testAddingUuidDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "uuid" varchar not null', $statements[0]); + } + + public function testAddingForeignUuid() + { + $blueprint = new Blueprint('users'); + $foreignUuid = $blueprint->foreignUuid('foo'); + $blueprint->foreignUuid('company_id')->constrained(); + $blueprint->foreignUuid('laravel_idea_id')->constrained(); + $blueprint->foreignUuid('team_id')->references('id')->on('teams'); + $blueprint->foreignUuid('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid); + $this->assertSame([ + 'alter table "users" add column "foo" varchar not null', + 'alter table "users" add column "company_id" varchar not null', + 'alter table "users" add column "laravel_idea_id" varchar not null', + 'alter table "users" add column "team_id" varchar not null', + 'alter table "users" add column "team_column_id" varchar not null', + ], $statements); + } + + public function testAddingIpAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); + } + + public function testAddingIpAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "ip_address" varchar not null', $statements[0]); + } + + public function testAddingMacAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); + } + + public function testAddingMacAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "mac_address" varchar not null', $statements[0]); + } + + public function testAddingGeometry() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add column "coordinates" geometry not null', $statements[0]); + } + + public function testAddingGeneratedColumn() + { + $blueprint = new Blueprint('products'); + $blueprint->create(); + $blueprint->integer('price'); + $blueprint->integer('discounted_virtual')->virtualAs('"price" - 5'); + $blueprint->integer('discounted_stored')->storedAs('"price" - 5'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "products" ("price" integer not null, "discounted_virtual" integer as ("price" - 5), "discounted_stored" integer as ("price" - 5) stored)', $statements[0]); + + $blueprint = new Blueprint('products'); + $blueprint->integer('price'); + $blueprint->integer('discounted_virtual')->virtualAs('"price" - 5')->nullable(false); + $blueprint->integer('discounted_stored')->storedAs('"price" - 5')->nullable(false); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(3, $statements); + $expected = [ + 'alter table "products" add column "price" integer not null', + 'alter table "products" add column "discounted_virtual" integer not null as ("price" - 5)', + 'alter table "products" add column "discounted_stored" integer not null as ("price" - 5) stored', + ]; + $this->assertSame($expected, $statements); + } + + public function testAddingGeneratedColumnByExpression() + { + $blueprint = new Blueprint('products'); + $blueprint->create(); + $blueprint->integer('price'); + $blueprint->integer('discounted_virtual')->virtualAs(new Expression('"price" - 5')); + $blueprint->integer('discounted_stored')->storedAs(new Expression('"price" - 5')); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "products" ("price" integer not null, "discounted_virtual" integer as ("price" - 5), "discounted_stored" integer as ("price" - 5) stored)', $statements[0]); + } + + public function testGrammarsAreMacroable() + { + // compileReplace macro. + $this->getGrammar()::macro('compileReplace', function () { + return true; + }); + + $c = $this->getGrammar()::compileReplace(); + + $this->assertTrue($c); + } + + public function testCreateTableWithVirtualAsColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_column'); + $blueprint->string('my_other_column')->virtualAs('my_column'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("my_column" varchar not null, "my_other_column" varchar as (my_column))', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"\')))', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"."nested"\')))', $statements[0]); + } + + public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]'); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table \"users\" (\"my_json_column\" varchar as (json_extract(\"my_json_column\", '$.\"foo\"[0][1]')))", $statements[0]); + } + + public function testCreateTableWithStoredAsColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_column'); + $blueprint->string('my_other_column')->storedAs('my_column'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("my_column" varchar not null, "my_other_column" varchar as (my_column) stored)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"\')) stored)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('my_json_column'); + $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"."nested"\')) stored)', $statements[0]); + } + + protected function getConnection() + { + return m::mock(Connection::class); + } + + public function getGrammar() + { + return new SQLiteGrammar; + } +} diff --git a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php new file mode 100644 index 000000000..3e9a50a0f --- /dev/null +++ b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php @@ -0,0 +1,932 @@ +create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("id" int not null identity primary key, "email" nvarchar(255) not null)', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "id" int not null identity primary key, "email" nvarchar(255) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()->setTablePrefix('prefix_')); + + $this->assertCount(1, $statements); + $this->assertSame('create table "prefix_users" ("id" int not null identity primary key, "email" nvarchar(255) not null)', $statements[0]); + } + + public function testCreateTemporaryTable() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->temporary(); + $blueprint->increments('id'); + $blueprint->string('email'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "#users" ("id" int not null identity primary key, "email" nvarchar(255) not null)', $statements[0]); + } + + public function testDropTable() + { + $blueprint = new Blueprint('users'); + $blueprint->drop(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop table "users"', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->drop(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()->setTablePrefix('prefix_')); + + $this->assertCount(1, $statements); + $this->assertSame('drop table "prefix_users"', $statements[0]); + } + + public function testDropTableIfExists() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIfExists(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('if object_id(N\'"users"\', \'U\') is not null drop table "users"', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropIfExists(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()->setTablePrefix('prefix_')); + + $this->assertCount(1, $statements); + $this->assertSame('if object_id(N\'"prefix_users"\', \'U\') is not null drop table "prefix_users"', $statements[0]); + } + + public function testDropColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->dropColumn('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertStringContainsString('alter table "users" drop column "foo"', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropColumn(['foo', 'bar']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertStringContainsString('alter table "users" drop column "foo", "bar"', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->dropColumn('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertStringContainsString('alter table "users" drop column "foo", "bar"', $statements[0]); + } + + public function testDropColumnDropsCreatesSqlToDropDefaultConstraints() + { + $blueprint = new Blueprint('foo'); + $blueprint->dropColumn('bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \"foo\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\"foo\"') AND [name] in ('bar') AND [default_object_id] <> 0;EXEC(@sql);alter table \"foo\" drop column \"bar\"", $statements[0]); + } + + public function testDropPrimary() + { + $blueprint = new Blueprint('users'); + $blueprint->dropPrimary('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); + } + + public function testDropUnique() + { + $blueprint = new Blueprint('users'); + $blueprint->dropUnique('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "foo" on "users"', $statements[0]); + } + + public function testDropIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->dropIndex('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "foo" on "users"', $statements[0]); + } + + public function testDropSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->dropSpatialIndex(['coordinates']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('drop index "geo_coordinates_spatialindex" on "geo"', $statements[0]); + } + + public function testDropForeign() + { + $blueprint = new Blueprint('users'); + $blueprint->dropForeign('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); + } + + public function testDropConstrainedForeignId() + { + $blueprint = new Blueprint('users'); + $blueprint->dropConstrainedForeignId('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('alter table "users" drop constraint "users_foo_foreign"', $statements[0]); + $this->assertSame('DECLARE @sql NVARCHAR(MAX) = \'\';SELECT @sql += \'ALTER TABLE "users" DROP CONSTRAINT \' + OBJECT_NAME([default_object_id]) + \';\' FROM sys.columns WHERE [object_id] = OBJECT_ID(N\'"users"\') AND [name] in (\'foo\') AND [default_object_id] <> 0;EXEC(@sql);alter table "users" drop column "foo"', $statements[1]); + } + + public function testDropTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->dropTimestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertStringContainsString('alter table "users" drop column "created_at", "updated_at"', $statements[0]); + } + + public function testDropTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dropTimestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertStringContainsString('alter table "users" drop column "created_at", "updated_at"', $statements[0]); + } + + public function testDropMorphs() + { + $blueprint = new Blueprint('photos'); + $blueprint->dropMorphs('imageable'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('drop index "photos_imageable_type_imageable_id_index" on "photos"', $statements[0]); + $this->assertStringContainsString('alter table "photos" drop column "imageable_type", "imageable_id"', $statements[1]); + } + + public function testRenameTable() + { + $blueprint = new Blueprint('users'); + $blueprint->rename('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('sp_rename N\'"users"\', "foo"', $statements[0]); + } + + public function testRenameIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->renameIndex('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('sp_rename N\'"users"."foo"\', "bar", N\'INDEX\'', $statements[0]); + } + + public function testAddingPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->primary('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add constraint "bar" primary key ("foo")', $statements[0]); + } + + public function testAddingUniqueKey() + { + $blueprint = new Blueprint('users'); + $blueprint->unique('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create unique index "bar" on "users" ("foo")', $statements[0]); + } + + public function testAddingIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->index(['foo', 'bar'], 'baz'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "baz" on "users" ("foo", "bar")', $statements[0]); + } + + public function testAddingSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->spatialIndex('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create spatial index "geo_coordinates_spatialindex" on "geo" ("coordinates")', $statements[0]); + } + + public function testAddingFluentSpatialIndex() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates', 'point')->spatialIndex(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertSame('create spatial index "geo_coordinates_spatialindex" on "geo" ("coordinates")', $statements[1]); + } + + public function testAddingRawIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->rawIndex('(function(column))', 'raw_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index "raw_index" on "users" ((function(column)))', $statements[0]); + } + + public function testAddingIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->increments('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "id" int not null identity primary key', $statements[0]); + } + + public function testAddingSmallIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->smallIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "id" smallint not null identity primary key', $statements[0]); + } + + public function testAddingMediumIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "id" int not null identity primary key', $statements[0]); + } + + public function testAddingID() + { + $blueprint = new Blueprint('users'); + $blueprint->id(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "id" bigint not null identity primary key', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->id('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" bigint not null identity primary key', $statements[0]); + } + + public function testAddingForeignID() + { + $blueprint = new Blueprint('users'); + $foreignId = $blueprint->foreignId('foo'); + $blueprint->foreignId('company_id')->constrained(); + $blueprint->foreignId('laravel_idea_id')->constrained(); + $blueprint->foreignId('team_id')->references('id')->on('teams'); + $blueprint->foreignId('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); + $this->assertSame([ + 'alter table "users" add "foo" bigint not null, "company_id" bigint not null, "laravel_idea_id" bigint not null, "team_id" bigint not null, "team_column_id" bigint not null', + 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', + 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', + 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', + 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', + ], $statements); + } + + public function testAddingForeignIdSpecifyingIndexNameInConstraint() + { + $blueprint = new Blueprint('users'); + $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertSame([ + 'alter table "users" add "company_id" bigint not null', + 'alter table "users" add constraint "my_index" foreign key ("company_id") references "companies" ("id")', + ], $statements); + } + + public function testAddingBigIncrementingID() + { + $blueprint = new Blueprint('users'); + $blueprint->bigIncrements('id'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "id" bigint not null identity primary key', $statements[0]); + } + + public function testAddingString() + { + $blueprint = new Blueprint('users'); + $blueprint->string('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(255) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(100) not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->string('foo', 100)->nullable()->default('bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(100) null default \'bar\'', $statements[0]); + } + + public function testAddingText() + { + $blueprint = new Blueprint('users'); + $blueprint->text('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(max) not null', $statements[0]); + } + + public function testAddingBigInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" bigint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->bigInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" bigint not null identity primary key', $statements[0]); + } + + public function testAddingInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->integer('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" int not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->integer('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" int not null identity primary key', $statements[0]); + } + + public function testAddingMediumInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" int not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->mediumInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" int not null identity primary key', $statements[0]); + } + + public function testAddingTinyInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" tinyint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->tinyInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" tinyint not null identity primary key', $statements[0]); + } + + public function testAddingSmallInteger() + { + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" smallint not null', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->smallInteger('foo', true); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" smallint not null identity primary key', $statements[0]); + } + + public function testAddingFloat() + { + $blueprint = new Blueprint('users'); + $blueprint->float('foo', 5); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" float(5) not null', $statements[0]); + } + + public function testAddingDouble() + { + $blueprint = new Blueprint('users'); + $blueprint->double('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" double precision not null', $statements[0]); + } + + public function testAddingDecimal() + { + $blueprint = new Blueprint('users'); + $blueprint->decimal('foo', 5, 2); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" decimal(5, 2) not null', $statements[0]); + } + + public function testAddingBoolean() + { + $blueprint = new Blueprint('users'); + $blueprint->boolean('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" bit not null', $statements[0]); + } + + public function testAddingEnum() + { + $blueprint = new Blueprint('users'); + $blueprint->enum('role', ['member', 'admin']); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "role" nvarchar(255) check ("role" in (N\'member\', N\'admin\')) not null', $statements[0]); + } + + public function testAddingJson() + { + $blueprint = new Blueprint('users'); + $blueprint->json('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(max) not null', $statements[0]); + } + + public function testAddingJsonb() + { + $blueprint = new Blueprint('users'); + $blueprint->jsonb('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(max) not null', $statements[0]); + } + + public function testAddingDate() + { + $blueprint = new Blueprint('users'); + $blueprint->date('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" date not null', $statements[0]); + } + + public function testAddingYear() + { + $blueprint = new Blueprint('users'); + $blueprint->year('birth_year'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "birth_year" int not null', $statements[0]); + } + + public function testAddingDateTime() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetime not null', $statements[0]); + } + + public function testAddingDateTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTime('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetime2(1) not null', $statements[0]); + } + + public function testAddingDateTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" datetimeoffset not null', $statements[0]); + } + + public function testAddingDateTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->dateTimeTz('foo', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" datetimeoffset(1) not null', $statements[0]); + } + + public function testAddingTime() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" time not null', $statements[0]); + } + + public function testAddingTimeWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->time('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" time(1) not null', $statements[0]); + } + + public function testAddingTimeTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" time not null', $statements[0]); + } + + public function testAddingTimeTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timeTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" time(1) not null', $statements[0]); + } + + public function testAddingTimestamp() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetime not null', $statements[0]); + } + + public function testAddingTimestampWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamp('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetime2(1) not null', $statements[0]); + } + + public function testAddingTimestampTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetimeoffset not null', $statements[0]); + } + + public function testAddingTimestampTzWithPrecision() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampTz('created_at', 1); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetimeoffset(1) not null', $statements[0]); + } + + public function testAddingTimestamps() + { + $blueprint = new Blueprint('users'); + $blueprint->timestamps(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetime null, "updated_at" datetime null', $statements[0]); + } + + public function testAddingTimestampsTz() + { + $blueprint = new Blueprint('users'); + $blueprint->timestampsTz(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "created_at" datetimeoffset null, "updated_at" datetimeoffset null', $statements[0]); + } + + public function testAddingRememberToken() + { + $blueprint = new Blueprint('users'); + $blueprint->rememberToken(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "remember_token" nvarchar(100) null', $statements[0]); + } + + public function testAddingBinary() + { + $blueprint = new Blueprint('users'); + $blueprint->binary('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" varbinary(max) not null', $statements[0]); + } + + public function testAddingUuid() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" uniqueidentifier not null', $statements[0]); + } + + public function testAddingUuidDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->uuid(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "uuid" uniqueidentifier not null', $statements[0]); + } + + public function testAddingForeignUuid() + { + $blueprint = new Blueprint('users'); + $foreignId = $blueprint->foreignUuid('foo'); + $blueprint->foreignUuid('company_id')->constrained(); + $blueprint->foreignUuid('laravel_idea_id')->constrained(); + $blueprint->foreignUuid('team_id')->references('id')->on('teams'); + $blueprint->foreignUuid('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); + $this->assertSame([ + 'alter table "users" add "foo" uniqueidentifier not null, "company_id" uniqueidentifier not null, "laravel_idea_id" uniqueidentifier not null, "team_id" uniqueidentifier not null, "team_column_id" uniqueidentifier not null', + 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', + 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', + 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', + 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', + ], $statements); + } + + public function testAddingIpAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(45) not null', $statements[0]); + } + + public function testAddingIpAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->ipAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "ip_address" nvarchar(45) not null', $statements[0]); + } + + public function testAddingMacAddress() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "foo" nvarchar(17) not null', $statements[0]); + } + + public function testAddingMacAddressDefaultsColumnName() + { + $blueprint = new Blueprint('users'); + $blueprint->macAddress(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "mac_address" nvarchar(17) not null', $statements[0]); + } + + public function testAddingGeometry() + { + $blueprint = new Blueprint('geo'); + $blueprint->geometry('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add "coordinates" geometry not null', $statements[0]); + } + + public function testAddingGeography() + { + $blueprint = new Blueprint('geo'); + $blueprint->geography('coordinates'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "geo" add "coordinates" geography not null', $statements[0]); + } + + public function testAddingGeneratedColumn() + { + $blueprint = new Blueprint('products'); + $blueprint->integer('price'); + $blueprint->computed('discounted_virtual', 'price - 5'); + $blueprint->computed('discounted_stored', 'price - 5')->persisted(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]); + + $blueprint = new Blueprint('products'); + $blueprint->integer('price'); + $blueprint->computed('discounted_virtual', new Expression('price - 5')); + $blueprint->computed('discounted_stored', new Expression('price - 5'))->persisted(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $this->assertCount(1, $statements); + $this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]); + } + + public function testGrammarsAreMacroable() + { + // compileReplace macro. + $this->getGrammar()::macro('compileReplace', function () { + return true; + }); + + $c = $this->getGrammar()::compileReplace(); + + $this->assertTrue($c); + } + + public function testQuoteString() + { + $this->assertSame("N'中文測試'", $this->getGrammar()->quoteString('中文測試')); + } + + public function testQuoteStringOnArray() + { + $this->assertSame("N'中文', N'測試'", $this->getGrammar()->quoteString(['中文', '測試'])); + } + + public function testCreateDatabase() + { + $connection = $this->getConnection(); + + $statement = $this->getGrammar()->compileCreateDatabase('my_database_a', $connection); + + $this->assertSame( + 'create database "my_database_a"', + $statement + ); + + $statement = $this->getGrammar()->compileCreateDatabase('my_database_b', $connection); + + $this->assertSame( + 'create database "my_database_b"', + $statement + ); + } + + public function testDropDatabaseIfExists() + { + $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a'); + + $this->assertSame( + 'drop database if exists "my_database_a"', + $statement + ); + + $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b'); + + $this->assertSame( + 'drop database if exists "my_database_b"', + $statement + ); + } + + protected function getConnection() + { + return m::mock(Connection::class); + } + + public function getGrammar() + { + return new SqlServerGrammar; + } +} From f6bd0bede1ce462cd4851c2930384ef7e9af5f93 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 5 Apr 2024 17:37:33 -0400 Subject: [PATCH 033/111] add MariaDb Connection and associated classes --- .../Connections/MariaDbConnection.php | 76 +++++++++++++++++++ .../Query/Grammars/MariaDbGrammar.php | 9 +++ src/Database/Schema/Grammars/MySqlGrammar.php | 4 +- .../Schema/Grammars/PostgresGrammar.php | 1 - .../Schema/Grammars/SQLiteGrammar.php | 7 +- .../Schema/Grammars/SqlServerGrammar.php | 3 +- 6 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/Database/Connections/MariaDbConnection.php create mode 100644 src/Database/Query/Grammars/MariaDbGrammar.php diff --git a/src/Database/Connections/MariaDbConnection.php b/src/Database/Connections/MariaDbConnection.php new file mode 100644 index 000000000..9d06b2bf5 --- /dev/null +++ b/src/Database/Connections/MariaDbConnection.php @@ -0,0 +1,76 @@ +withTablePrefix(new QueryGrammar); + } + + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\MariaDbBuilder + */ + public function getSchemaBuilder() + { + if (!isset($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new MariaDbBuilder($this); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Grammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\MariaDbProcessor + */ + protected function getDefaultPostProcessor() + { + return new MariaDbProcessor; + } + + /** + * Bind values to their parameters in the given statement. + * + * @param \PDOStatement $statement + * @param array $bindings + * @return void + */ + public function bindValues($statement, $bindings) + { + foreach ($bindings as $key => $value) { + $statement->bindValue( + is_string($key) ? $key : $key + 1, + $value, + is_int($value) || is_float($value) ? PDO::PARAM_INT : PDO::PARAM_STR + ); + } + } +} diff --git a/src/Database/Query/Grammars/MariaDbGrammar.php b/src/Database/Query/Grammars/MariaDbGrammar.php new file mode 100644 index 000000000..11eccd722 --- /dev/null +++ b/src/Database/Query/Grammars/MariaDbGrammar.php @@ -0,0 +1,9 @@ +getSchemaBuilder()->getColumns($blueprint->getTable())); foreach ($blueprint->getChangedColumns() as $column) { - $sql = sprintf('%s %s%s %s', + $sql = sprintf( + '%s %s%s %s', is_null($column->renameTo) ? 'modify' : 'change', $this->wrap($column), is_null($column->renameTo) ? '' : ' '.$this->wrap($column->renameTo), @@ -51,5 +52,4 @@ protected function addLegacyModifiers($sql, Blueprint $blueprint, Fluent $column return $sql; } - } diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index e1f1d0b7c..62acdde92 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -49,5 +49,4 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); } - } diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index f411649cf..52356a126 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -55,7 +55,9 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $columnNames[] = $name; } - return $this->addModifiers($name.' '.$column['type'], $blueprint, + return $this->addModifiers( + $name.' '.$column['type'], + $blueprint, new ColumnDefinition([ 'change' => true, 'type' => $column['type_name'], @@ -101,7 +103,8 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $foreignKeyConstraintsEnabled = $connection->scalar('pragma foreign_keys'); - return array_filter(array_merge([ + return array_filter(array_merge( + [ $foreignKeyConstraintsEnabled ? $this->compileDisableForeignKeyConstraints() : null, sprintf('create table %s (%s%s%s)', $tempTable, diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index 01c885c78..607eaf074 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -25,7 +25,8 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $oldColumns = collect($connection->getSchemaBuilder()->getColumns($blueprint->getTable())); foreach ($blueprint->getChangedColumns() as $column) { - $sql = sprintf('alter table %s alter column %s %s', + $sql = sprintf( + 'alter table %s alter column %s %s', $this->wrapTable($blueprint), $this->wrap($column), $this->getType($column) From e9915c9715a087a296f2d05e2fd7c81b3f82e70c Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 5 Apr 2024 17:49:26 -0400 Subject: [PATCH 034/111] try to appease code quality --- .../Schema/Grammars/SQLiteGrammar.php | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 52356a126..0b0d2de08 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -103,18 +103,35 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $foreignKeyConstraintsEnabled = $connection->scalar('pragma foreign_keys'); - return array_filter(array_merge( - [ - $foreignKeyConstraintsEnabled ? $this->compileDisableForeignKeyConstraints() : null, - sprintf('create table %s (%s%s%s)', - $tempTable, - implode(', ', $columns), - $this->addForeignKeys($foreignKeys), - $autoIncrementColumn ? '' : $this->addPrimaryKeys($primary->first()) - ), - sprintf('insert into %s (%s) select %s from %s', $tempTable, $columnNames, $columnNames, $table), - sprintf('drop table %s', $table), - sprintf('alter table %s rename to %s', $tempTable, $table), - ], $indexes, [$foreignKeyConstraintsEnabled ? $this->compileEnableForeignKeyConstraints() : null])); + return array_filter( + array_merge( + [ + $foreignKeyConstraintsEnabled ? $this->compileDisableForeignKeyConstraints() : null, + sprintf('create table %s (%s%s%s)', + $tempTable, + implode(', ', $columns), + $this->addForeignKeys($foreignKeys), + $autoIncrementColumn ? '' : $this->addPrimaryKeys($primary->first()) + ), + sprintf('insert into %s (%s) select %s from %s', + $tempTable, + $columnNames, + $columnNames, + $table + ), + sprintf('drop table %s', + $table + ), + sprintf('alter table %s rename to %s', + $tempTable, + $table + ), + ], + $indexes, + [ + $foreignKeyConstraintsEnabled ? $this->compileEnableForeignKeyConstraints() : null + ] + ) + ); } } From 0a35475e3c6ef1ce0525f3f7af92754a107b32a4 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 5 Apr 2024 19:46:09 -0400 Subject: [PATCH 035/111] fix phpstan ignore rules; fix overriden Grammars --- composer.json | 2 +- phpstan-baseline.neon | 293 +++++++++--------- src/Database/Connections/MySqlConnection.php | 2 +- src/Database/Schema/Grammars/MySqlGrammar.php | 2 +- .../Schema/Grammars/PostgresGrammar.php | 2 +- .../Schema/Grammars/SQLiteGrammar.php | 12 +- .../Schema/Grammars/SqlServerGrammar.php | 2 +- 7 files changed, 152 insertions(+), 163 deletions(-) diff --git a/composer.json b/composer.json index 27cd5cc24..c2595600d 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "mockery/mockery": "^1.6|^2.0", "dms/phpunit-arraysubset-asserts": "^0.5", "orchestra/testbench": "^9.0", - "larastan/larastan": "^2.8.1" + "larastan/larastan": "^2.9.2" }, "suggest": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ace12018d..1dc54b1a2 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,27 +1,27 @@ parameters: ignoreErrors: - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\)\\:\\:getOriginalEncryptableValues\\(\\)\\.$#" + message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\)::getOriginalEncryptableValues\\(\\)\\.$#" count: 1 path: src/Auth/Models/Group.php - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\)\\:\\:getOriginalHashValues\\(\\)\\.$#" + message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\)::getOriginalHashValues\\(\\)\\.$#" count: 1 path: src/Auth/Models/Group.php - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)\\:\\:getOriginalEncryptableValues\\(\\)\\.$#" + message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)::getOriginalEncryptableValues\\(\\)\\.$#" count: 1 path: src/Auth/Models/Role.php - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)\\:\\:getOriginalHashValues\\(\\)\\.$#" + message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)::getOriginalHashValues\\(\\)\\.$#" count: 1 path: src/Auth/Models/Role.php - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\User\\)\\:\\:getOriginalEncryptableValues\\(\\)\\.$#" + message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\User\\)::getOriginalEncryptableValues\\(\\)\\.$#" count: 1 path: src/Auth/Models/User.php @@ -31,57 +31,57 @@ parameters: path: src/Database/Capsule/Manager.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface\\:\\:getName\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface::getName\\(\\)\\.$#" count: 1 path: src/Database/MemoryCache.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$is_bind\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$is_bind\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$master_field\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$master_field\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$pivot_data\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$pivot_data\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$slave_id\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$slave_id\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$slave_type\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$slave_type\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Method Winter\\\\Storm\\\\Database\\\\Model\\:\\:getDeferredBindingRecords\\(\\) should return Winter\\\\Storm\\\\Database\\\\Collection but returns Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\.$#" + message: "#^Method Winter\\\\Storm\\\\Database\\\\Model::getDeferredBindingRecords\\(\\) should return Winter\\\\Storm\\\\Database\\\\Collection but returns Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Return type \\(Winter\\\\Storm\\\\Database\\\\Pivot\\) of method Winter\\\\Storm\\\\Database\\\\Model\\:\\:newPivot\\(\\) should be compatible with return type \\(Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Pivot\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:newPivot\\(\\)$#" + message: "#^Return type \\(Winter\\\\Storm\\\\Database\\\\Pivot\\) of method Winter\\\\Storm\\\\Database\\\\Model::newPivot\\(\\) should be compatible with return type \\(Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Pivot\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Model::newPivot\\(\\)$#" count: 1 path: src/Database/Model.php - - message: "#^Static property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$dispatcher \\(Illuminate\\\\Contracts\\\\Events\\\\Dispatcher\\) in isset\\(\\) is not nullable\\.$#" + message: "#^Static property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$dispatcher \\(Illuminate\\\\Contracts\\\\Events\\\\Dispatcher\\) in isset\\(\\) is not nullable\\.$#" count: 1 path: src/Database/Model.php - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Model\\:\\:errors\\(\\)\\.$#" + message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Model::errors\\(\\)\\.$#" count: 1 path: src/Database/ModelException.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:deleteCancel\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::deleteCancel\\(\\)\\.$#" count: 2 path: src/Database/Models/DeferredBinding.php @@ -91,7 +91,7 @@ parameters: path: src/Database/MorphPivot.php - - message: "#^Parameter \\#1 \\$ids of method Winter\\\\Storm\\\\Database\\\\Pivot\\:\\:newQueryForRestoration\\(\\) expects array\\\\|string, int given\\.$#" + message: "#^Parameter \\#1 \\$ids of method Winter\\\\Storm\\\\Database\\\\Pivot::newQueryForRestoration\\(\\) expects array\\\\|string, int given\\.$#" count: 1 path: src/Database/MorphPivot.php @@ -101,107 +101,92 @@ parameters: path: src/Database/MorphPivot.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:getLeftColumnName\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getLeftColumnName\\(\\)\\.$#" count: 1 path: src/Database/NestedTreeScope.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:\\$concats\\.$#" - count: 2 - path: src/Database/Query/Grammars/MySqlGrammar.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:\\$concats\\.$#" - count: 2 - path: src/Database/Query/Grammars/PostgresGrammar.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:\\$concats\\.$#" - count: 2 - path: src/Database/Query/Grammars/SQLiteGrammar.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:\\$concats\\.$#" - count: 2 - path: src/Database/Query/Grammars/SqlServerGrammar.php + message: "#^Access to an undefined property Illuminate.+(Builder|(Column|Index)Definition|Fluent)::\\$(.+)\\.$#" + paths: + - src/Database/*/Grammars/*Grammar.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface\\:\\:getName\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface::getName\\(\\)\\.$#" count: 1 path: src/Database/QueryBuilder.php - - message: "#^Property Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:\\$orders \\(array\\) does not accept null\\.$#" + message: "#^Property Illuminate\\\\Database\\\\Query\\\\Builder::\\$orders \\(array\\) does not accept null\\.$#" count: 1 path: src/Database/QueryBuilder.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/AttachMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/AttachMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachMany.php - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\AttachMany\\:\\:getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" + message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\AttachMany::getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachMany.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/AttachOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/AttachOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachOne.php - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\AttachOne\\:\\:getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" + message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\AttachOne::getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" count: 1 path: src/Database/Relations/AttachOne.php @@ -211,172 +196,172 @@ parameters: path: src/Database/Relations/AttachOne.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/BelongsTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:bindEventOnce\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindEventOnce\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/BelongsTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsTo.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$sessionKey\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$sessionKey\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:bindDeferred\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindDeferred\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:bindEventOnce\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindEventOnce\\(\\)\\.$#" count: 2 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:fireEvent\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::fireEvent\\(\\)\\.$#" count: 4 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:getRelationDefinition\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getRelationDefinition\\(\\)\\.$#" count: 3 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:newRelationPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::newRelationPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:reloadRelations\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::reloadRelations\\(\\)\\.$#" count: 2 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:unbindDeferred\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::unbindDeferred\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:lists\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany\\:\\:flushDuplicateCache\\(\\)\\.$#" + message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::flushDuplicateCache\\(\\)\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:paginate\\(\\) expects array, int\\|null given\\.$#" + message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany\\:\\:paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:paginate\\(\\)$#" + message: "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany\\:\\:paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:paginate\\(\\)$#" + message: "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:paginate\\(\\) expects string, array given\\.$#" + message: "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects string, array given\\.$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany\\:\\:paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:paginate\\(\\)$#" + message: "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" count: 1 path: src/Database/Relations/BelongsToMany.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/HasMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/HasMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasMany.php @@ -396,62 +381,62 @@ parameters: path: src/Database/Relations/HasMany.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/HasManyThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/HasManyThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasManyThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasManyThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasManyThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasManyThrough.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/HasOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/HasOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOne.php @@ -461,62 +446,62 @@ parameters: path: src/Database/Relations/HasOne.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/HasOneThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/HasOneThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOneThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOneThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOneThrough.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/HasOneThrough.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/MorphMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphMany.php @@ -536,47 +521,47 @@ parameters: path: src/Database/Relations/MorphMany.php - - message: "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\\\:\\:__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" + message: "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\::__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphMany\\:\\:__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" + message: "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphMany::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphMany\\:\\:__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" + message: "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphMany::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" count: 1 path: src/Database/Relations/MorphMany.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/MorphOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphOne.php @@ -586,177 +571,177 @@ parameters: path: src/Database/Relations/MorphOne.php - - message: "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\\\:\\:__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" + message: "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\::__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphOne\\:\\:__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" + message: "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphOne::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphOne\\:\\:__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" + message: "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphOne::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" count: 1 path: src/Database/Relations/MorphOne.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/MorphTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:bindEventOnce\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindEventOnce\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/MorphTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphTo.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphTo.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\:\\:\\$countMode\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getForeignKey\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" count: 3 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:select\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withDefault\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withPivot\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:withTimestamps\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder\\:\\:lists\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany\\:\\:flushDuplicateCache\\(\\)\\.$#" + message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::flushDuplicateCache\\(\\)\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:paginate\\(\\) expects array, int\\|null given\\.$#" + message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany\\:\\:paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:paginate\\(\\)$#" + message: "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany\\:\\:paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:paginate\\(\\)$#" + message: "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:paginate\\(\\) expects string, array given\\.$#" + message: "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects string, array given\\.$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany\\:\\:paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:paginate\\(\\)$#" + message: "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" count: 1 path: src/Database/Relations/MorphToMany.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:getSortOrderColumn\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getSortOrderColumn\\(\\)\\.$#" count: 1 path: src/Database/SortableScope.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$children\\.$#" + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$children\\.$#" count: 1 path: src/Database/TreeCollection.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:getParentId\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getParentId\\(\\)\\.$#" count: 1 path: src/Database/TreeCollection.php - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue\\:\\:queue\\(\\)$#" + message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" count: 1 path: src/Mail/Mailer.php - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer\\:\\:queue\\(\\)$#" + message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::queue\\(\\)$#" count: 1 path: src/Mail/Mailer.php - - message: "#^Parameter \\#2 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:queueOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer\\:\\:queueOn\\(\\)$#" + message: "#^Parameter \\#2 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queueOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::queueOn\\(\\)$#" count: 1 path: src/Mail/Mailer.php - - message: "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue\\:\\:later\\(\\)$#" + message: "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::later\\(\\)$#" count: 1 path: src/Mail/Mailer.php - - message: "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer\\:\\:later\\(\\)$#" + message: "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::later\\(\\)$#" count: 1 path: src/Mail/Mailer.php - - message: "#^Parameter \\#3 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:laterOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer\\:\\:laterOn\\(\\)$#" + message: "#^Parameter \\#3 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::laterOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::laterOn\\(\\)$#" count: 1 path: src/Mail/Mailer.php - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake\\:\\:queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue\\:\\:queue\\(\\)$#" + message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" count: 1 path: src/Support/Testing/Fakes/MailFake.php - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake\\:\\:queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Support\\\\Testing\\\\Fakes\\\\MailFake\\:\\:queue\\(\\)$#" + message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\)$#" count: 1 path: src/Support/Testing/Fakes/MailFake.php - - message: "#^Return type \\(void\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake\\:\\:send\\(\\) should be compatible with return type \\(Illuminate\\\\Mail\\\\SentMessage\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\Mailer\\:\\:send\\(\\)$#" + message: "#^Return type \\(void\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::send\\(\\) should be compatible with return type \\(Illuminate\\\\Mail\\\\SentMessage\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\Mailer::send\\(\\)$#" count: 1 path: src/Support/Testing/Fakes/MailFake.php diff --git a/src/Database/Connections/MySqlConnection.php b/src/Database/Connections/MySqlConnection.php index e8f809014..dbcf04dfc 100644 --- a/src/Database/Connections/MySqlConnection.php +++ b/src/Database/Connections/MySqlConnection.php @@ -4,8 +4,8 @@ use Illuminate\Database\Schema\MySqlBuilder; use Illuminate\Database\Query\Processors\MySqlProcessor; -use Winter\Storm\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; use Winter\Storm\Database\Query\Grammars\MySqlGrammar as QueryGrammar; +use Winter\Storm\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar diff --git a/src/Database/Schema/Grammars/MySqlGrammar.php b/src/Database/Schema/Grammars/MySqlGrammar.php index c4d777c82..1cb8d2a02 100755 --- a/src/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Database/Schema/Grammars/MySqlGrammar.php @@ -33,7 +33,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $this->getType($column) ); - $oldColum = new Fluent($prevColumns->where('name', $name)->first()); + $oldColumn = new Fluent($oldColumns->where('name', $column->name)->first()); $columns[] = $this->addLegacyModifiers($sql, $blueprint, $column, $oldColumn); } diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index 62acdde92..bdeb1ab7d 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -27,7 +27,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection foreach ($blueprint->getChangedColumns() as $column) { $changes = ['type '.$this->getType($column).$this->modifyCollate($blueprint, $column)]; - $oldColum = new Fluent($prevColumns->where('name', $name)->first()); + $oldColumn = new Fluent($oldColumns->where('name', $column->name)->first()); foreach ($this->modifiers as $modifier) { if ($modifier === 'Collate') { continue; diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 0b0d2de08..4ee06becf 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -107,22 +107,26 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection array_merge( [ $foreignKeyConstraintsEnabled ? $this->compileDisableForeignKeyConstraints() : null, - sprintf('create table %s (%s%s%s)', + sprintf( + 'create table %s (%s%s%s)', $tempTable, implode(', ', $columns), $this->addForeignKeys($foreignKeys), $autoIncrementColumn ? '' : $this->addPrimaryKeys($primary->first()) ), - sprintf('insert into %s (%s) select %s from %s', + sprintf( + 'insert into %s (%s) select %s from %s', $tempTable, $columnNames, $columnNames, $table ), - sprintf('drop table %s', + sprintf( + 'drop table %s', $table ), - sprintf('alter table %s rename to %s', + sprintf( + 'alter table %s rename to %s', $tempTable, $table ), diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index 607eaf074..11b013c43 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -32,7 +32,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $this->getType($column) ); - $oldColum = new Fluent($prevColumns->where('name', $name)->first()); + $oldColumn = new Fluent($oldColumns->where('name', $column->name)->first()); foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { From 9a6233d4801f3d0cbc18761f98cadaa95d0e837b Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 5 Apr 2024 19:52:13 -0400 Subject: [PATCH 036/111] downgrade larastan --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c2595600d..27cd5cc24 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "mockery/mockery": "^1.6|^2.0", "dms/phpunit-arraysubset-asserts": "^0.5", "orchestra/testbench": "^9.0", - "larastan/larastan": "^2.9.2" + "larastan/larastan": "^2.8.1" }, "suggest": { From 5dca01ebec53d87e041c13fd44b0e0ae628d76cc Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 08:53:50 -0400 Subject: [PATCH 037/111] simplify phpstan baseline rules --- phpstan-baseline.neon | 265 ++++-------------------------------------- 1 file changed, 21 insertions(+), 244 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1dc54b1a2..db79a5870 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,29 +1,11 @@ parameters: ignoreErrors: - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\)::getOriginalEncryptableValues\\(\\)\\.$#" - count: 1 - path: src/Auth/Models/Group.php - - - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\)::getOriginalHashValues\\(\\)\\.$#" - count: 1 - path: src/Auth/Models/Group.php - - - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)::getOriginalEncryptableValues\\(\\)\\.$#" - count: 1 - path: src/Auth/Models/Role.php - - - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)::getOriginalHashValues\\(\\)\\.$#" - count: 1 - path: src/Auth/Models/Role.php - - - - message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\User\\)::getOriginalEncryptableValues\\(\\)\\.$#" - count: 1 - path: src/Auth/Models/User.php + message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\(Group|Role|User)\\)::getOriginal(Encryptable|Hash)Values\\(\\)\\.$#" + paths: + - src/Auth/Models/Group.php + - src/Auth/Models/Role.php + - src/Auth/Models/User.php - message: "#^Parameter \\#1 \\$app of class Illuminate\\\\Database\\\\DatabaseManager constructor expects Illuminate\\\\Contracts\\\\Foundation\\\\Application, Illuminate\\\\Contracts\\\\Container\\\\Container given\\.$#" @@ -36,43 +18,11 @@ parameters: path: src/Database/MemoryCache.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$is_bind\\.$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$master_field\\.$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$pivot_data\\.$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$slave_id\\.$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$slave_type\\.$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Method Winter\\\\Storm\\\\Database\\\\Model::getDeferredBindingRecords\\(\\) should return Winter\\\\Storm\\\\Database\\\\Collection but returns Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\.$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Return type \\(Winter\\\\Storm\\\\Database\\\\Pivot\\) of method Winter\\\\Storm\\\\Database\\\\Model::newPivot\\(\\) should be compatible with return type \\(Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Pivot\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Model::newPivot\\(\\)$#" - count: 1 - path: src/Database/Model.php - - - - message: "#^Static property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$dispatcher \\(Illuminate\\\\Contracts\\\\Events\\\\Dispatcher\\) in isset\\(\\) is not nullable\\.$#" - count: 1 + messages: + - "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$(is_bind|master_field|pivot_data|slave_(id|type))\\.$#" + - "#^Method Winter\\\\Storm\\\\Database\\\\Model::getDeferredBindingRecords\\(\\) should return Winter\\\\Storm\\\\Database\\\\Collection but returns Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\.$#" + - "#^Return type \\(Winter\\\\Storm\\\\Database\\\\Pivot\\) of method Winter\\\\Storm\\\\Database\\\\Model::newPivot\\(\\) should be compatible with return type \\(Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Pivot\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Model::newPivot\\(\\)$#" + - "#^Static property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$dispatcher \\(Illuminate\\\\Contracts\\\\Events\\\\Dispatcher\\) in isset\\(\\) is not nullable\\.$#" path: src/Database/Model.php - @@ -108,7 +58,8 @@ parameters: - message: "#^Access to an undefined property Illuminate.+(Builder|(Column|Index)Definition|Fluent)::\\$(.+)\\.$#" paths: - - src/Database/*/Grammars/*Grammar.php + - src/Database/Schema/Grammars/*Grammar.php + - src/Database/Query/Grammars/*Grammar.php - message: "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface::getName\\(\\)\\.$#" @@ -121,189 +72,15 @@ parameters: path: src/Database/QueryBuilder.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\AttachMany::getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachMany.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\AttachOne::getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Call to private method delete\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOne\\\\.$#" - count: 3 - path: src/Database/Relations/AttachOne.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindEventOnce\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsTo.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$sessionKey\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindDeferred\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindEventOnce\\(\\)\\.$#" - count: 2 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::fireEvent\\(\\)\\.$#" - count: 4 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getRelationDefinition\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::newRelationPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::reloadRelations\\(\\)\\.$#" - count: 2 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::unbindDeferred\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php + messages: + - "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$sessionKey\\.$#" + - "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" + - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::(getForeignKey|select|with(Default|Pivot|Timestamps))\\(\\)\\.$#" + - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::((un)?bind(Deferred|EventOnce)|fireEvent|getRelationDefinition|newRelationPivot|reloadRelations)\\(\\)\\.$#" + - "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" + - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\Attach(Many|One)::getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" + - "#^Call to private method delete\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOne\\\\.$#" + path: src/Database/Relations/*.php - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::flushDuplicateCache\\(\\)\\.$#" From f136a78e147bc351ca088755bb3a38f16d037446 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 08:56:36 -0400 Subject: [PATCH 038/111] simplify phpstan baseline rules --- phpstan-baseline.neon | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index db79a5870..961254465 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -78,15 +78,10 @@ parameters: - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::(getForeignKey|select|with(Default|Pivot|Timestamps))\\(\\)\\.$#" - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::((un)?bind(Deferred|EventOnce)|fireEvent|getRelationDefinition|newRelationPivot|reloadRelations)\\(\\)\\.$#" - "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" - - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\Attach(Many|One)::getRelationExistenceQueryForSelfJoin\\(\\)\\.$#" + - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Attach|BelongsTo)(Many|One)::(flushDuplicateCache|getRelationExistenceQueryForSelfJoin)\\(\\)\\.$#" - "#^Call to private method delete\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOne\\\\.$#" path: src/Database/Relations/*.php - - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::flushDuplicateCache\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" count: 1 From d4f7389fe53a00f3c1a74b5f8332d0b21e93273e Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 09:39:30 -0400 Subject: [PATCH 039/111] major simplifications to phpstan baseline rules --- phpstan-baseline.neon | 478 ++++-------------------------------------- 1 file changed, 40 insertions(+), 438 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 961254465..c5f878a90 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -36,18 +36,10 @@ parameters: path: src/Database/Models/DeferredBinding.php - - message: "#^Parameter \\#1 \\$haystack of function str_contains expects string, int given\\.$#" - count: 1 - path: src/Database/MorphPivot.php - - - - message: "#^Parameter \\#1 \\$ids of method Winter\\\\Storm\\\\Database\\\\Pivot::newQueryForRestoration\\(\\) expects array\\\\|string, int given\\.$#" - count: 1 - path: src/Database/MorphPivot.php - - - - message: "#^Parameter \\#2 \\$string of function explode expects string, int given\\.$#" - count: 1 + messages: + - "#^Parameter \\#1 \\$haystack of function str_contains expects string, int given\\.$#" + - "#^Parameter \\#1 \\$ids of method Winter\\\\Storm\\\\Database\\\\Pivot::newQueryForRestoration\\(\\) expects array\\\\|string, int given\\.$#" + - "#^Parameter \\#2 \\$string of function explode expects string, int given\\.$#" path: src/Database/MorphPivot.php - @@ -62,13 +54,9 @@ parameters: - src/Database/Query/Grammars/*Grammar.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface::getName\\(\\)\\.$#" - count: 1 - path: src/Database/QueryBuilder.php - - - - message: "#^Property Illuminate\\\\Database\\\\Query\\\\Builder::\\$orders \\(array\\) does not accept null\\.$#" - count: 1 + messages: + - "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface::getName\\(\\)\\.$#" + - "#^Property Illuminate\\\\Database\\\\Query\\\\Builder::\\$orders \\(array\\) does not accept null\\.$#" path: src/Database/QueryBuilder.php - @@ -78,384 +66,30 @@ parameters: - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::(getForeignKey|select|with(Default|Pivot|Timestamps))\\(\\)\\.$#" - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::((un)?bind(Deferred|EventOnce)|fireEvent|getRelationDefinition|newRelationPivot|reloadRelations)\\(\\)\\.$#" - "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" - - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Attach|BelongsTo)(Many|One)::(flushDuplicateCache|getRelationExistenceQueryForSelfJoin)\\(\\)\\.$#" - - "#^Call to private method delete\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOne\\\\.$#" + - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Attach|(Belongs|Morph)To)(One|Many)::(flushDuplicateCache|getRelationExistenceQueryForSelfJoin)\\(\\)\\.$#" + - "#^Call to private method .+ of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Has|Morph)(One|Many)\\\\.$#" + - "#^If condition is always true\\.$#" path: src/Database/Relations/*.php - - message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects string, array given\\.$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\BelongsToMany::paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" - count: 1 - path: src/Database/Relations/BelongsToMany.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to private method update\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Call to private method whereNotIn\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: src/Database/Relations/HasMany.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/HasManyThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/HasManyThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasManyThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasManyThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasManyThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasManyThrough.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/HasOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/HasOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOne.php - - - - message: "#^Call to private method update\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasOne\\\\.$#" - count: 2 - path: src/Database/Relations/HasOne.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/HasOneThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/HasOneThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOneThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOneThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOneThrough.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/HasOneThrough.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to private method update\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphMany\\\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Call to private method whereNotIn\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphMany\\\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\::__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphMany::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphMany::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" - count: 1 - path: src/Database/Relations/MorphMany.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Call to private method update\\(\\) of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOne\\\\.$#" - count: 2 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\::__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphOne::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphOne::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" - count: 1 - path: src/Database/Relations/MorphOne.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::bindEventOnce\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphTo.php - - - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany::\\$countMode\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getForeignKey\\(\\)\\.$#" - count: 3 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::select\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withDefault\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withPivot\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::withTimestamps\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::flushDuplicateCache\\(\\)\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" - count: 1 - path: src/Database/Relations/MorphToMany.php - - - - message: "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects string, array given\\.$#" - count: 1 - path: src/Database/Relations/MorphToMany.php + messages: + - "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" + - "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" + - "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" + - "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects string, array given\\.$#" + - "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" + paths: + - src/Database/Relations/BelongsToMany.php + - src/Database/Relations/MorphToMany.php - - message: "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\MorphToMany::paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\::paginate\\(\\)$#" - count: 1 - path: src/Database/Relations/MorphToMany.php + messages: + - "#^Parameter \\#1 \\$query of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\MorphOneOrMany\\::__construct\\(\\) expects Illuminate\\\\Database\\\\Eloquent\\\\Builder\\, Illuminate\\\\Database\\\\Eloquent\\\\Builder\\ given\\.$#" + - "#^Parameter \\$parent of method Winter\\\\Storm\\\\Database\\\\Relations\\\\Morph(One|Many)::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" + - "#^Parameter \\$query of method Winter\\\\Storm\\\\Database\\\\Relations\\\\Morph(One|Many)::__construct\\(\\) has invalid type Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\TRelatedModel\\.$#" + paths: + - src/Database/Relations/MorphOne.php + - src/Database/Relations/MorphMany.php - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getSortOrderColumn\\(\\)\\.$#" @@ -463,58 +97,26 @@ parameters: path: src/Database/SortableScope.php - - message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$children\\.$#" - count: 1 - path: src/Database/TreeCollection.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getParentId\\(\\)\\.$#" - count: 1 + messages: + - "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$children\\.$#" + - "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model::getParentId\\(\\)\\.$#" path: src/Database/TreeCollection.php - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" - count: 1 - path: src/Mail/Mailer.php - - - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::queue\\(\\)$#" - count: 1 - path: src/Mail/Mailer.php - - - - message: "#^Parameter \\#2 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queueOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::queueOn\\(\\)$#" - count: 1 - path: src/Mail/Mailer.php - - - - message: "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::later\\(\\)$#" - count: 1 - path: src/Mail/Mailer.php - - - - message: "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::later\\(\\)$#" - count: 1 - path: src/Mail/Mailer.php - - - - message: "#^Parameter \\#3 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::laterOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::laterOn\\(\\)$#" - count: 1 + messages: + - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" + - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::queue\\(\\)$#" + - "#^Parameter \\#2 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queueOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::queueOn\\(\\)$#" + - "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::later\\(\\)$#" + - "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::later\\(\\)$#" + - "#^Parameter \\#3 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::laterOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::laterOn\\(\\)$#" path: src/Mail/Mailer.php - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" - count: 1 - path: src/Support/Testing/Fakes/MailFake.php - - - - message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\)$#" - count: 1 - path: src/Support/Testing/Fakes/MailFake.php - - - - message: "#^Return type \\(void\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::send\\(\\) should be compatible with return type \\(Illuminate\\\\Mail\\\\SentMessage\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\Mailer::send\\(\\)$#" - count: 1 + messages: + - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" + - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::queue\\(\\)$#" + - "#^Return type \\(void\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::send\\(\\) should be compatible with return type \\(Illuminate\\\\Mail\\\\SentMessage\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\Mailer::send\\(\\)$#" path: src/Support/Testing/Fakes/MailFake.php - From 158573ecfc1d67addbcd19c328ae83a4b2978b3f Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 09:55:09 -0400 Subject: [PATCH 040/111] ignore src/Scaffold/GeneratorCommand.php --- phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon b/phpstan.neon index a7a8abc05..8ea424707 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,6 +11,7 @@ parameters: - src/Parse/PHP/ArrayFile.php - src/Parse/PHP/ArrayPrinter.php - src/Foundation/Console/KeyGenerateCommand.php + - src/Scaffold/GeneratorCommand.php disableSchemaScan: true databaseMigrationsPath: - src/Auth/Migrations From eb133026bd61cc9cf7fb309f836961e6d5e55526 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 09:56:51 -0400 Subject: [PATCH 041/111] only use spaces in phpstan.neon --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 8ea424707..291360afc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,7 +11,7 @@ parameters: - src/Parse/PHP/ArrayFile.php - src/Parse/PHP/ArrayPrinter.php - src/Foundation/Console/KeyGenerateCommand.php - - src/Scaffold/GeneratorCommand.php + - src/Scaffold/GeneratorCommand.php disableSchemaScan: true databaseMigrationsPath: - src/Auth/Migrations From 7d668136772d55a0e125cd3b3ab329d41b87187a Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 11:59:46 -0400 Subject: [PATCH 042/111] no need to wrap in Fluent --- src/Database/Schema/Grammars/MySqlGrammar.php | 2 +- src/Database/Schema/Grammars/PostgresGrammar.php | 2 +- src/Database/Schema/Grammars/SqlServerGrammar.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Database/Schema/Grammars/MySqlGrammar.php b/src/Database/Schema/Grammars/MySqlGrammar.php index 1cb8d2a02..15d6f51cb 100755 --- a/src/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Database/Schema/Grammars/MySqlGrammar.php @@ -33,7 +33,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $this->getType($column) ); - $oldColumn = new Fluent($oldColumns->where('name', $column->name)->first()); + $oldColumn = $oldColumns->where('name', $column->name)->first(); $columns[] = $this->addLegacyModifiers($sql, $blueprint, $column, $oldColumn); } diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index bdeb1ab7d..205644d65 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -27,7 +27,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection foreach ($blueprint->getChangedColumns() as $column) { $changes = ['type '.$this->getType($column).$this->modifyCollate($blueprint, $column)]; - $oldColumn = new Fluent($oldColumns->where('name', $column->name)->first()); + $oldColumn = $oldColumns->where('name', $column->name)->first(); foreach ($this->modifiers as $modifier) { if ($modifier === 'Collate') { continue; diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index 11b013c43..f01815ca8 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -32,7 +32,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $this->getType($column) ); - $oldColumn = new Fluent($oldColumns->where('name', $column->name)->first()); + $oldColumn = $oldColumns->where('name', $column->name)->first(); foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { From 58d5b83777b2df2fc3c977280470637af44a27ce Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 12:03:38 -0400 Subject: [PATCH 043/111] add test for Blueprint::change() method --- .../Grammars/MySqlSchemaGrammarTest.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php index 167637c75..e308f6131 100644 --- a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -5,9 +5,11 @@ use Illuminate\Database\Connection; use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Schema\Builder; use Illuminate\Database\Schema\ForeignIdColumnDefinition; use Winter\Storm\Database\Schema\Grammars\MySqlGrammar; use Mockery as m; +use PDO; use PHPUnit\Framework\TestCase; class MySqlSchemaGrammarTest extends TestCase @@ -1276,6 +1278,32 @@ public function testAddingComment() $this->assertSame("alter table `users` add `foo` varchar(255) not null comment 'Escape \\' when using words like it\\'s'", $statements[0]); } + public function testChangingColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->string('name')->nullable(); + + $connection = $this->getConnection(); + $grammar = $this->getGrammar(); + + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->once()->andReturn($blueprint->getColumns()); + + $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schemaBuilder); + + $statements = $blueprint->toSql($connection, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); + + $changeBlueprint = new Blueprint('users'); + $changeBlueprint->string('name')->default('admin')->change(); + $statements = $changeBlueprint->toSql($connection, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame("alter table `users` modify `name` varchar(255) null default 'admin'", $statements[0]); + } + public function testCreateDatabase() { $connection = $this->getConnection(); From 01248282b937134537ad477ab7e51a3afeb4fa63 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 13:43:34 -0400 Subject: [PATCH 044/111] add test for Blueprint change() command for SqlServer & Postgres --- .../Grammars/Concerns/MySqlBasedGrammar.php | 52 +++++++++++++++++++ .../Schema/Grammars/MariaDbGrammar.php | 5 +- src/Database/Schema/Grammars/MySqlGrammar.php | 47 +---------------- .../Schema/Grammars/PostgresGrammar.php | 4 ++ .../Grammars/PostgresSchemaGrammarTest.php | 30 +++++++++++ .../Grammars/SqlServerSchemaGrammarTest.php | 27 ++++++++++ 6 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php diff --git a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php new file mode 100644 index 000000000..da1b79a62 --- /dev/null +++ b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php @@ -0,0 +1,52 @@ +getSchemaBuilder()->getColumns($blueprint->getTable())); + + foreach ($blueprint->getChangedColumns() as $column) { + $sql = sprintf( + '%s %s%s %s', + is_null($column->renameTo) ? 'modify' : 'change', + $this->wrap($column), + is_null($column->renameTo) ? '' : ' '.$this->wrap($column->renameTo), + $this->getType($column) + ); + + $oldColumn = $oldColumns->where('name', $column->name)->first(); + foreach ($this->modifiers as $modifier) { + if (method_exists($this, $method = "modify{$modifier}")) { + $mod = strtolower($modifier); + $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $sql .= $this->{$method}($blueprint, $col); + } + } + $columns[] = $sql; + } + + return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); + } +} diff --git a/src/Database/Schema/Grammars/MariaDbGrammar.php b/src/Database/Schema/Grammars/MariaDbGrammar.php index 9a574623e..fbc4f6ca2 100755 --- a/src/Database/Schema/Grammars/MariaDbGrammar.php +++ b/src/Database/Schema/Grammars/MariaDbGrammar.php @@ -2,6 +2,9 @@ namespace Winter\Storm\Database\Schema\Grammars; -class MariaDbGrammar extends MySqlGrammar +use Illuminate\Database\Schema\Grammars\MariaDbGrammar as MariaDbGrammarBase; + +class MariaDbGrammar extends MariaDbGrammarBase { + use Concerns\MySqlBasedGrammar; } diff --git a/src/Database/Schema/Grammars/MySqlGrammar.php b/src/Database/Schema/Grammars/MySqlGrammar.php index 15d6f51cb..207f58a3e 100755 --- a/src/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Database/Schema/Grammars/MySqlGrammar.php @@ -2,54 +2,9 @@ namespace Winter\Storm\Database\Schema\Grammars; -use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Grammars\MySqlGrammar as MySqlGrammarBase; -use Illuminate\Database\Connection; -use Illuminate\Support\Fluent; class MySqlGrammar extends MySqlGrammarBase { - /** - * Compile a change column command into a series of SQL statements. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @param \Illuminate\Database\Connection $connection - * @return array|string - * - * @throws \RuntimeException - */ - public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection) - { - $columns = []; - $oldColumns = collect($connection->getSchemaBuilder()->getColumns($blueprint->getTable())); - - foreach ($blueprint->getChangedColumns() as $column) { - $sql = sprintf( - '%s %s%s %s', - is_null($column->renameTo) ? 'modify' : 'change', - $this->wrap($column), - is_null($column->renameTo) ? '' : ' '.$this->wrap($column->renameTo), - $this->getType($column) - ); - - $oldColumn = $oldColumns->where('name', $column->name)->first(); - $columns[] = $this->addLegacyModifiers($sql, $blueprint, $column, $oldColumn); - } - - return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); - } - - protected function addLegacyModifiers($sql, Blueprint $blueprint, Fluent $column, Fluent $oldColumn) - { - foreach ($this->modifiers as $modifier) { - if (method_exists($this, $method = "modify{$modifier}")) { - $mod = strtolower($modifier); - $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; - $sql .= $this->{$method}($blueprint, $col); - } - } - - return $sql; - } + use Concerns\MySqlBasedGrammar; } diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index 205644d65..7bf589655 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -11,6 +11,10 @@ class PostgresGrammar extends PostgresGrammarBase { /** * Compile a change column command into a series of SQL statements. + * + * Starting with Laravel 11, previous column attributes do not persist when changing a column. + * This restores Laravel previous behavior where existing column attributes are kept + * unless they get changed by the new Blueprint. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command diff --git a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php index 96b1222bf..a861b0c09 100644 --- a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php @@ -1155,6 +1155,36 @@ public function testAddingMultiPolygon() $this->assertSame('alter table "geo" add column "coordinates" geometry(multipolygon) not null', $statements[0]); } + public function testChangingColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->string('name')->nullable(); + + $connection = $this->getConnection(); + $grammar = $this->getGrammar(); + + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->once()->andReturn($blueprint->getColumns()); + + $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schemaBuilder); + + $statements = $blueprint->toSql($connection, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "name" varchar(255) null', $statements[0]); + + $changeBlueprint = new Blueprint('users'); + $changeBlueprint->string('name')->default('admin')->change(); + $statements = $changeBlueprint->toSql($connection, $grammar); + + $this->assertCount(2, $statements); + + $parts = explode(', ', $statements[0]); + $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); + $this->assertSame('alter column "name" null', $parts[1]); + $this->assertSame("alter column \"name\" set default 'admin'", $parts[2]); + } + public function testCreateDatabase() { $connection = $this->getConnection(); diff --git a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php index 3e9a50a0f..aea3d7160 100644 --- a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php @@ -862,6 +862,33 @@ public function testAddingGeneratedColumn() $this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]); } + public function testChangingColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->string('name')->nullable(); + + $connection = $this->getConnection(); + $grammar = $this->getGrammar(); + + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->once()->andReturn($blueprint->getColumns()); + + $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schemaBuilder); + + $statements = $blueprint->toSql($connection, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add "name" nvarchar(255) null', $statements[0]); + + $changeBlueprint = new Blueprint('users'); + $changeBlueprint->string('name')->default('admin')->change(); + $statements = $changeBlueprint->toSql($connection, $grammar); + + $this->assertCount(3, $statements); + $this->assertSame('alter table "users" alter column "name" nvarchar(255) null', $statements[1]); + $this->assertSame('alter table "users" add default \'admin\' for "name"', $statements[2]); + } + public function testGrammarsAreMacroable() { // compileReplace macro. From fad6c26ca1d0b7015b0d5f07cb8d06fec47db86b Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 13:57:54 -0400 Subject: [PATCH 045/111] remove extra white space --- src/Database/Schema/Grammars/PostgresGrammar.php | 2 +- src/Database/Schema/Grammars/SqlServerGrammar.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index 7bf589655..e62b2f36a 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -11,7 +11,7 @@ class PostgresGrammar extends PostgresGrammarBase { /** * Compile a change column command into a series of SQL statements. - * + * * Starting with Laravel 11, previous column attributes do not persist when changing a column. * This restores Laravel previous behavior where existing column attributes are kept * unless they get changed by the new Blueprint. diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index f01815ca8..52e80237b 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -12,6 +12,10 @@ class SqlServerGrammar extends SqlServerGrammarBase /** * Compile a change column command into a series of SQL statements. * + * Starting with Laravel 11, previous column attributes do not persist when changing a column. + * This restores Laravel previous behavior where existing column attributes are kept + * unless they get changed by the new Blueprint. + * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @param \Illuminate\Database\Connection $connection From 0ed6f64676151dcb74e51a1e1c87c797a95b99e3 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 14:33:33 -0400 Subject: [PATCH 046/111] add compileChange override --- .../Schema/Grammars/SQLiteGrammar.php | 60 +++++++++---------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 4ee06becf..b8b0ecf8e 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -16,6 +16,10 @@ class SQLiteGrammar extends SQLiteGrammarBase /** * Compile a change column command into a series of SQL statements. * + * Starting with Laravel 11, previous column attributes do not persist when changing a column. + * This restores Laravel previous behavior where existing column attributes are kept + * unless they get changed by the new Blueprint. + * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @param \Illuminate\Database\Connection $connection @@ -32,47 +36,37 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $columnNames = []; $autoIncrementColumn = null; + $oldColumns = collect($connection->getSchemaBuilder()->getColumns($blueprint->getTable())); + $columns = collect($schema->getColumns($table)) - ->map(function ($column) use ($blueprint, $changedColumns, &$columnNames, &$autoIncrementColumn) { + ->map(function ($column) use ($blueprint, $changedColumns, &$columnNames, &$autoIncrementColumn, $oldColumns) { $column = $changedColumns->first(fn ($col) => $col->name === $column['name'], $column); - if ($column instanceof Fluent) { - $name = $this->wrap($column); - $autoIncrementColumn = $column->autoIncrement ? $column->name : $autoIncrementColumn; + if (! $column instanceof Fluent) { + $column = new Fluent($column); + } - if (is_null($column->virtualAs) && is_null($column->virtualAsJson) && - is_null($column->storedAs) && is_null($column->storedAsJson)) { - $columnNames[] = $name; - } + $name = $this->wrap($column); + $autoIncrementColumn = $column->autoIncrement ? $column->name : $autoIncrementColumn; - return $this->addModifiers($name.' '.$this->getType($column), $blueprint, $column); - } else { - $name = $this->wrap($column['name']); - $autoIncrementColumn = $column['auto_increment'] ? $column['name'] : $autoIncrementColumn; - $isGenerated = ! is_null($column['generation']); + if (is_null($column->virtualAs) && is_null($column->virtualAsJson) && + is_null($column->storedAs) && is_null($column->storedAsJson) && + is_null($column->generation) + ) { + $columnNames[] = $name; + } - if (! $isGenerated) { - $columnNames[] = $name; - } + $oldColumn = $oldColumns->where('name', $column->name)->first(); + $sql = $name.' '.$this->getType($column); - return $this->addModifiers( - $name.' '.$column['type'], - $blueprint, - new ColumnDefinition([ - 'change' => true, - 'type' => $column['type_name'], - 'nullable' => $column['nullable'], - 'default' => $column['default'] ? new Expression($column['default']) : null, - 'autoIncrement' => $column['auto_increment'], - 'collation' => $column['collation'], - 'comment' => $column['comment'], - 'virtualAs' => $isGenerated && $column['generation']['type'] === 'virtual' - ? $column['generation']['expression'] : null, - 'storedAs' => $isGenerated && $column['generation']['type'] === 'stored' - ? $column['generation']['expression'] : null, - ]) - ); + foreach ($this->modifiers as $modifier) { + if (method_exists($this, $method = "modify{$modifier}")) { + $mod = strtolower($modifier); + $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $sql .= $this->{$method}($blueprint, $col); + } } + return $sql; })->all(); $foreignKeys = collect($schema->getForeignKeys($table))->map(fn ($foreignKey) => new ForeignKeyDefinition([ From 157451c430762600a44358992373f60bbe2c2627 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 14:33:43 -0400 Subject: [PATCH 047/111] add SQLite Blueprint change() unit test --- .../Grammars/MySqlSchemaGrammarTest.php | 4 +-- .../Grammars/PostgresSchemaGrammarTest.php | 4 +-- .../Grammars/SQLiteSchemaGrammarTest.php | 29 +++++++++++++++++++ .../Grammars/SqlServerSchemaGrammarTest.php | 4 +-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php index e308f6131..1cc7c4064 100644 --- a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -1287,9 +1287,9 @@ public function testChangingColumn() $grammar = $this->getGrammar(); $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->once()->andReturn($blueprint->getColumns()); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schemaBuilder); + $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); $statements = $blueprint->toSql($connection, $grammar); diff --git a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php index a861b0c09..2c634b072 100644 --- a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php @@ -1164,9 +1164,9 @@ public function testChangingColumn() $grammar = $this->getGrammar(); $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->once()->andReturn($blueprint->getColumns()); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schemaBuilder); + $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); $statements = $blueprint->toSql($connection, $grammar); diff --git a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php index a120e88bf..b5d6fd911 100644 --- a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php @@ -832,6 +832,35 @@ public function testAddingGeneratedColumnByExpression() $this->assertSame('create table "products" ("price" integer not null, "discounted_virtual" integer as ("price" - 5), "discounted_stored" integer as ("price" - 5) stored)', $statements[0]); } + public function testChangingColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->string('name')->nullable(); + + $connection = $this->getConnection(); + $grammar = $this->getGrammar(); + + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); + $schemaBuilder->shouldReceive('getForeignKeys')->andReturn([]); + $schemaBuilder->shouldReceive('getIndexes')->andReturn([]); + + $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); + $connection->shouldReceive('scalar')->andReturn(''); + + $statements = $blueprint->toSql($connection, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame('alter table "users" add column "name" varchar', $statements[0]); + + $changeBlueprint = new Blueprint('users'); + $changeBlueprint->string('name')->default('admin')->change(); + $statements = $changeBlueprint->toSql($connection, $grammar); + + $this->assertCount(4, $statements); + $this->assertStringContainsString("varchar default 'admin'", $statements[0]); + } + public function testGrammarsAreMacroable() { // compileReplace macro. diff --git a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php index aea3d7160..37ccd6f07 100644 --- a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php @@ -871,9 +871,9 @@ public function testChangingColumn() $grammar = $this->getGrammar(); $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->once()->andReturn($blueprint->getColumns()); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schemaBuilder); + $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); $statements = $blueprint->toSql($connection, $grammar); From 8a7f0a37cd8bfbf636cd66dfb0e104cfdc56e22c Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 6 Apr 2024 14:45:18 -0400 Subject: [PATCH 048/111] be safe and properly instantiate a new ColumnDefinition object --- src/Database/Schema/Grammars/SQLiteGrammar.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index b8b0ecf8e..9b01e5a10 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -43,15 +43,27 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $column = $changedColumns->first(fn ($col) => $col->name === $column['name'], $column); if (! $column instanceof Fluent) { - $column = new Fluent($column); + $isGenerated = ! is_null($column['generation']); + $column = new ColumnDefinition([ + 'change' => true, + 'type' => $column['type_name'], + 'nullable' => $column['nullable'], + 'default' => $column['default'] ? new Expression($column['default']) : null, + 'autoIncrement' => $column['auto_increment'], + 'collation' => $column['collation'], + 'comment' => $column['comment'], + 'virtualAs' => $isGenerated && $column['generation']['type'] === 'virtual' + ? $column['generation']['expression'] : null, + 'storedAs' => $isGenerated && $column['generation']['type'] === 'stored' + ? $column['generation']['expression'] : null, + ]); } $name = $this->wrap($column); $autoIncrementColumn = $column->autoIncrement ? $column->name : $autoIncrementColumn; if (is_null($column->virtualAs) && is_null($column->virtualAsJson) && - is_null($column->storedAs) && is_null($column->storedAsJson) && - is_null($column->generation) + is_null($column->storedAs) && is_null($column->storedAsJson) ) { $columnNames[] = $name; } From 6d8bd9dd8dd7824ff18690ac1943a3f7d83a26eb Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 7 Apr 2024 09:19:08 -0400 Subject: [PATCH 049/111] only use previous modifiers if not set in current Blueprint --- .../Schema/Grammars/Concerns/MySqlBasedGrammar.php | 2 +- src/Database/Schema/Grammars/PostgresGrammar.php | 2 +- src/Database/Schema/Grammars/SQLiteGrammar.php | 2 +- src/Database/Schema/Grammars/SqlServerGrammar.php | 2 +- .../Schema/Grammars/MySqlSchemaGrammarTest.php | 7 +++++++ .../Schema/Grammars/PostgresSchemaGrammarTest.php | 10 ++++++++++ .../Schema/Grammars/SQLiteSchemaGrammarTest.php | 7 +++++++ .../Schema/Grammars/SqlServerSchemaGrammarTest.php | 7 +++++++ 8 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php index da1b79a62..1a83fb5e6 100644 --- a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php +++ b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php @@ -40,7 +40,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { $mod = strtolower($modifier); - $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $col = isset($oldColumn->{$mod}) && !isset($column->{$mod}) ? $oldColumn : $column; $sql .= $this->{$method}($blueprint, $col); } } diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index e62b2f36a..16c81542a 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -39,7 +39,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection if (method_exists($this, $method = "modify{$modifier}")) { $mod = strtolower($modifier); - $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $col = isset($oldColumn->{$mod}) && ! isset($column->{$mod}) ? $oldColumn : $column; $constraints = (array) $this->{$method}($blueprint, $col); foreach ($constraints as $constraint) { diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 9b01e5a10..095a96eb8 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -74,7 +74,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { $mod = strtolower($modifier); - $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $col = isset($oldColumn->{$mod}) && !isset($column->{$mod}) ? $oldColumn : $column; $sql .= $this->{$method}($blueprint, $col); } } diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index 52e80237b..c2212c113 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -41,7 +41,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { $mod = strtolower($modifier); - $col = isset($oldColumn->{$mod}) ? $oldColumn : $column; + $col = isset($oldColumn->{$mod}) && !isset($column->{$mod}) ? $oldColumn : $column; $sql .= $this->{$method}($blueprint, $col); } } diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php index 1cc7c4064..7100c67b2 100644 --- a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -1302,6 +1302,13 @@ public function testChangingColumn() $this->assertCount(1, $statements); $this->assertSame("alter table `users` modify `name` varchar(255) null default 'admin'", $statements[0]); + + $otherChangeBlueprint = new Blueprint('users'); + $otherChangeBlueprint->string('name')->nullable(false)->change(); + $statements = $otherChangeBlueprint->toSql($connection, $grammar); + + $this->assertCount(1, $statements); + $this->assertSame("alter table `users` modify `name` varchar(255) not null", $statements[0]); } public function testCreateDatabase() diff --git a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php index 2c634b072..5fa8a174c 100644 --- a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php @@ -1183,6 +1183,16 @@ public function testChangingColumn() $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); $this->assertSame('alter column "name" null', $parts[1]); $this->assertSame("alter column \"name\" set default 'admin'", $parts[2]); + + $otherChangeBlueprint = new Blueprint('users'); + $otherChangeBlueprint->string('name')->nullable(false)->change(); + $statements = $otherChangeBlueprint->toSql($connection, $grammar); + + $this->assertCount(2, $statements); + + $parts = explode(', ', $statements[0]); + $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); + $this->assertSame('alter column "name" set not null', $parts[1]); } public function testCreateDatabase() diff --git a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php index b5d6fd911..c43c7d6fa 100644 --- a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php @@ -859,6 +859,13 @@ public function testChangingColumn() $this->assertCount(4, $statements); $this->assertStringContainsString("varchar default 'admin'", $statements[0]); + + $otherChangeBlueprint = new Blueprint('users'); + $otherChangeBlueprint->string('name')->nullable(false)->change(); + $statements = $otherChangeBlueprint->toSql($connection, $grammar); + + $this->assertCount(4, $statements); + $this->assertStringContainsString("varchar not null", $statements[0]); } public function testGrammarsAreMacroable() diff --git a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php index 37ccd6f07..0adf8dc45 100644 --- a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php @@ -887,6 +887,13 @@ public function testChangingColumn() $this->assertCount(3, $statements); $this->assertSame('alter table "users" alter column "name" nvarchar(255) null', $statements[1]); $this->assertSame('alter table "users" add default \'admin\' for "name"', $statements[2]); + + $otherChangeBlueprint = new Blueprint('users'); + $otherChangeBlueprint->string('name')->nullable(false)->change(); + $statements = $otherChangeBlueprint->toSql($connection, $grammar); + + $this->assertCount(2, $statements); + $this->assertSame('alter table "users" alter column "name" nvarchar(255) not null', $statements[1]); } public function testGrammarsAreMacroable() From 75555345fe9ad7fd1323f6a2e4b32696baec6556 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 7 Apr 2024 10:19:24 -0400 Subject: [PATCH 050/111] only test change() Blueprint method --- .../Grammars/MySqlSchemaGrammarTest.php | 1478 +---------------- 1 file changed, 39 insertions(+), 1439 deletions(-) diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php index 7100c67b2..e8c89f64a 100644 --- a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -19,1476 +19,76 @@ protected function tearDown(): void m::close(); } - public function testBasicCreateTable() + protected function setupConnection(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $blueprint->string('email'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key, add `email` varchar(255) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->uuid('id')->primary(); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table `users` (`id` char(36) not null, primary key (`id`))', $statements[0]); - } - - public function testAutoIncrementStartingValue() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id')->startingValue(1000); - $blueprint->string('email'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); - $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]); - } - - public function testAddColumnsWithMultipleAutoIncrementStartingValue() - { - $blueprint = new Blueprint('users'); - $blueprint->id()->from(100); - $blueprint->string('name')->from(200); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertEquals([ - 'alter table `users` add `id` bigint unsigned not null auto_increment primary key, add `name` varchar(255) not null', - 'alter table `users` auto_increment = 100', - ], $statements); - } - - public function testEngineCreateTable() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $blueprint->engine('InnoDB'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB", $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn('InnoDB'); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB", $statements[0]); - } - - public function testCharsetCollationCreateTable() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $blueprint->charset('utf8mb4'); - $blueprint->collation('utf8mb4_unicode_ci'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci'", $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email')->charset('utf8mb4')->collation('utf8mb4_unicode_ci'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) character set utf8mb4 collate 'utf8mb4_unicode_ci' not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); - } - - public function testBasicCreateTableWithPrefix() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $grammar = $this->getGrammar(); - $grammar->setTablePrefix('prefix_'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $grammar); - - $this->assertCount(1, $statements); - $this->assertSame('create table `prefix_users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]); - } - - public function testCreateTemporaryTable() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->temporary(); - $blueprint->increments('id'); - $blueprint->string('email'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create temporary table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]); - } - - public function testDropTable() - { - $blueprint = new Blueprint('users'); - $blueprint->drop(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table `users`', $statements[0]); - } - - public function testDropTableIfExists() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIfExists(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table if exists `users`', $statements[0]); - } - - public function testDropColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->dropColumn('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop `foo`', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropColumn(['foo', 'bar']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropColumn('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]); - } - - public function testDropPrimary() - { - $blueprint = new Blueprint('users'); - $blueprint->dropPrimary(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop primary key', $statements[0]); - } - - public function testDropUnique() - { - $blueprint = new Blueprint('users'); - $blueprint->dropUnique('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop index `foo`', $statements[0]); - } - - public function testDropIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIndex('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop index `foo`', $statements[0]); - } - - public function testDropSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->dropSpatialIndex(['coordinates']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` drop index `geo_coordinates_spatialindex`', $statements[0]); - } - - public function testDropForeign() - { - $blueprint = new Blueprint('users'); - $blueprint->dropForeign('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop foreign key `foo`', $statements[0]); - } - - public function testDropTimestamps() - { - $blueprint = new Blueprint('users'); - $blueprint->dropTimestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]); - } - - public function testDropTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dropTimestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]); - } - - public function testDropMorphs() - { - $blueprint = new Blueprint('photos'); - $blueprint->dropMorphs('imageable'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('alter table `photos` drop index `photos_imageable_type_imageable_id_index`', $statements[0]); - $this->assertSame('alter table `photos` drop `imageable_type`, drop `imageable_id`', $statements[1]); - } - - public function testRenameTable() - { - $blueprint = new Blueprint('users'); - $blueprint->rename('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('rename table `users` to `foo`', $statements[0]); - } - - public function testRenameIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->renameIndex('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` rename index `foo` to `bar`', $statements[0]); - } - - public function testAddingPrimaryKey() - { - $blueprint = new Blueprint('users'); - $blueprint->primary('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add primary key (`foo`)', $statements[0]); - } - - public function testAddingPrimaryKeyWithAlgorithm() - { - $blueprint = new Blueprint('users'); - $blueprint->primary('foo', 'bar', 'hash'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add primary key using hash(`foo`)', $statements[0]); - } - - public function testAddingUniqueKey() - { - $blueprint = new Blueprint('users'); - $blueprint->unique('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add unique `bar`(`foo`)', $statements[0]); - } - - public function testAddingIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->index(['foo', 'bar'], 'baz'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add index `baz`(`foo`, `bar`)', $statements[0]); - } - - public function testAddingIndexWithAlgorithm() - { - $blueprint = new Blueprint('users'); - $blueprint->index(['foo', 'bar'], 'baz', 'hash'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add index `baz` using hash(`foo`, `bar`)', $statements[0]); - } - - public function testAddingFulltextIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->fulltext('body'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add fulltext `users_body_fulltext`(`body`)', $statements[0]); - } - - public function testAddingSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->spatialIndex('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[0]); - } - - public function testAddingFluentSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point')->spatialIndex(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[1]); - } - - public function testAddingRawIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->rawIndex('(function(column))', 'raw_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add index `raw_index`((function(column)))', $statements[0]); - } - - public function testAddingForeignKey() - { - $blueprint = new Blueprint('users'); - $blueprint->foreign('foo_id')->references('id')->on('orders'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnDelete(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on delete cascade', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnUpdate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on update cascade', $statements[0]); - } - - public function testAddingIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key', $statements[0]); - } - - public function testAddingSmallIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->smallIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `id` smallint unsigned not null auto_increment primary key', $statements[0]); - } - - public function testAddingID() - { - $blueprint = new Blueprint('users'); - $blueprint->id(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->id('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` bigint unsigned not null auto_increment primary key', $statements[0]); - } - - public function testAddingForeignID() - { - $blueprint = new Blueprint('users'); - $foreignId = $blueprint->foreignId('foo'); - $blueprint->foreignId('company_id')->constrained(); - $blueprint->foreignId('laravel_idea_id')->constrained(); - $blueprint->foreignId('team_id')->references('id')->on('teams'); - $blueprint->foreignId('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); - $this->assertSame([ - 'alter table `users` add `foo` bigint unsigned not null, add `company_id` bigint unsigned not null, add `laravel_idea_id` bigint unsigned not null, add `team_id` bigint unsigned not null, add `team_column_id` bigint unsigned not null', - 'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)', - 'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)', - 'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)', - 'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)', - ], $statements); - } - - public function testAddingForeignIdSpecifyingIndexNameInConstraint() - { - $blueprint = new Blueprint('users'); - $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertSame([ - 'alter table `users` add `company_id` bigint unsigned not null', - 'alter table `users` add constraint `my_index` foreign key (`company_id`) references `companies` (`id`)', - ], $statements); - } - - public function testAddingBigIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->bigIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]); - } - - public function testAddingColumnInTableFirst() - { - $blueprint = new Blueprint('users'); - $blueprint->string('name')->first(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `name` varchar(255) not null first', $statements[0]); - } - - public function testAddingColumnAfterAnotherColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->string('name')->after('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `name` varchar(255) not null after `foo`', $statements[0]); - } - - public function testAddingMultipleColumnsAfterAnotherColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->after('foo', function ($blueprint) { - $blueprint->string('one'); - $blueprint->string('two'); - }); - $blueprint->string('three'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `one` varchar(255) not null after `foo`, add `two` varchar(255) not null after `one`, add `three` varchar(255) not null', $statements[0]); - } - - public function testAddingGeneratedColumn() - { - $blueprint = new Blueprint('products'); - $blueprint->integer('price'); - $blueprint->integer('discounted_virtual')->virtualAs('price - 5'); - $blueprint->integer('discounted_stored')->storedAs('price - 5'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5), add `discounted_stored` int as (price - 5) stored', $statements[0]); - - $blueprint = new Blueprint('products'); - $blueprint->integer('price'); - $blueprint->integer('discounted_virtual')->virtualAs('price - 5')->nullable(false); - $blueprint->integer('discounted_stored')->storedAs('price - 5')->nullable(false); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5) not null, add `discounted_stored` int as (price - 5) stored not null', $statements[0]); - } - - public function testAddingGeneratedColumnWithCharset() - { - $blueprint = new Blueprint('links'); - $blueprint->string('url', 2083)->charset('ascii'); - $blueprint->string('url_hash_virtual', 64)->virtualAs('sha2(url, 256)')->charset('ascii'); - $blueprint->string('url_hash_stored', 64)->storedAs('sha2(url, 256)')->charset('ascii'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `links` add `url` varchar(2083) character set ascii not null, add `url_hash_virtual` varchar(64) character set ascii as (sha2(url, 256)), add `url_hash_stored` varchar(64) character set ascii as (sha2(url, 256)) stored', $statements[0]); - } - - public function testAddingGeneratedColumnByExpression() - { - $blueprint = new Blueprint('products'); - $blueprint->integer('price'); - $blueprint->integer('discounted_virtual')->virtualAs(new Expression('price - 5')); - $blueprint->integer('discounted_stored')->storedAs(new Expression('price - 5')); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `products` add `price` int not null, add `discounted_virtual` int as (price - 5), add `discounted_stored` int as (price - 5) stored', $statements[0]); - } - - public function testAddingInvisibleColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->string('secret', 64)->nullable(false)->invisible(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `secret` varchar(64) not null invisible', $statements[0]); - } - - public function testAddingString() - { - $blueprint = new Blueprint('users'); - $blueprint->string('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` varchar(255) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` varchar(100) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100)->nullable()->default('bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` varchar(100) null default \'bar\'', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100)->nullable()->default(new Expression('CURRENT TIMESTAMP')); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` varchar(100) null default CURRENT TIMESTAMP', $statements[0]); - } - - public function testAddingText() - { - $blueprint = new Blueprint('users'); - $blueprint->text('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` text not null', $statements[0]); - } - - public function testAddingBigInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` bigint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` bigint not null auto_increment primary key', $statements[0]); - } - - public function testAddingInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->integer('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` int not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->integer('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` int not null auto_increment primary key', $statements[0]); - } - - public function testAddingIncrementsWithStartingValues() - { - $blueprint = new Blueprint('users'); - $blueprint->id()->startingValue(1000); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]); - $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]); - } - - public function testAddingMediumInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` mediumint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` mediumint not null auto_increment primary key', $statements[0]); - } - - public function testAddingSmallInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` smallint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` smallint not null auto_increment primary key', $statements[0]); - } - - public function testAddingTinyInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` tinyint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` tinyint not null auto_increment primary key', $statements[0]); - } - - public function testAddingFloat() - { - $blueprint = new Blueprint('users'); - $blueprint->float('foo', 5); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` float(5) not null', $statements[0]); - } - - public function testAddingDouble() - { - $blueprint = new Blueprint('users'); - $blueprint->double('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` double not null', $statements[0]); - } - - public function testAddingDecimal() - { - $blueprint = new Blueprint('users'); - $blueprint->decimal('foo', 5, 2); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` decimal(5, 2) not null', $statements[0]); - } - - public function testAddingBoolean() - { - $blueprint = new Blueprint('users'); - $blueprint->boolean('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` tinyint(1) not null', $statements[0]); - } - - public function testAddingEnum() - { - $blueprint = new Blueprint('users'); - $blueprint->enum('role', ['member', 'admin']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `role` enum(\'member\', \'admin\') not null', $statements[0]); - } - - public function testAddingSet() - { - $blueprint = new Blueprint('users'); - $blueprint->set('role', ['member', 'admin']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `role` set(\'member\', \'admin\') not null', $statements[0]); - } - - public function testAddingJson() - { - $blueprint = new Blueprint('users'); - $blueprint->json('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` json not null', $statements[0]); - } - - public function testAddingJsonb() - { - $blueprint = new Blueprint('users'); - $blueprint->jsonb('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` json not null', $statements[0]); - } - - public function testAddingDate() - { - $blueprint = new Blueprint('users'); - $blueprint->date('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` date not null', $statements[0]); - } - - public function testAddingYear() - { - $blueprint = new Blueprint('users'); - $blueprint->year('birth_year'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `birth_year` year not null', $statements[0]); - } - - public function testAddingDateTime() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dateTime('foo', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]); - } - - public function testAddingDateTimeWithDefaultCurrent() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('foo')->useCurrent(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP', $statements[0]); - } - - public function testAddingDateTimeWithOnUpdateCurrent() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('foo')->useCurrentOnUpdate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime not null on update CURRENT_TIMESTAMP', $statements[0]); - } - - public function testAddingDateTimeWithDefaultCurrentAndOnUpdateCurrent() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('foo')->useCurrent()->useCurrentOnUpdate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP', $statements[0]); - } - - public function testAddingDateTimeWithDefaultCurrentOnUpdateCurrentAndPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('foo', 3)->useCurrent()->useCurrentOnUpdate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime(3) not null default CURRENT_TIMESTAMP(3) on update CURRENT_TIMESTAMP(3)', $statements[0]); - } - - public function testAddingDateTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('foo', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]); - } - - public function testAddingTime() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]); - } - - public function testAddingTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]); - } - - public function testAddingTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]); - } - - public function testAddingTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]); - } - - public function testAddingTimestamp() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]); - } - - public function testAddingTimestampWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]); - } - - public function testAddingTimestampWithDefault() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at')->default('2015-07-22 11:43:17'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame("alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'", $statements[0]); - } - - public function testAddingTimestampWithDefaultCurrentSpecifyingPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1)->useCurrent(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1)', $statements[0]); - } - - public function testAddingTimestampWithOnUpdateCurrentSpecifyingPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1)->useCurrentOnUpdate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp(1) not null on update CURRENT_TIMESTAMP(1)', $statements[0]); - } - - public function testAddingTimestampWithDefaultCurrentAndOnUpdateCurrentSpecifyingPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1)->useCurrent()->useCurrentOnUpdate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1) on update CURRENT_TIMESTAMP(1)', $statements[0]); - } - - public function testAddingTimestampTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]); - } - - public function testAddingTimestampTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]); - } - - public function testAddingTimeStampTzWithDefault() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at')->default('2015-07-22 11:43:17'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame("alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'", $statements[0]); - } - - public function testAddingTimestamps() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp null, add `updated_at` timestamp null', $statements[0]); - } - - public function testAddingTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `created_at` timestamp null, add `updated_at` timestamp null', $statements[0]); - } - - public function testAddingRememberToken() - { - $blueprint = new Blueprint('users'); - $blueprint->rememberToken(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `remember_token` varchar(100) null', $statements[0]); - } - - public function testAddingBinary() - { - $blueprint = new Blueprint('users'); - $blueprint->binary('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` blob not null', $statements[0]); - } - - public function testAddingUuid() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` char(36) not null', $statements[0]); - } - - public function testAddingUuidDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `uuid` char(36) not null', $statements[0]); - } - - public function testAddingForeignUuid() - { - $blueprint = new Blueprint('users'); - $foreignUuid = $blueprint->foreignUuid('foo'); - $blueprint->foreignUuid('company_id')->constrained(); - $blueprint->foreignUuid('laravel_idea_id')->constrained(); - $blueprint->foreignUuid('team_id')->references('id')->on('teams'); - $blueprint->foreignUuid('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid); - $this->assertSame([ - 'alter table `users` add `foo` char(36) not null, add `company_id` char(36) not null, add `laravel_idea_id` char(36) not null, add `team_id` char(36) not null, add `team_column_id` char(36) not null', - 'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)', - 'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)', - 'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)', - 'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)', - ], $statements); - } - - public function testAddingIpAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` varchar(45) not null', $statements[0]); - } - - public function testAddingIpAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `ip_address` varchar(45) not null', $statements[0]); - } - - public function testAddingMacAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `foo` varchar(17) not null', $statements[0]); - } - - public function testAddingMacAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `mac_address` varchar(17) not null', $statements[0]); - } - - public function testAddingGeometry() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` geometry not null', $statements[0]); - } - - public function testAddingGeography() - { - $blueprint = new Blueprint('geo'); - $blueprint->geography('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` geometry srid 4326 not null', $statements[0]); - } - - public function testAddingPoint() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` point not null', $statements[0]); - } - - public function testAddingPointWithSrid() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point', 4326); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` point srid 4326 not null', $statements[0]); - } - - public function testAddingPointWithSridColumn() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point', 4326)->after('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` point srid 4326 not null after `id`', $statements[0]); - } - - public function testAddingLineString() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'linestring'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` linestring not null', $statements[0]); - } - - public function testAddingPolygon() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'polygon'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` polygon not null', $statements[0]); - } - - public function testAddingGeometryCollection() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'geometrycollection'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` geometrycollection not null', $statements[0]); - } - - public function testAddingMultiPoint() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'multipoint'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` multipoint not null', $statements[0]); + $connection = m::mock(Connection::class); + $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); + return $connection; } - public function testAddingMultiLineString() + protected function getSchemaBuilder(Blueprint $blueprint) { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'multilinestring'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` multilinestring not null', $statements[0]); - } - - public function testAddingMultiPolygon() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'multipolygon'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `geo` add `coordinates` multipolygon not null', $statements[0]); - } - - public function testAddingComment() - { - $blueprint = new Blueprint('users'); - $blueprint->string('foo')->comment("Escape ' when using words like it's"); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("alter table `users` add `foo` varchar(255) not null comment 'Escape \\' when using words like it\\'s'", $statements[0]); - } - - public function testChangingColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->string('name')->nullable(); - - $connection = $this->getConnection(); - $grammar = $this->getGrammar(); - $schemaBuilder = m::mock(Builder::class); $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); - - $statements = $blueprint->toSql($connection, $grammar); - - $this->assertCount(1, $statements); - $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); - - $changeBlueprint = new Blueprint('users'); - $changeBlueprint->string('name')->default('admin')->change(); - $statements = $changeBlueprint->toSql($connection, $grammar); - - $this->assertCount(1, $statements); - $this->assertSame("alter table `users` modify `name` varchar(255) null default 'admin'", $statements[0]); - - $otherChangeBlueprint = new Blueprint('users'); - $otherChangeBlueprint->string('name')->nullable(false)->change(); - $statements = $otherChangeBlueprint->toSql($connection, $grammar); - - $this->assertCount(1, $statements); - $this->assertSame("alter table `users` modify `name` varchar(255) not null", $statements[0]); + return $schemaBuilder; } - public function testCreateDatabase() + protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) { - $connection = $this->getConnection(); - $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_foo'); - $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_foo'); - - $statement = $this->getGrammar()->compileCreateDatabase('my_database_a', $connection); - - $this->assertSame( - 'create database `my_database_a` default character set `utf8mb4_foo` default collate `utf8mb4_unicode_ci_foo`', - $statement - ); - - $connection = $this->getConnection(); - $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_bar'); - $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_bar'); - - $statement = $this->getGrammar()->compileCreateDatabase('my_database_b', $connection); - - $this->assertSame( - 'create database `my_database_b` default character set `utf8mb4_bar` default collate `utf8mb4_unicode_ci_bar`', - $statement - ); + $connection = $this->setupConnection($initialBlueprint); + if (is_null($blueprint)) { + $blueprint = $initialBlueprint; + } + return $blueprint->toSql($connection, new MySqlGrammar); } - public function testCreateTableWithVirtualAsColumn() + public function testNoInitialModifiersAddNullable() { - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_column'); - $blueprint->string('my_other_column')->virtualAs('my_column'); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column)) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name'); + $statements = $this->runBlueprint($initialBlueprint); $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\"'))))", $statements[0]); + $this->assertSame('alter table `users` add `name` varchar(255) not null', $statements[0]); - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->nullable()->change(); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\".\"nested\"'))))", $statements[0]); + $this->assertSame("alter table `users` modify `name` varchar(255) null", $statements[0]); } - public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey() + public function testNullableInitialModifierAddDefault() { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]'); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); - $statements = $blueprint->toSql($conn, $this->getGrammar()); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->change(); - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_json_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"foo\"[0][1]'))))", $statements[0]); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $this->assertSame("alter table `users` modify `name` varchar(255) null default 'admin'", $statements[0]); } - public function testCreateTableWithStoredAsColumn() + public function testNullableInitialModifierAddDefaultNotNullable() { - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); - $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); - $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_column'); - $blueprint->string('my_other_column')->storedAs('my_column'); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column) stored) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); - - $statements = $blueprint->toSql($conn, $this->getGrammar()); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); + $statements = $this->runBlueprint($initialBlueprint); $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\"'))) stored)", $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested'); - - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); + $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); - $statements = $blueprint->toSql($conn, $this->getGrammar()); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); $this->assertCount(1, $statements); - $this->assertSame("create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\"some_attribute\".\"nested\"'))) stored)", $statements[0]); - } - - public function testDropDatabaseIfExists() - { - $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a'); - - $this->assertSame( - 'drop database if exists `my_database_a`', - $statement - ); - - $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b'); - - $this->assertSame( - 'drop database if exists `my_database_b`', - $statement - ); - } - - public function testDropAllTables() - { - $statement = $this->getGrammar()->compileDropAllTables(['alpha', 'beta', 'gamma']); - - $this->assertSame('drop table `alpha`,`beta`,`gamma`', $statement); - } - - public function testDropAllViews() - { - $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']); - - $this->assertSame('drop view `alpha`,`beta`,`gamma`', $statement); - } - - public function testGrammarsAreMacroable() - { - // compileReplace macro. - $this->getGrammar()::macro('compileReplace', function () { - return true; - }); - - $c = $this->getGrammar()::compileReplace(); - - $this->assertTrue($c); - } - - protected function getConnection() - { - return m::mock(Connection::class); - } - - public function getGrammar() - { - return new MySqlGrammar; + $this->assertSame("alter table `users` modify `name` varchar(255) not null default 'admin'", $statements[0]); } } From 5dc7fc9650bc1c5c15e3f82c0a5e34b0e5ab1140 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 7 Apr 2024 10:53:47 -0400 Subject: [PATCH 051/111] only test change() Blueprint method --- .../Grammars/MySqlSchemaGrammarTest.php | 4 - .../Grammars/PostgresSchemaGrammarTest.php | 1269 +---------------- .../Grammars/SQLiteSchemaGrammarTest.php | 960 +------------ .../Grammars/SqlServerSchemaGrammarTest.php | 956 +------------ 4 files changed, 124 insertions(+), 3065 deletions(-) diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php index e8c89f64a..ab7963141 100644 --- a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -49,14 +49,12 @@ public function testNoInitialModifiersAddNullable() $initialBlueprint->string('name'); $statements = $this->runBlueprint($initialBlueprint); - $this->assertCount(1, $statements); $this->assertSame('alter table `users` add `name` varchar(255) not null', $statements[0]); $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->nullable()->change(); $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); - $this->assertCount(1, $statements); $this->assertSame("alter table `users` modify `name` varchar(255) null", $statements[0]); } @@ -81,14 +79,12 @@ public function testNullableInitialModifierAddDefaultNotNullable() $initialBlueprint->string('name')->nullable(); $statements = $this->runBlueprint($initialBlueprint); - $this->assertCount(1, $statements); $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); - $this->assertCount(1, $statements); $this->assertSame("alter table `users` modify `name` varchar(255) not null default 'admin'", $statements[0]); } } diff --git a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php index 5fa8a174c..474f0858f 100644 --- a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php @@ -18,1261 +18,80 @@ protected function tearDown(): void m::close(); } - public function testBasicCreateTable() + protected function setupConnection(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $blueprint->string('name')->collation('nb_NO.utf8'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("id" serial not null primary key, "email" varchar(255) not null, "name" varchar(255) collate "nb_NO.utf8" not null)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" serial not null primary key, add column "email" varchar(255) not null', $statements[0]); - } - - public function testCreateTableWithAutoIncrementStartingValue() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id')->startingValue(1000); - $blueprint->string('email'); - $blueprint->string('name')->collation('nb_NO.utf8'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('create table "users" ("id" serial not null primary key, "email" varchar(255) not null, "name" varchar(255) collate "nb_NO.utf8" not null)', $statements[0]); - $this->assertSame('alter sequence users_id_seq restart with 1000', $statements[1]); - } - - public function testAddColumnsWithMultipleAutoIncrementStartingValue() - { - $blueprint = new Blueprint('users'); - $blueprint->id()->from(100); - $blueprint->increments('code')->from(200); - $blueprint->string('name')->from(300); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertEquals([ - 'alter table "users" add column "id" bigserial not null primary key, add column "code" serial not null primary key, add column "name" varchar(255) not null', - 'alter sequence users_id_seq restart with 100', - 'alter sequence users_code_seq restart with 200', - ], $statements); - } - - public function testCreateTableAndCommentColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email')->comment('my first comment'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('create table "users" ("id" serial not null primary key, "email" varchar(255) not null)', $statements[0]); - $this->assertSame('comment on column "users"."email" is \'my first comment\'', $statements[1]); - } - - public function testCreateTemporaryTable() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->temporary(); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create temporary table "users" ("id" serial not null primary key, "email" varchar(255) not null)', $statements[0]); - } - - public function testDropTable() - { - $blueprint = new Blueprint('users'); - $blueprint->drop(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table "users"', $statements[0]); - } - - public function testDropTableIfExists() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIfExists(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table if exists "users"', $statements[0]); - } - - public function testDropColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->dropColumn('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop column "foo"', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropColumn(['foo', 'bar']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop column "foo", drop column "bar"', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropColumn('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop column "foo", drop column "bar"', $statements[0]); - } - - public function testDropPrimary() - { - $blueprint = new Blueprint('users'); - $blueprint->dropPrimary(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop constraint "users_pkey"', $statements[0]); - } - - public function testDropUnique() - { - $blueprint = new Blueprint('users'); - $blueprint->dropUnique('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); - } - - public function testDropIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIndex('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "foo"', $statements[0]); - } - - public function testDropSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->dropSpatialIndex(['coordinates']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "geo_coordinates_spatialindex"', $statements[0]); - } - - public function testDropForeign() - { - $blueprint = new Blueprint('users'); - $blueprint->dropForeign('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); + $connection = m::mock(Connection::class); + $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); + return $connection; } - public function testDropTimestamps() + protected function getSchemaBuilder(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->dropTimestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop column "created_at", drop column "updated_at"', $statements[0]); - } - - public function testDropTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dropTimestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop column "created_at", drop column "updated_at"', $statements[0]); - } - - public function testDropMorphs() - { - $blueprint = new Blueprint('photos'); - $blueprint->dropMorphs('imageable'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('drop index "photos_imageable_type_imageable_id_index"', $statements[0]); - $this->assertSame('alter table "photos" drop column "imageable_type", drop column "imageable_id"', $statements[1]); - } - - public function testRenameTable() - { - $blueprint = new Blueprint('users'); - $blueprint->rename('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" rename to "foo"', $statements[0]); - } - - public function testRenameIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->renameIndex('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter index "foo" rename to "bar"', $statements[0]); - } - - public function testAddingPrimaryKey() - { - $blueprint = new Blueprint('users'); - $blueprint->primary('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add primary key ("foo")', $statements[0]); - } - - public function testAddingUniqueKey() - { - $blueprint = new Blueprint('users'); - $blueprint->unique('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add constraint "bar" unique ("foo")', $statements[0]); - } - - public function testAddingIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->index(['foo', 'bar'], 'baz'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "baz" on "users" ("foo", "bar")', $statements[0]); - } - - public function testAddingIndexWithAlgorithm() - { - $blueprint = new Blueprint('users'); - $blueprint->index(['foo', 'bar'], 'baz', 'hash'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "baz" on "users" using hash ("foo", "bar")', $statements[0]); - } - - public function testAddingFulltextIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->fulltext('body'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "users_body_fulltext" on "users" using gin ((to_tsvector(\'english\', "body")))', $statements[0]); - } - - public function testAddingFulltextIndexMultipleColumns() - { - $blueprint = new Blueprint('users'); - $blueprint->fulltext(['body', 'title']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "users_body_title_fulltext" on "users" using gin ((to_tsvector(\'english\', "body") || to_tsvector(\'english\', "title")))', $statements[0]); - } - - public function testAddingFulltextIndexWithLanguage() - { - $blueprint = new Blueprint('users'); - $blueprint->fulltext('body')->language('spanish'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "users_body_fulltext" on "users" using gin ((to_tsvector(\'spanish\', "body")))', $statements[0]); - } - - public function testAddingFulltextIndexWithFluency() - { - $blueprint = new Blueprint('users'); - $blueprint->string('body')->fulltext(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('create index "users_body_fulltext" on "users" using gin ((to_tsvector(\'english\', "body")))', $statements[1]); - } - - public function testAddingSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->spatialIndex('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "geo_coordinates_spatialindex" on "geo" using gist ("coordinates")', $statements[0]); - } - - public function testAddingFluentSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point')->spatialIndex(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('create index "geo_coordinates_spatialindex" on "geo" using gist ("coordinates")', $statements[1]); - } - - public function testAddingRawIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->rawIndex('(function(column))', 'raw_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "raw_index" on "users" ((function(column)))', $statements[0]); - } - - public function testAddingIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" serial not null primary key', $statements[0]); - } - - public function testAddingSmallIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->smallIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" smallserial not null primary key', $statements[0]); - } - - public function testAddingMediumIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" serial not null primary key', $statements[0]); - } - - public function testAddingID() - { - $blueprint = new Blueprint('users'); - $blueprint->id(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" bigserial not null primary key', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->id('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" bigserial not null primary key', $statements[0]); - } - - public function testAddingForeignID() - { - $blueprint = new Blueprint('users'); - $foreignId = $blueprint->foreignId('foo'); - $blueprint->foreignId('company_id')->constrained(); - $blueprint->foreignId('laravel_idea_id')->constrained(); - $blueprint->foreignId('team_id')->references('id')->on('teams'); - $blueprint->foreignId('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); - $this->assertSame([ - 'alter table "users" add column "foo" bigint not null, add column "company_id" bigint not null, add column "laravel_idea_id" bigint not null, add column "team_id" bigint not null, add column "team_column_id" bigint not null', - 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', - 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', - 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', - 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', - ], $statements); - } - - public function testAddingForeignIdSpecifyingIndexNameInConstraint() - { - $blueprint = new Blueprint('users'); - $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertSame([ - 'alter table "users" add column "company_id" bigint not null', - 'alter table "users" add constraint "my_index" foreign key ("company_id") references "companies" ("id")', - ], $statements); - } - - public function testAddingBigIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->bigIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" bigserial not null primary key', $statements[0]); - } - - public function testAddingString() - { - $blueprint = new Blueprint('users'); - $blueprint->string('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar(255) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar(100) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100)->nullable()->default('bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar(100) null default \'bar\'', $statements[0]); - } - - public function testAddingStringWithoutLengthLimit() - { - $blueprint = new Blueprint('users'); - $blueprint->string('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar(255) not null', $statements[0]); - - Builder::$defaultStringLength = null; - - $blueprint = new Blueprint('users'); - $blueprint->string('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - try { - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); - } finally { - Builder::$defaultStringLength = 255; - } + return $schemaBuilder; } - public function testAddingCharWithoutLengthLimit() + protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) { - $blueprint = new Blueprint('users'); - $blueprint->char('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" char(255) not null', $statements[0]); - - Builder::$defaultStringLength = null; - - $blueprint = new Blueprint('users'); - $blueprint->char('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - try { - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" char not null', $statements[0]); - } finally { - Builder::$defaultStringLength = 255; + $connection = $this->setupConnection($initialBlueprint); + if (is_null($blueprint)) { + $blueprint = $initialBlueprint; } + return $blueprint->toSql($connection, new PostgresGrammar); } - public function testAddingText() - { - $blueprint = new Blueprint('users'); - $blueprint->text('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); - } - - public function testAddingBigInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" bigint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" bigserial not null primary key', $statements[0]); - } - - public function testAddingInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->integer('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->integer('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" serial not null primary key', $statements[0]); - } - - public function testAddingMediumInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" serial not null primary key', $statements[0]); - } - - public function testAddingTinyInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" smallint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" smallserial not null primary key', $statements[0]); - } - - public function testAddingSmallInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" smallint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" smallserial not null primary key', $statements[0]); - } - - public function testAddingFloat() - { - $blueprint = new Blueprint('users'); - $blueprint->float('foo', 5); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" float(5) not null', $statements[0]); - } - - public function testAddingDouble() - { - $blueprint = new Blueprint('users'); - $blueprint->double('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" double precision not null', $statements[0]); - } - - public function testAddingDecimal() - { - $blueprint = new Blueprint('users'); - $blueprint->decimal('foo', 5, 2); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" decimal(5, 2) not null', $statements[0]); - } - - public function testAddingBoolean() - { - $blueprint = new Blueprint('users'); - $blueprint->boolean('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" boolean not null', $statements[0]); - } - - public function testAddingEnum() + public function testNoInitialModifiersAddNullable() { - $blueprint = new Blueprint('users'); - $blueprint->enum('role', ['member', 'admin']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name'); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "role" varchar(255) check ("role" in (\'member\', \'admin\')) not null', $statements[0]); - } - - public function testAddingDate() - { - $blueprint = new Blueprint('users'); - $blueprint->date('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" date not null', $statements[0]); - } - - public function testAddingYear() - { - $blueprint = new Blueprint('users'); - $blueprint->year('birth_year'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "birth_year" integer not null', $statements[0]); - } - - public function testAddingJson() - { - $blueprint = new Blueprint('users'); - $blueprint->json('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" json not null', $statements[0]); - } - - public function testAddingJsonb() - { - $blueprint = new Blueprint('users'); - $blueprint->jsonb('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" jsonb not null', $statements[0]); - } - - public function testAddingDateTime() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(0) without time zone not null', $statements[0]); - } - - public function testAddingDateTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(1) without time zone not null', $statements[0]); - } - - public function testAddingDateTimeWithNullPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at', null); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp without time zone not null', $statements[0]); - } - - public function testAddingDateTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(0) with time zone not null', $statements[0]); - } - - public function testAddingDateTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(1) with time zone not null', $statements[0]); - } - - public function testAddingDateTimeTzWithNullPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('created_at', null); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp with time zone not null', $statements[0]); - } - - public function testAddingTime() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time(0) without time zone not null', $statements[0]); - } - - public function testAddingTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time(1) without time zone not null', $statements[0]); - } - - public function testAddingTimeWithNullPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at', null); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time without time zone not null', $statements[0]); - } - - public function testAddingTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time(0) with time zone not null', $statements[0]); - } - - public function testAddingTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time(1) with time zone not null', $statements[0]); - } - - public function testAddingTimeTzWithNullPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at', null); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time with time zone not null', $statements[0]); - } - - public function testAddingTimestamp() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(0) without time zone not null', $statements[0]); - } + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add column "name" varchar(255) not null', $statements[0]); - public function testAddingTimestampWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(1) without time zone not null', $statements[0]); - } - - public function testAddingTimestampWithNullPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', null); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp without time zone not null', $statements[0]); - } - - public function testAddingTimestampTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(0) with time zone not null', $statements[0]); - } - - public function testAddingTimestampTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(1) with time zone not null', $statements[0]); - } - - public function testAddingTimestampTzWithNullPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at', null); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp with time zone not null', $statements[0]); - } - - public function testAddingTimestamps() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(0) without time zone null, add column "updated_at" timestamp(0) without time zone null', $statements[0]); - } - - public function testAddingTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" timestamp(0) with time zone null, add column "updated_at" timestamp(0) with time zone null', $statements[0]); - } - - public function testAddingBinary() - { - $blueprint = new Blueprint('users'); - $blueprint->binary('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" bytea not null', $statements[0]); - } - - public function testAddingUuid() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" uuid not null', $statements[0]); - } - - public function testAddingUuidDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "uuid" uuid not null', $statements[0]); - } - - public function testAddingForeignUuid() - { - $blueprint = new Blueprint('users'); - $foreignUuid = $blueprint->foreignUuid('foo'); - $blueprint->foreignUuid('company_id')->constrained(); - $blueprint->foreignUuid('laravel_idea_id')->constrained(); - $blueprint->foreignUuid('team_id')->references('id')->on('teams'); - $blueprint->foreignUuid('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid); - $this->assertSame([ - 'alter table "users" add column "foo" uuid not null, add column "company_id" uuid not null, add column "laravel_idea_id" uuid not null, add column "team_id" uuid not null, add column "team_column_id" uuid not null', - 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', - 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', - 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', - 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', - ], $statements); - } - - public function testAddingGeneratedAs() - { - $blueprint = new Blueprint('users'); - $blueprint->increments('foo')->generatedAs(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null generated by default as identity primary key', $statements[0]); - // With always modifier - $blueprint = new Blueprint('users'); - $blueprint->increments('foo')->generatedAs()->always(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null generated always as identity primary key', $statements[0]); - // With sequence options - $blueprint = new Blueprint('users'); - $blueprint->increments('foo')->generatedAs('increment by 10 start with 100'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null generated by default as identity (increment by 10 start with 100) primary key', $statements[0]); - // Not a primary key - $blueprint = new Blueprint('users'); - $blueprint->integer('foo')->generatedAs(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null generated by default as identity', $statements[0]); - } - - public function testAddingVirtualAs() - { - $blueprint = new Blueprint('users'); - $blueprint->integer('foo')->nullable(); - $blueprint->boolean('bar')->virtualAs('foo is not null'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->integer('foo')->nullable(); - $blueprint->boolean('bar')->virtualAs(new Expression('foo is not null')); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null)', $statements[0]); - } - - public function testAddingStoredAs() - { - $blueprint = new Blueprint('users'); - $blueprint->integer('foo')->nullable(); - $blueprint->boolean('bar')->storedAs('foo is not null'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null) stored', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->integer('foo')->nullable(); - $blueprint->boolean('bar')->storedAs(new Expression('foo is not null')); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer null, add column "bar" boolean not null generated always as (foo is not null) stored', $statements[0]); - } - - public function testAddingIpAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" inet not null', $statements[0]); - } - - public function testAddingIpAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->nullable()->change(); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "ip_address" inet not null', $statements[0]); - } - - public function testAddingMacAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" macaddr not null', $statements[0]); - } - - public function testAddingMacAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "mac_address" macaddr not null', $statements[0]); - } - - public function testCompileForeign() - { - $blueprint = new Blueprint('users'); - $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade deferrable', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable(false)->initiallyImmediate(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade not deferrable', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable()->initiallyImmediate(false); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade deferrable initially deferred', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable()->notValid(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add constraint "users_parent_id_foreign" foreign key ("parent_id") references "parents" ("id") on delete cascade deferrable not valid', $statements[0]); - } - - public function testAddingGeometry() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry not null', $statements[0]); - } - - public function testAddingGeography() - { - $blueprint = new Blueprint('geo'); - $blueprint->geography('coordinates', 'pointzm', 4269); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geography(pointzm,4269) not null', $statements[0]); - } - - public function testAddingPoint() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(point) not null', $statements[0]); - } - - public function testAddingPointWithSrid() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point', 4269); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(point,4269) not null', $statements[0]); - } - - public function testAddingLineString() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'linestring'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(linestring) not null', $statements[0]); - } - - public function testAddingPolygon() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'polygon'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(polygon) not null', $statements[0]); - } - - public function testAddingGeometryCollection() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'geometrycollection'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(geometrycollection) not null', $statements[0]); - } - - public function testAddingMultiPoint() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'multipoint'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(multipoint) not null', $statements[0]); - } - - public function testAddingMultiLineString() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'multilinestring'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(multilinestring) not null', $statements[0]); - } - - public function testAddingMultiPolygon() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'multipolygon'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry(multipolygon) not null', $statements[0]); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $parts = explode(', ', $statements[0]); + $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); + $this->assertSame('alter column "name" drop not null', $parts[1]); + $this->assertSame("alter column \"name\" drop default", $parts[2]); } - - public function testChangingColumn() + public function testNullableInitialModifierAddDefault() { - $blueprint = new Blueprint('users'); - $blueprint->string('name')->nullable(); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - $connection = $this->getConnection(); - $grammar = $this->getGrammar(); - - $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - - $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); - - $statements = $blueprint->toSql($connection, $grammar); - - $this->assertCount(1, $statements); + $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar(255) null', $statements[0]); - $changeBlueprint = new Blueprint('users'); - $changeBlueprint->string('name')->default('admin')->change(); - $statements = $changeBlueprint->toSql($connection, $grammar); - - $this->assertCount(2, $statements); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->change(); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); $parts = explode(', ', $statements[0]); $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); $this->assertSame('alter column "name" null', $parts[1]); $this->assertSame("alter column \"name\" set default 'admin'", $parts[2]); - - $otherChangeBlueprint = new Blueprint('users'); - $otherChangeBlueprint->string('name')->nullable(false)->change(); - $statements = $otherChangeBlueprint->toSql($connection, $grammar); - - $this->assertCount(2, $statements); - - $parts = explode(', ', $statements[0]); - $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); - $this->assertSame('alter column "name" set not null', $parts[1]); - } - - public function testCreateDatabase() - { - $connection = $this->getConnection(); - $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8_foo'); - $statement = $this->getGrammar()->compileCreateDatabase('my_database_a', $connection); - - $this->assertSame( - 'create database "my_database_a" encoding "utf8_foo"', - $statement - ); - - $connection = $this->getConnection(); - $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8_bar'); - $statement = $this->getGrammar()->compileCreateDatabase('my_database_b', $connection); - - $this->assertSame( - 'create database "my_database_b" encoding "utf8_bar"', - $statement - ); - } - - public function testDropDatabaseIfExists() - { - $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a'); - - $this->assertSame( - 'drop database if exists "my_database_a"', - $statement - ); - - $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b'); - - $this->assertSame( - 'drop database if exists "my_database_b"', - $statement - ); - } - - public function testDropAllTablesEscapesTableNames() - { - $statement = $this->getGrammar()->compileDropAllTables(['alpha', 'beta', 'gamma']); - - $this->assertSame('drop table "alpha","beta","gamma" cascade', $statement); } - public function testDropAllViewsEscapesTableNames() + public function testNullableInitialModifierAddDefaultNotNullable() { - $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']); - - $this->assertSame('drop view "alpha","beta","gamma" cascade', $statement); - } + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - public function testDropAllTypesEscapesTableNames() - { - $statement = $this->getGrammar()->compileDropAllTypes(['alpha', 'beta', 'gamma']); - - $this->assertSame('drop type "alpha","beta","gamma" cascade', $statement); - } - - protected function getConnection() - { - return m::mock(Connection::class); - } - - public function getGrammar() - { - return new PostgresGrammar; - } - - public function testGrammarsAreMacroable() - { - // compileReplace macro. - $this->getGrammar()::macro('compileReplace', function () { - return true; - }); + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add column "name" varchar(255) null', $statements[0]); - $c = $this->getGrammar()::compileReplace(); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - $this->assertTrue($c); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $parts = explode(', ', $statements[0]); + $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); + $this->assertSame('alter column "name" set not null', $parts[1]); + $this->assertSame("alter column \"name\" set default 'admin'", $parts[2]); } } diff --git a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php index c43c7d6fa..432d99ced 100644 --- a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php @@ -19,955 +19,75 @@ protected function tearDown(): void m::close(); } - public function testBasicCreateTable() + protected function setupConnection(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("id" integer primary key autoincrement not null, "email" varchar not null)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $expected = [ - 'alter table "users" add column "id" integer primary key autoincrement not null', - 'alter table "users" add column "email" varchar not null', - ]; - $this->assertEquals($expected, $statements); - } - - public function testCreateTemporaryTable() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->temporary(); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create temporary table "users" ("id" integer primary key autoincrement not null, "email" varchar not null)', $statements[0]); - } - - public function testDropTable() - { - $blueprint = new Blueprint('users'); - $blueprint->drop(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table "users"', $statements[0]); - } - - public function testDropTableIfExists() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIfExists(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table if exists "users"', $statements[0]); - } - - public function testDropUnique() - { - $blueprint = new Blueprint('users'); - $blueprint->dropUnique('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "foo"', $statements[0]); - } - - public function testDropIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIndex('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "foo"', $statements[0]); - } - - public function testDropColumn() - { - $db = new Manager; - - $db->addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => 'prefix_', - ]); - - $schema = $db->getConnection()->getSchemaBuilder(); - - $schema->create('users', function (Blueprint $table) { - $table->string('email'); - $table->string('name'); - }); - - $this->assertTrue($schema->hasTable('users')); - $this->assertTrue($schema->hasColumn('users', 'name')); - - $schema->table('users', function (Blueprint $table) { - $table->dropColumn('name'); - }); - - $this->assertFalse($schema->hasColumn('users', 'name')); - } - - public function testDropSpatialIndex() - { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('The database driver in use does not support spatial indexes.'); - - $blueprint = new Blueprint('geo'); - $blueprint->dropSpatialIndex(['coordinates']); - $blueprint->toSql($this->getConnection(), $this->getGrammar()); - } - - public function testRenameTable() - { - $blueprint = new Blueprint('users'); - $blueprint->rename('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" rename to "foo"', $statements[0]); - } - - public function testRenameIndex() - { - $db = new Manager; - - $db->addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => 'prefix_', - ]); - - $schema = $db->getConnection()->getSchemaBuilder(); - - $schema->create('users', function (Blueprint $table) { - $table->string('name'); - $table->string('email'); - }); - - $schema->table('users', function (Blueprint $table) { - $table->index(['name', 'email'], 'index1'); - }); - - $indexes = $schema->getIndexListing('users'); - - $this->assertContains('index1', $indexes); - $this->assertNotContains('index2', $indexes); - - $schema->table('users', function (Blueprint $table) { - $table->renameIndex('index1', 'index2'); - }); - - $this->assertFalse($schema->hasIndex('users', 'index1')); - $this->assertTrue(collect($schema->getIndexes('users'))->contains( - fn ($index) => $index['name'] === 'index2' && $index['columns'] === ['name', 'email'] - )); - } - - public function testAddingPrimaryKey() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('foo')->primary(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("foo" varchar not null, primary key ("foo"))', $statements[0]); - } - - public function testAddingForeignKey() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('foo')->primary(); - $blueprint->string('order_id'); - $blueprint->foreign('order_id')->references('id')->on('orders'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("foo" varchar not null, "order_id" varchar not null, foreign key("order_id") references "orders"("id"), primary key ("foo"))', $statements[0]); - } - - public function testAddingUniqueKey() - { - $blueprint = new Blueprint('users'); - $blueprint->unique('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create unique index "bar" on "users" ("foo")', $statements[0]); - } - - public function testAddingIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->index(['foo', 'bar'], 'baz'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "baz" on "users" ("foo", "bar")', $statements[0]); - } - - public function testAddingSpatialIndex() - { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('The database driver in use does not support spatial indexes.'); - - $blueprint = new Blueprint('geo'); - $blueprint->spatialIndex('coordinates'); - $blueprint->toSql($this->getConnection(), $this->getGrammar()); - } - - public function testAddingFluentSpatialIndex() - { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('The database driver in use does not support spatial indexes.'); - - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates')->spatialIndex(); - $blueprint->toSql($this->getConnection(), $this->getGrammar()); - } - - public function testAddingRawIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->rawIndex('(function(column))', 'raw_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "raw_index" on "users" ((function(column)))', $statements[0]); - } - - public function testAddingIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingSmallIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->smallIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingMediumIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingID() - { - $blueprint = new Blueprint('users'); - $blueprint->id(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->id('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingForeignID() - { - $blueprint = new Blueprint('users'); - $foreignId = $blueprint->foreignId('foo'); - $blueprint->foreignId('company_id')->constrained(); - $blueprint->foreignId('laravel_idea_id')->constrained(); - $blueprint->foreignId('team_id')->references('id')->on('teams'); - $blueprint->foreignId('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); - $this->assertSame([ - 'alter table "users" add column "foo" integer not null', - 'alter table "users" add column "company_id" integer not null', - 'alter table "users" add column "laravel_idea_id" integer not null', - 'alter table "users" add column "team_id" integer not null', - 'alter table "users" add column "team_column_id" integer not null', - ], $statements); - } - - public function testAddingForeignIdSpecifyingIndexNameInConstraint() - { - $blueprint = new Blueprint('users'); - $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertSame([ - 'alter table "users" add column "company_id" integer not null', - ], $statements); - } - - public function testAddingBigIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->bigIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "id" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingString() - { - $blueprint = new Blueprint('users'); - $blueprint->string('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100)->nullable()->default('bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar default \'bar\'', $statements[0]); - } - - public function testAddingText() - { - $blueprint = new Blueprint('users'); - $blueprint->text('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); - } - - public function testAddingBigInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->integer('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->integer('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingMediumInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingTinyInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingSmallInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" integer primary key autoincrement not null', $statements[0]); - } - - public function testAddingFloat() - { - $blueprint = new Blueprint('users'); - $blueprint->float('foo', 5); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" float not null', $statements[0]); - } - - public function testAddingDouble() - { - $blueprint = new Blueprint('users'); - $blueprint->double('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" double not null', $statements[0]); - } - - public function testAddingDecimal() - { - $blueprint = new Blueprint('users'); - $blueprint->decimal('foo', 5, 2); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" numeric not null', $statements[0]); - } - - public function testAddingBoolean() - { - $blueprint = new Blueprint('users'); - $blueprint->boolean('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" tinyint(1) not null', $statements[0]); - } - - public function testAddingEnum() - { - $blueprint = new Blueprint('users'); - $blueprint->enum('role', ['member', 'admin']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "role" varchar check ("role" in (\'member\', \'admin\')) not null', $statements[0]); - } - - public function testAddingJson() - { - $blueprint = new Blueprint('users'); - $blueprint->json('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); - } - - public function testAddingJsonb() - { - $blueprint = new Blueprint('users'); - $blueprint->jsonb('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" text not null', $statements[0]); - } - - public function testAddingDate() - { - $blueprint = new Blueprint('users'); - $blueprint->date('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" date not null', $statements[0]); - } - - public function testAddingYear() - { - $blueprint = new Blueprint('users'); - $blueprint->year('birth_year'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "birth_year" integer not null', $statements[0]); - } - - public function testAddingDateTime() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingDateTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingDateTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingDateTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingTime() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); - } - - public function testAddingTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); - } - - public function testAddingTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); - } - - public function testAddingTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" time not null', $statements[0]); - } - - public function testAddingTimestamp() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingTimestampWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingTimestampTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingTimestampTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "created_at" datetime not null', $statements[0]); - } - - public function testAddingTimestamps() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(2, $statements); - $this->assertEquals([ - 'alter table "users" add column "created_at" datetime', - 'alter table "users" add column "updated_at" datetime', - ], $statements); - } - - public function testAddingTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(2, $statements); - $this->assertEquals([ - 'alter table "users" add column "created_at" datetime', - 'alter table "users" add column "updated_at" datetime', - ], $statements); - } - - public function testAddingRememberToken() - { - $blueprint = new Blueprint('users'); - $blueprint->rememberToken(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "remember_token" varchar', $statements[0]); - } - - public function testAddingBinary() - { - $blueprint = new Blueprint('users'); - $blueprint->binary('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" blob not null', $statements[0]); - } - - public function testAddingUuid() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); - } - - public function testAddingUuidDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "uuid" varchar not null', $statements[0]); - } - - public function testAddingForeignUuid() - { - $blueprint = new Blueprint('users'); - $foreignUuid = $blueprint->foreignUuid('foo'); - $blueprint->foreignUuid('company_id')->constrained(); - $blueprint->foreignUuid('laravel_idea_id')->constrained(); - $blueprint->foreignUuid('team_id')->references('id')->on('teams'); - $blueprint->foreignUuid('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid); - $this->assertSame([ - 'alter table "users" add column "foo" varchar not null', - 'alter table "users" add column "company_id" varchar not null', - 'alter table "users" add column "laravel_idea_id" varchar not null', - 'alter table "users" add column "team_id" varchar not null', - 'alter table "users" add column "team_column_id" varchar not null', - ], $statements); - } - - public function testAddingIpAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); - } - - public function testAddingIpAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "ip_address" varchar not null', $statements[0]); - } - - public function testAddingMacAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "foo" varchar not null', $statements[0]); - } - - public function testAddingMacAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "mac_address" varchar not null', $statements[0]); - } - - public function testAddingGeometry() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add column "coordinates" geometry not null', $statements[0]); - } - - public function testAddingGeneratedColumn() - { - $blueprint = new Blueprint('products'); - $blueprint->create(); - $blueprint->integer('price'); - $blueprint->integer('discounted_virtual')->virtualAs('"price" - 5'); - $blueprint->integer('discounted_stored')->storedAs('"price" - 5'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "products" ("price" integer not null, "discounted_virtual" integer as ("price" - 5), "discounted_stored" integer as ("price" - 5) stored)', $statements[0]); - - $blueprint = new Blueprint('products'); - $blueprint->integer('price'); - $blueprint->integer('discounted_virtual')->virtualAs('"price" - 5')->nullable(false); - $blueprint->integer('discounted_stored')->storedAs('"price" - 5')->nullable(false); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(3, $statements); - $expected = [ - 'alter table "products" add column "price" integer not null', - 'alter table "products" add column "discounted_virtual" integer not null as ("price" - 5)', - 'alter table "products" add column "discounted_stored" integer not null as ("price" - 5) stored', - ]; - $this->assertSame($expected, $statements); - } - - public function testAddingGeneratedColumnByExpression() - { - $blueprint = new Blueprint('products'); - $blueprint->create(); - $blueprint->integer('price'); - $blueprint->integer('discounted_virtual')->virtualAs(new Expression('"price" - 5')); - $blueprint->integer('discounted_stored')->storedAs(new Expression('"price" - 5')); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "products" ("price" integer not null, "discounted_virtual" integer as ("price" - 5), "discounted_stored" integer as ("price" - 5) stored)', $statements[0]); + $connection = m::mock(Connection::class); + $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); + $connection->shouldReceive('scalar')->andReturn(''); + return $connection; } - public function testChangingColumn() + protected function getSchemaBuilder(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->string('name')->nullable(); - - $connection = $this->getConnection(); - $grammar = $this->getGrammar(); - $schemaBuilder = m::mock(Builder::class); $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); $schemaBuilder->shouldReceive('getForeignKeys')->andReturn([]); $schemaBuilder->shouldReceive('getIndexes')->andReturn([]); - $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); - $connection->shouldReceive('scalar')->andReturn(''); - - $statements = $blueprint->toSql($connection, $grammar); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add column "name" varchar', $statements[0]); - - $changeBlueprint = new Blueprint('users'); - $changeBlueprint->string('name')->default('admin')->change(); - $statements = $changeBlueprint->toSql($connection, $grammar); - - $this->assertCount(4, $statements); - $this->assertStringContainsString("varchar default 'admin'", $statements[0]); - - $otherChangeBlueprint = new Blueprint('users'); - $otherChangeBlueprint->string('name')->nullable(false)->change(); - $statements = $otherChangeBlueprint->toSql($connection, $grammar); - - $this->assertCount(4, $statements); - $this->assertStringContainsString("varchar not null", $statements[0]); + return $schemaBuilder; } - public function testGrammarsAreMacroable() + protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) { - // compileReplace macro. - $this->getGrammar()::macro('compileReplace', function () { - return true; - }); - - $c = $this->getGrammar()::compileReplace(); - - $this->assertTrue($c); + $connection = $this->setupConnection($initialBlueprint); + if (is_null($blueprint)) { + $blueprint = $initialBlueprint; + } + return $blueprint->toSql($connection, new SQLiteGrammar); } - public function testCreateTableWithVirtualAsColumn() + public function testNoInitialModifiersAddNullable() { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_column'); - $blueprint->string('my_other_column')->virtualAs('my_column'); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add column "name" varchar not null', $statements[0]); - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("my_column" varchar not null, "my_other_column" varchar as (my_column))', $statements[0]); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->nullable()->change(); - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"\')))', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"."nested"\')))', $statements[0]); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $this->assertStringContainsString('"name" varchar', $statements[0]); } - public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey() + public function testNullableInitialModifierAddDefault() { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]'); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - $conn = $this->getConnection(); - $conn->shouldReceive('getConfig')->andReturn(null); + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add column "name" varchar', $statements[0]); - $statements = $blueprint->toSql($conn, $this->getGrammar()); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->change(); - $this->assertCount(1, $statements); - $this->assertSame("create table \"users\" (\"my_json_column\" varchar as (json_extract(\"my_json_column\", '$.\"foo\"[0][1]')))", $statements[0]); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $this->assertStringContainsString("varchar default 'admin'", $statements[0]); } - public function testCreateTableWithStoredAsColumn() + public function testNullableInitialModifierAddDefaultNotNullable() { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_column'); - $blueprint->string('my_other_column')->storedAs('my_column'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("my_column" varchar not null, "my_other_column" varchar as (my_column) stored)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute'); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"\')) stored)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->string('my_json_column'); - $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("my_json_column" varchar not null, "my_other_column" varchar as (json_extract("my_json_column", \'$."some_attribute"."nested"\')) stored)', $statements[0]); - } + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add column "name" varchar', $statements[0]); - protected function getConnection() - { - return m::mock(Connection::class); - } + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - public function getGrammar() - { - return new SQLiteGrammar; + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $this->assertStringContainsString("\"name\" varchar not null default 'admin'", $statements[0]); } } diff --git a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php index 0adf8dc45..d68702df2 100644 --- a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php @@ -17,950 +17,74 @@ protected function tearDown(): void m::close(); } - public function testBasicCreateTable() + protected function setupConnection(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("id" int not null identity primary key, "email" nvarchar(255) not null)', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "id" int not null identity primary key, "email" nvarchar(255) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()->setTablePrefix('prefix_')); - - $this->assertCount(1, $statements); - $this->assertSame('create table "prefix_users" ("id" int not null identity primary key, "email" nvarchar(255) not null)', $statements[0]); - } - - public function testCreateTemporaryTable() - { - $blueprint = new Blueprint('users'); - $blueprint->create(); - $blueprint->temporary(); - $blueprint->increments('id'); - $blueprint->string('email'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create table "#users" ("id" int not null identity primary key, "email" nvarchar(255) not null)', $statements[0]); - } - - public function testDropTable() - { - $blueprint = new Blueprint('users'); - $blueprint->drop(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop table "users"', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->drop(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()->setTablePrefix('prefix_')); - - $this->assertCount(1, $statements); - $this->assertSame('drop table "prefix_users"', $statements[0]); - } - - public function testDropTableIfExists() - { - $blueprint = new Blueprint('users'); - $blueprint->dropIfExists(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('if object_id(N\'"users"\', \'U\') is not null drop table "users"', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropIfExists(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()->setTablePrefix('prefix_')); - - $this->assertCount(1, $statements); - $this->assertSame('if object_id(N\'"prefix_users"\', \'U\') is not null drop table "prefix_users"', $statements[0]); - } - - public function testDropColumn() - { - $blueprint = new Blueprint('users'); - $blueprint->dropColumn('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertStringContainsString('alter table "users" drop column "foo"', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropColumn(['foo', 'bar']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertStringContainsString('alter table "users" drop column "foo", "bar"', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->dropColumn('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertStringContainsString('alter table "users" drop column "foo", "bar"', $statements[0]); - } - - public function testDropColumnDropsCreatesSqlToDropDefaultConstraints() - { - $blueprint = new Blueprint('foo'); - $blueprint->dropColumn('bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame("DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \"foo\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\"foo\"') AND [name] in ('bar') AND [default_object_id] <> 0;EXEC(@sql);alter table \"foo\" drop column \"bar\"", $statements[0]); - } - - public function testDropPrimary() - { - $blueprint = new Blueprint('users'); - $blueprint->dropPrimary('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); - } - - public function testDropUnique() - { - $blueprint = new Blueprint('users'); - $blueprint->dropUnique('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "foo" on "users"', $statements[0]); + $connection = m::mock(Connection::class); + $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); + return $connection; } - public function testDropIndex() + protected function getSchemaBuilder(Blueprint $blueprint) { - $blueprint = new Blueprint('users'); - $blueprint->dropIndex('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "foo" on "users"', $statements[0]); - } - - public function testDropSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->dropSpatialIndex(['coordinates']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('drop index "geo_coordinates_spatialindex" on "geo"', $statements[0]); - } - - public function testDropForeign() - { - $blueprint = new Blueprint('users'); - $blueprint->dropForeign('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" drop constraint "foo"', $statements[0]); - } - - public function testDropConstrainedForeignId() - { - $blueprint = new Blueprint('users'); - $blueprint->dropConstrainedForeignId('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('alter table "users" drop constraint "users_foo_foreign"', $statements[0]); - $this->assertSame('DECLARE @sql NVARCHAR(MAX) = \'\';SELECT @sql += \'ALTER TABLE "users" DROP CONSTRAINT \' + OBJECT_NAME([default_object_id]) + \';\' FROM sys.columns WHERE [object_id] = OBJECT_ID(N\'"users"\') AND [name] in (\'foo\') AND [default_object_id] <> 0;EXEC(@sql);alter table "users" drop column "foo"', $statements[1]); - } - - public function testDropTimestamps() - { - $blueprint = new Blueprint('users'); - $blueprint->dropTimestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertStringContainsString('alter table "users" drop column "created_at", "updated_at"', $statements[0]); - } - - public function testDropTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dropTimestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertStringContainsString('alter table "users" drop column "created_at", "updated_at"', $statements[0]); - } - - public function testDropMorphs() - { - $blueprint = new Blueprint('photos'); - $blueprint->dropMorphs('imageable'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('drop index "photos_imageable_type_imageable_id_index" on "photos"', $statements[0]); - $this->assertStringContainsString('alter table "photos" drop column "imageable_type", "imageable_id"', $statements[1]); - } - - public function testRenameTable() - { - $blueprint = new Blueprint('users'); - $blueprint->rename('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('sp_rename N\'"users"\', "foo"', $statements[0]); - } - - public function testRenameIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->renameIndex('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('sp_rename N\'"users"."foo"\', "bar", N\'INDEX\'', $statements[0]); - } - - public function testAddingPrimaryKey() - { - $blueprint = new Blueprint('users'); - $blueprint->primary('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add constraint "bar" primary key ("foo")', $statements[0]); - } - - public function testAddingUniqueKey() - { - $blueprint = new Blueprint('users'); - $blueprint->unique('foo', 'bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create unique index "bar" on "users" ("foo")', $statements[0]); - } - - public function testAddingIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->index(['foo', 'bar'], 'baz'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "baz" on "users" ("foo", "bar")', $statements[0]); - } - - public function testAddingSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->spatialIndex('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create spatial index "geo_coordinates_spatialindex" on "geo" ("coordinates")', $statements[0]); - } - - public function testAddingFluentSpatialIndex() - { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates', 'point')->spatialIndex(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(2, $statements); - $this->assertSame('create spatial index "geo_coordinates_spatialindex" on "geo" ("coordinates")', $statements[1]); - } - - public function testAddingRawIndex() - { - $blueprint = new Blueprint('users'); - $blueprint->rawIndex('(function(column))', 'raw_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('create index "raw_index" on "users" ((function(column)))', $statements[0]); - } - - public function testAddingIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->increments('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "id" int not null identity primary key', $statements[0]); - } - - public function testAddingSmallIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->smallIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "id" smallint not null identity primary key', $statements[0]); - } - - public function testAddingMediumIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "id" int not null identity primary key', $statements[0]); - } - - public function testAddingID() - { - $blueprint = new Blueprint('users'); - $blueprint->id(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "id" bigint not null identity primary key', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->id('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" bigint not null identity primary key', $statements[0]); - } - - public function testAddingForeignID() - { - $blueprint = new Blueprint('users'); - $foreignId = $blueprint->foreignId('foo'); - $blueprint->foreignId('company_id')->constrained(); - $blueprint->foreignId('laravel_idea_id')->constrained(); - $blueprint->foreignId('team_id')->references('id')->on('teams'); - $blueprint->foreignId('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); - $this->assertSame([ - 'alter table "users" add "foo" bigint not null, "company_id" bigint not null, "laravel_idea_id" bigint not null, "team_id" bigint not null, "team_column_id" bigint not null', - 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', - 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', - 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', - 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', - ], $statements); - } - - public function testAddingForeignIdSpecifyingIndexNameInConstraint() - { - $blueprint = new Blueprint('users'); - $blueprint->foreignId('company_id')->constrained(indexName: 'my_index'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertSame([ - 'alter table "users" add "company_id" bigint not null', - 'alter table "users" add constraint "my_index" foreign key ("company_id") references "companies" ("id")', - ], $statements); - } - - public function testAddingBigIncrementingID() - { - $blueprint = new Blueprint('users'); - $blueprint->bigIncrements('id'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "id" bigint not null identity primary key', $statements[0]); - } - - public function testAddingString() - { - $blueprint = new Blueprint('users'); - $blueprint->string('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(255) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(100) not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->string('foo', 100)->nullable()->default('bar'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(100) null default \'bar\'', $statements[0]); - } - - public function testAddingText() - { - $blueprint = new Blueprint('users'); - $blueprint->text('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(max) not null', $statements[0]); - } - - public function testAddingBigInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" bigint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->bigInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" bigint not null identity primary key', $statements[0]); - } - - public function testAddingInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->integer('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" int not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->integer('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" int not null identity primary key', $statements[0]); - } - - public function testAddingMediumInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" int not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->mediumInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" int not null identity primary key', $statements[0]); - } - - public function testAddingTinyInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" tinyint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->tinyInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" tinyint not null identity primary key', $statements[0]); - } - - public function testAddingSmallInteger() - { - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" smallint not null', $statements[0]); - - $blueprint = new Blueprint('users'); - $blueprint->smallInteger('foo', true); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" smallint not null identity primary key', $statements[0]); - } - - public function testAddingFloat() - { - $blueprint = new Blueprint('users'); - $blueprint->float('foo', 5); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" float(5) not null', $statements[0]); - } - - public function testAddingDouble() - { - $blueprint = new Blueprint('users'); - $blueprint->double('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" double precision not null', $statements[0]); - } - - public function testAddingDecimal() - { - $blueprint = new Blueprint('users'); - $blueprint->decimal('foo', 5, 2); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" decimal(5, 2) not null', $statements[0]); - } - - public function testAddingBoolean() - { - $blueprint = new Blueprint('users'); - $blueprint->boolean('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" bit not null', $statements[0]); - } - - public function testAddingEnum() - { - $blueprint = new Blueprint('users'); - $blueprint->enum('role', ['member', 'admin']); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "role" nvarchar(255) check ("role" in (N\'member\', N\'admin\')) not null', $statements[0]); - } - - public function testAddingJson() - { - $blueprint = new Blueprint('users'); - $blueprint->json('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(max) not null', $statements[0]); - } - - public function testAddingJsonb() - { - $blueprint = new Blueprint('users'); - $blueprint->jsonb('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(max) not null', $statements[0]); - } - - public function testAddingDate() - { - $blueprint = new Blueprint('users'); - $blueprint->date('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" date not null', $statements[0]); - } - - public function testAddingYear() - { - $blueprint = new Blueprint('users'); - $blueprint->year('birth_year'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "birth_year" int not null', $statements[0]); - } - - public function testAddingDateTime() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetime not null', $statements[0]); - } - - public function testAddingDateTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTime('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetime2(1) not null', $statements[0]); - } - - public function testAddingDateTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" datetimeoffset not null', $statements[0]); - } - - public function testAddingDateTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->dateTimeTz('foo', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" datetimeoffset(1) not null', $statements[0]); - } - - public function testAddingTime() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" time not null', $statements[0]); - } - - public function testAddingTimeWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->time('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" time(1) not null', $statements[0]); - } - - public function testAddingTimeTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" time not null', $statements[0]); - } - - public function testAddingTimeTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timeTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" time(1) not null', $statements[0]); - } - - public function testAddingTimestamp() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetime not null', $statements[0]); - } - - public function testAddingTimestampWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamp('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetime2(1) not null', $statements[0]); - } - - public function testAddingTimestampTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetimeoffset not null', $statements[0]); - } - - public function testAddingTimestampTzWithPrecision() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampTz('created_at', 1); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetimeoffset(1) not null', $statements[0]); - } - - public function testAddingTimestamps() - { - $blueprint = new Blueprint('users'); - $blueprint->timestamps(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetime null, "updated_at" datetime null', $statements[0]); - } - - public function testAddingTimestampsTz() - { - $blueprint = new Blueprint('users'); - $blueprint->timestampsTz(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "created_at" datetimeoffset null, "updated_at" datetimeoffset null', $statements[0]); - } - - public function testAddingRememberToken() - { - $blueprint = new Blueprint('users'); - $blueprint->rememberToken(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "remember_token" nvarchar(100) null', $statements[0]); - } - - public function testAddingBinary() - { - $blueprint = new Blueprint('users'); - $blueprint->binary('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" varbinary(max) not null', $statements[0]); - } - - public function testAddingUuid() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" uniqueidentifier not null', $statements[0]); - } - - public function testAddingUuidDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->uuid(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "uuid" uniqueidentifier not null', $statements[0]); - } - - public function testAddingForeignUuid() - { - $blueprint = new Blueprint('users'); - $foreignId = $blueprint->foreignUuid('foo'); - $blueprint->foreignUuid('company_id')->constrained(); - $blueprint->foreignUuid('laravel_idea_id')->constrained(); - $blueprint->foreignUuid('team_id')->references('id')->on('teams'); - $blueprint->foreignUuid('team_column_id')->constrained('teams'); - - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); - $this->assertSame([ - 'alter table "users" add "foo" uniqueidentifier not null, "company_id" uniqueidentifier not null, "laravel_idea_id" uniqueidentifier not null, "team_id" uniqueidentifier not null, "team_column_id" uniqueidentifier not null', - 'alter table "users" add constraint "users_company_id_foreign" foreign key ("company_id") references "companies" ("id")', - 'alter table "users" add constraint "users_laravel_idea_id_foreign" foreign key ("laravel_idea_id") references "laravel_ideas" ("id")', - 'alter table "users" add constraint "users_team_id_foreign" foreign key ("team_id") references "teams" ("id")', - 'alter table "users" add constraint "users_team_column_id_foreign" foreign key ("team_column_id") references "teams" ("id")', - ], $statements); - } - - public function testAddingIpAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(45) not null', $statements[0]); - } - - public function testAddingIpAddressDefaultsColumnName() - { - $blueprint = new Blueprint('users'); - $blueprint->ipAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "ip_address" nvarchar(45) not null', $statements[0]); - } - - public function testAddingMacAddress() - { - $blueprint = new Blueprint('users'); - $blueprint->macAddress('foo'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "foo" nvarchar(17) not null', $statements[0]); + return $schemaBuilder; } - public function testAddingMacAddressDefaultsColumnName() + protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) { - $blueprint = new Blueprint('users'); - $blueprint->macAddress(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - - $this->assertCount(1, $statements); - $this->assertSame('alter table "users" add "mac_address" nvarchar(17) not null', $statements[0]); + $connection = $this->setupConnection($initialBlueprint); + if (is_null($blueprint)) { + $blueprint = $initialBlueprint; + } + return $blueprint->toSql($connection, new SqlServerGrammar); } - public function testAddingGeometry() + public function testNoInitialModifiersAddNullable() { - $blueprint = new Blueprint('geo'); - $blueprint->geometry('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name'); - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add "coordinates" geometry not null', $statements[0]); - } + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add "name" nvarchar(255) not null', $statements[0]); - public function testAddingGeography() - { - $blueprint = new Blueprint('geo'); - $blueprint->geography('coordinates'); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->nullable()->change(); - $this->assertCount(1, $statements); - $this->assertSame('alter table "geo" add "coordinates" geography not null', $statements[0]); - } - - public function testAddingGeneratedColumn() - { - $blueprint = new Blueprint('products'); - $blueprint->integer('price'); - $blueprint->computed('discounted_virtual', 'price - 5'); - $blueprint->computed('discounted_stored', 'price - 5')->persisted(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]); - - $blueprint = new Blueprint('products'); - $blueprint->integer('price'); - $blueprint->computed('discounted_virtual', new Expression('price - 5')); - $blueprint->computed('discounted_stored', new Expression('price - 5'))->persisted(); - $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); - $this->assertCount(1, $statements); - $this->assertSame('alter table "products" add "price" int not null, "discounted_virtual" as (price - 5), "discounted_stored" as (price - 5) persisted', $statements[0]); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $this->assertSame('alter table "users" alter column "name" nvarchar(255) null', $statements[1]); } - public function testChangingColumn() + public function testNullableInitialModifierAddDefault() { - $blueprint = new Blueprint('users'); - $blueprint->string('name')->nullable(); - - $connection = $this->getConnection(); - $grammar = $this->getGrammar(); - - $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - - $connection->shouldReceive('getSchemaBuilder')->andReturn($schemaBuilder); - - $statements = $blueprint->toSql($connection, $grammar); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - $this->assertCount(1, $statements); + $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add "name" nvarchar(255) null', $statements[0]); - $changeBlueprint = new Blueprint('users'); - $changeBlueprint->string('name')->default('admin')->change(); - $statements = $changeBlueprint->toSql($connection, $grammar); + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->change(); - $this->assertCount(3, $statements); + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); $this->assertSame('alter table "users" alter column "name" nvarchar(255) null', $statements[1]); $this->assertSame('alter table "users" add default \'admin\' for "name"', $statements[2]); - - $otherChangeBlueprint = new Blueprint('users'); - $otherChangeBlueprint->string('name')->nullable(false)->change(); - $statements = $otherChangeBlueprint->toSql($connection, $grammar); - - $this->assertCount(2, $statements); - $this->assertSame('alter table "users" alter column "name" nvarchar(255) not null', $statements[1]); - } - - public function testGrammarsAreMacroable() - { - // compileReplace macro. - $this->getGrammar()::macro('compileReplace', function () { - return true; - }); - - $c = $this->getGrammar()::compileReplace(); - - $this->assertTrue($c); - } - - public function testQuoteString() - { - $this->assertSame("N'中文測試'", $this->getGrammar()->quoteString('中文測試')); - } - - public function testQuoteStringOnArray() - { - $this->assertSame("N'中文', N'測試'", $this->getGrammar()->quoteString(['中文', '測試'])); - } - - public function testCreateDatabase() - { - $connection = $this->getConnection(); - - $statement = $this->getGrammar()->compileCreateDatabase('my_database_a', $connection); - - $this->assertSame( - 'create database "my_database_a"', - $statement - ); - - $statement = $this->getGrammar()->compileCreateDatabase('my_database_b', $connection); - - $this->assertSame( - 'create database "my_database_b"', - $statement - ); } - public function testDropDatabaseIfExists() + public function testNullableInitialModifierAddDefaultNotNullable() { - $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a'); - - $this->assertSame( - 'drop database if exists "my_database_a"', - $statement - ); - - $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b'); + $initialBlueprint = new Blueprint('users'); + $initialBlueprint->string('name')->nullable(); - $this->assertSame( - 'drop database if exists "my_database_b"', - $statement - ); - } + $statements = $this->runBlueprint($initialBlueprint); + $this->assertSame('alter table "users" add "name" nvarchar(255) null', $statements[0]); - protected function getConnection() - { - return m::mock(Connection::class); - } + $changedBlueprint = new Blueprint('users'); + $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - public function getGrammar() - { - return new SqlServerGrammar; + $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $this->assertSame('alter table "users" alter column "name" nvarchar(255) not null', $statements[1]); + $this->assertSame('alter table "users" add default \'admin\' for "name"', $statements[2]); } } From 63427a3db51c7f7a8f04e0961c70e9903bb578c0 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 7 Apr 2024 12:25:15 -0400 Subject: [PATCH 052/111] use new GrammarTestCase to simplify tests --- composer.json | 3 +- .../Grammars/MySqlSchemaGrammarTest.php | 48 +++++------------- .../Grammars/PostgresSchemaGrammarTest.php | 45 ++++------------- .../Grammars/SQLiteSchemaGrammarTest.php | 49 ++++--------------- .../Grammars/SqlServerSchemaGrammarTest.php | 44 ++++------------- tests/GrammarTestCase.php | 42 ++++++++++++++++ 6 files changed, 85 insertions(+), 146 deletions(-) create mode 100644 tests/GrammarTestCase.php diff --git a/composer.json b/composer.json index 27cd5cc24..a178e4911 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,8 @@ "autoload-dev": { "classmap": [ "tests/TestCase.php", - "tests/DbTestCase.php" + "tests/DbTestCase.php", + "tests/GrammarTestCase.php" ], "psr-4": { "Winter\\Storm\\Tests\\": "tests/" diff --git a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php index ab7963141..38ed92813 100644 --- a/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/MySqlSchemaGrammarTest.php @@ -1,52 +1,24 @@ shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); - return $connection; - } - - protected function getSchemaBuilder(Blueprint $blueprint) - { - $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - - return $schemaBuilder; - } - - protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) - { - $connection = $this->setupConnection($initialBlueprint); - if (is_null($blueprint)) { - $blueprint = $initialBlueprint; - } - return $blueprint->toSql($connection, new MySqlGrammar); + $this->grammar = new MySqlGrammar; } public function testNoInitialModifiersAddNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name'); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table `users` add `name` varchar(255) not null', $statements[0]); @@ -54,7 +26,7 @@ public function testNoInitialModifiersAddNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->nullable()->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertSame("alter table `users` modify `name` varchar(255) null", $statements[0]); } @@ -62,6 +34,7 @@ public function testNullableInitialModifierAddDefault() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); @@ -69,7 +42,7 @@ public function testNullableInitialModifierAddDefault() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertSame("alter table `users` modify `name` varchar(255) null default 'admin'", $statements[0]); } @@ -77,6 +50,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table `users` add `name` varchar(255) null', $statements[0]); @@ -84,7 +58,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertSame("alter table `users` modify `name` varchar(255) not null default 'admin'", $statements[0]); } } diff --git a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php index 474f0858f..dbf137158 100644 --- a/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/PostgresSchemaGrammarTest.php @@ -2,50 +2,23 @@ namespace Winter\Storm\Tests\Database\Schema\Grammars; -use Illuminate\Database\Connection; -use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\Builder; -use Illuminate\Database\Schema\ForeignIdColumnDefinition; use Winter\Storm\Database\Schema\Grammars\PostgresGrammar; -use Mockery as m; -use PHPUnit\Framework\TestCase; -class PostgresSchemaGrammarTest extends TestCase +class PostgresSchemaGrammarTest extends \GrammarTestCase { - protected function tearDown(): void + public function setUp(): void { - m::close(); - } + parent::setUp(); - protected function setupConnection(Blueprint $blueprint) - { - $connection = m::mock(Connection::class); - $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); - return $connection; - } - - protected function getSchemaBuilder(Blueprint $blueprint) - { - $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - - return $schemaBuilder; - } - - protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) - { - $connection = $this->setupConnection($initialBlueprint); - if (is_null($blueprint)) { - $blueprint = $initialBlueprint; - } - return $blueprint->toSql($connection, new PostgresGrammar); + $this->grammar = new PostgresGrammar; } public function testNoInitialModifiersAddNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name'); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar(255) not null', $statements[0]); @@ -53,7 +26,7 @@ public function testNoInitialModifiersAddNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->nullable()->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $parts = explode(', ', $statements[0]); $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); $this->assertSame('alter column "name" drop not null', $parts[1]); @@ -63,6 +36,7 @@ public function testNullableInitialModifierAddDefault() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar(255) null', $statements[0]); @@ -70,7 +44,7 @@ public function testNullableInitialModifierAddDefault() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $parts = explode(', ', $statements[0]); $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); $this->assertSame('alter column "name" null', $parts[1]); @@ -81,6 +55,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar(255) null', $statements[0]); @@ -88,7 +63,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $parts = explode(', ', $statements[0]); $this->assertSame('alter table "users" alter column "name" type varchar(255)', $parts[0]); $this->assertSame('alter column "name" set not null', $parts[1]); diff --git a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php index 432d99ced..8d6b8c979 100644 --- a/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SQLiteSchemaGrammarTest.php @@ -2,54 +2,23 @@ namespace Winter\Storm\Tests\Database\Schema\Grammars; -use Illuminate\Database\Capsule\Manager; -use Illuminate\Database\Connection; -use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\ForeignIdColumnDefinition; use Winter\Storm\Database\Schema\Grammars\SQLiteGrammar; -use Mockery as m; -use PHPUnit\Framework\TestCase; -use RuntimeException; -class SQLiteSchemaGrammarTest extends TestCase +class SQLiteSchemaGrammarTest extends \GrammarTestCase { - protected function tearDown(): void + public function setUp(): void { - m::close(); - } + parent::setUp(); - protected function setupConnection(Blueprint $blueprint) - { - $connection = m::mock(Connection::class); - $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); - $connection->shouldReceive('scalar')->andReturn(''); - return $connection; - } - - protected function getSchemaBuilder(Blueprint $blueprint) - { - $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - $schemaBuilder->shouldReceive('getForeignKeys')->andReturn([]); - $schemaBuilder->shouldReceive('getIndexes')->andReturn([]); - - return $schemaBuilder; - } - - protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) - { - $connection = $this->setupConnection($initialBlueprint); - if (is_null($blueprint)) { - $blueprint = $initialBlueprint; - } - return $blueprint->toSql($connection, new SQLiteGrammar); + $this->grammar = new SQLiteGrammar; } public function testNoInitialModifiersAddNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name'); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar not null', $statements[0]); @@ -57,7 +26,7 @@ public function testNoInitialModifiersAddNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->nullable()->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertStringContainsString('"name" varchar', $statements[0]); } @@ -65,6 +34,7 @@ public function testNullableInitialModifierAddDefault() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar', $statements[0]); @@ -72,7 +42,7 @@ public function testNullableInitialModifierAddDefault() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertStringContainsString("varchar default 'admin'", $statements[0]); } @@ -80,6 +50,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add column "name" varchar', $statements[0]); @@ -87,7 +58,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertStringContainsString("\"name\" varchar not null default 'admin'", $statements[0]); } } diff --git a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php index d68702df2..60a42873a 100644 --- a/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php +++ b/tests/Database/Schema/Grammars/SqlServerSchemaGrammarTest.php @@ -2,49 +2,23 @@ namespace Winter\Storm\Tests\Database\Schema\Grammars; -use Illuminate\Database\Connection; -use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\ForeignIdColumnDefinition; use Winter\Storm\Database\Schema\Grammars\SqlServerGrammar; -use Mockery as m; -use PHPUnit\Framework\TestCase; -class SqlServerSchemaGrammarTest extends TestCase +class SqlServerSchemaGrammarTest extends \GrammarTestCase { - protected function tearDown(): void + public function setUp(): void { - m::close(); - } + parent::setUp(); - protected function setupConnection(Blueprint $blueprint) - { - $connection = m::mock(Connection::class); - $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); - return $connection; - } - - protected function getSchemaBuilder(Blueprint $blueprint) - { - $schemaBuilder = m::mock(Builder::class); - $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); - - return $schemaBuilder; - } - - protected function runBlueprint(Blueprint $initialBlueprint, Blueprint $blueprint = null) - { - $connection = $this->setupConnection($initialBlueprint); - if (is_null($blueprint)) { - $blueprint = $initialBlueprint; - } - return $blueprint->toSql($connection, new SqlServerGrammar); + $this->grammar = new SqlServerGrammar; } public function testNoInitialModifiersAddNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name'); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add "name" nvarchar(255) not null', $statements[0]); @@ -52,7 +26,7 @@ public function testNoInitialModifiersAddNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->nullable()->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertSame('alter table "users" alter column "name" nvarchar(255) null', $statements[1]); } @@ -60,6 +34,7 @@ public function testNullableInitialModifierAddDefault() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add "name" nvarchar(255) null', $statements[0]); @@ -67,7 +42,7 @@ public function testNullableInitialModifierAddDefault() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertSame('alter table "users" alter column "name" nvarchar(255) null', $statements[1]); $this->assertSame('alter table "users" add default \'admin\' for "name"', $statements[2]); } @@ -76,6 +51,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() { $initialBlueprint = new Blueprint('users'); $initialBlueprint->string('name')->nullable(); + $this->setupConnection($initialBlueprint); $statements = $this->runBlueprint($initialBlueprint); $this->assertSame('alter table "users" add "name" nvarchar(255) null', $statements[0]); @@ -83,7 +59,7 @@ public function testNullableInitialModifierAddDefaultNotNullable() $changedBlueprint = new Blueprint('users'); $changedBlueprint->string('name')->default('admin')->nullable(false)->change(); - $statements = $this->runBlueprint($initialBlueprint, $changedBlueprint); + $statements = $this->runBlueprint($changedBlueprint); $this->assertSame('alter table "users" alter column "name" nvarchar(255) not null', $statements[1]); $this->assertSame('alter table "users" add default \'admin\' for "name"', $statements[2]); } diff --git a/tests/GrammarTestCase.php b/tests/GrammarTestCase.php new file mode 100644 index 000000000..cd1953215 --- /dev/null +++ b/tests/GrammarTestCase.php @@ -0,0 +1,42 @@ +shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); + $connection->shouldReceive('scalar')->andReturn(''); + $this->connection = $connection; + } + + protected function getSchemaBuilder(Blueprint $blueprint) + { + $schemaBuilder = m::mock(Builder::class); + $schemaBuilder->shouldReceive('getColumns')->andReturn($blueprint->getColumns()); + $schemaBuilder->shouldReceive('getForeignKeys')->andReturn([]); + $schemaBuilder->shouldReceive('getIndexes')->andReturn([]); + + return $schemaBuilder; + } + + protected function runBlueprint(Blueprint $blueprint) + { + return $blueprint->toSql($this->connection, $this->grammar); + } +} From a18f40b2dc60bd050b08a69c9beec61727c9fb5e Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 8 Apr 2024 13:20:32 -0400 Subject: [PATCH 053/111] extend Illuminate\Database\Connection --- src/Database/Connections/Connection.php | 2 +- src/Database/Connections/MySqlConnection.php | 4 +++- src/Database/Connections/PostgresConnection.php | 4 +++- src/Database/Connections/SQLiteConnection.php | 4 +++- src/Database/Connections/SqlServerConnection.php | 4 +++- src/Database/Connectors/ConnectionFactory.php | 2 +- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Database/Connections/Connection.php b/src/Database/Connections/Connection.php index e42c91f50..80cccca22 100644 --- a/src/Database/Connections/Connection.php +++ b/src/Database/Connections/Connection.php @@ -4,7 +4,7 @@ use Winter\Storm\Database\QueryBuilder; use Illuminate\Database\Connection as ConnectionBase; -class Connection extends ConnectionBase +trait Connection { /** * Get a new query builder instance. diff --git a/src/Database/Connections/MySqlConnection.php b/src/Database/Connections/MySqlConnection.php index dbcf04dfc..514dfb150 100644 --- a/src/Database/Connections/MySqlConnection.php +++ b/src/Database/Connections/MySqlConnection.php @@ -10,8 +10,10 @@ /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ -class MySqlConnection extends Connection +class MySqlConnection extends \Illuminate\Database\MySqlConnection { + use Connection; + /** * Get the default query grammar instance. * diff --git a/src/Database/Connections/PostgresConnection.php b/src/Database/Connections/PostgresConnection.php index e1b11dc0b..1730b5320 100644 --- a/src/Database/Connections/PostgresConnection.php +++ b/src/Database/Connections/PostgresConnection.php @@ -9,8 +9,10 @@ /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ -class PostgresConnection extends Connection +class PostgresConnection extends \Illuminate\Database\PostgresConnection { + use Connection; + /** * Get the default query grammar instance. * diff --git a/src/Database/Connections/SQLiteConnection.php b/src/Database/Connections/SQLiteConnection.php index 0e22ff93d..95631baec 100644 --- a/src/Database/Connections/SQLiteConnection.php +++ b/src/Database/Connections/SQLiteConnection.php @@ -9,8 +9,10 @@ /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ -class SQLiteConnection extends Connection +class SQLiteConnection extends \Illuminate\Database\SQLiteConnection { + use Connection; + /** * Get the default query grammar instance. * diff --git a/src/Database/Connections/SqlServerConnection.php b/src/Database/Connections/SqlServerConnection.php index 640e3181a..cbe0728b8 100644 --- a/src/Database/Connections/SqlServerConnection.php +++ b/src/Database/Connections/SqlServerConnection.php @@ -12,8 +12,10 @@ /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ -class SqlServerConnection extends Connection +class SqlServerConnection extends \Illuminate\Database\SqlServerConnection { + use Connection; + /** * Execute a Closure within a transaction. * diff --git a/src/Database/Connectors/ConnectionFactory.php b/src/Database/Connectors/ConnectionFactory.php index d9be1dc6c..a193640fc 100644 --- a/src/Database/Connectors/ConnectionFactory.php +++ b/src/Database/Connectors/ConnectionFactory.php @@ -2,7 +2,7 @@ use Illuminate\Support\Arr; use Illuminate\Database\Connectors\ConnectionFactory as ConnectionFactoryBase; -use Winter\Storm\Database\Connections\Connection; +use Illuminate\Database\Connection; use Winter\Storm\Database\Connections\MariaDbConnection; use Winter\Storm\Database\Connections\MySqlConnection; use Winter\Storm\Database\Connections\SQLiteConnection; From a98c60cedaee8fac1b0c2d2504ef1e40062da73d Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 8 Apr 2024 13:27:27 -0400 Subject: [PATCH 054/111] fix MariaDbConnection parent --- src/Database/Connections/Connection.php | 1 - src/Database/Connections/MariaDbConnection.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Database/Connections/Connection.php b/src/Database/Connections/Connection.php index 80cccca22..50e7e5921 100644 --- a/src/Database/Connections/Connection.php +++ b/src/Database/Connections/Connection.php @@ -2,7 +2,6 @@ use Winter\Storm\Database\MemoryCache; use Winter\Storm\Database\QueryBuilder; -use Illuminate\Database\Connection as ConnectionBase; trait Connection { diff --git a/src/Database/Connections/MariaDbConnection.php b/src/Database/Connections/MariaDbConnection.php index 9d06b2bf5..35e185b8e 100644 --- a/src/Database/Connections/MariaDbConnection.php +++ b/src/Database/Connections/MariaDbConnection.php @@ -10,7 +10,7 @@ /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ -class MariaDbConnection extends Connection +class MariaDbConnection extends \Illuminate\Database\MariaDbConnection { /** * Get the default query grammar instance. From 2fb435da22c2f953eab003d9d58a90368472f8ad Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 9 Apr 2024 11:26:01 -0400 Subject: [PATCH 055/111] make sure we have a column definition --- src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php | 5 +++++ src/Database/Schema/Grammars/PostgresGrammar.php | 5 +++++ src/Database/Schema/Grammars/SQLiteGrammar.php | 3 +++ src/Database/Schema/Grammars/SqlServerGrammar.php | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php index 1a83fb5e6..e990c58dd 100644 --- a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php +++ b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php @@ -4,6 +4,7 @@ use Illuminate\Database\Connection; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Schema\ColumnDefinition; use Illuminate\Support\Fluent; trait MySqlBasedGrammar @@ -37,6 +38,10 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection ); $oldColumn = $oldColumns->where('name', $column->name)->first(); + if (!$oldColumn instanceof ColumnDefinition) { + $oldColumn = new ColumnDefinition($oldColumn); + } + foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { $mod = strtolower($modifier); diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index 16c81542a..98ab4bed2 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -4,6 +4,7 @@ use Illuminate\Database\Connection; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Schema\ColumnDefinition; use Illuminate\Database\Schema\Grammars\PostgresGrammar as PostgresGrammarBase; use Illuminate\Support\Fluent; @@ -32,6 +33,10 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $changes = ['type '.$this->getType($column).$this->modifyCollate($blueprint, $column)]; $oldColumn = $oldColumns->where('name', $column->name)->first(); + if (!$oldColumn instanceof ColumnDefinition) { + $oldColumn = new ColumnDefinition($oldColumn); + } + foreach ($this->modifiers as $modifier) { if ($modifier === 'Collate') { continue; diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 095a96eb8..dcb79b25a 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -69,6 +69,9 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection } $oldColumn = $oldColumns->where('name', $column->name)->first(); + if (!$oldColumn instanceof ColumnDefinition) { + $oldColumn = new ColumnDefinition($oldColumn); + } $sql = $name.' '.$this->getType($column); foreach ($this->modifiers as $modifier) { diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index c2212c113..2684a4d79 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -4,6 +4,7 @@ use Illuminate\Database\Connection; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Schema\ColumnDefinition; use Illuminate\Database\Schema\Grammars\SqlServerGrammar as SqlServerGrammarBase; use Illuminate\Support\Fluent; @@ -37,6 +38,9 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection ); $oldColumn = $oldColumns->where('name', $column->name)->first(); + if (!$oldColumn instanceof ColumnDefinition) { + $oldColumn = new ColumnDefinition($oldColumn); + } foreach ($this->modifiers as $modifier) { if (method_exists($this, $method = "modify{$modifier}")) { From a4f0f49722e543d7794ef48b21d0c537358cfc7c Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 9 Apr 2024 11:36:03 -0400 Subject: [PATCH 056/111] hasAttribute() has been added in Eloquent HasAttributes trait --- src/Database/Model.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Database/Model.php b/src/Database/Model.php index 5e3d9fcee..bf31daa0c 100644 --- a/src/Database/Model.php +++ b/src/Database/Model.php @@ -1097,20 +1097,6 @@ public function addJsonable($attributes = null) // Getters // - /** - * Determine if the given attribute will be processed by getAttributeValue(). - */ - public function hasAttribute(string $key): bool - { - return ( - array_key_exists($key, $this->attributes) - || array_key_exists($key, $this->casts) - || $this->hasGetMutator($key) - || $this->hasAttributeMutator($key) - || $this->isClassCastable($key) - ); - } - /** * Get an attribute from the model. * Overrides {@link Eloquent} to support loading from property-defined relations. From 73aefbe07f7931ca6dc2339d76f0ca06e7c4f37a Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 9 Apr 2024 14:32:18 -0400 Subject: [PATCH 057/111] remove single quotes from value before processing it --- .../Schema/Grammars/Concerns/MySqlBasedGrammar.php | 9 +++++++++ src/Database/Schema/Grammars/PostgresGrammar.php | 9 +++++++++ src/Database/Schema/Grammars/SQLiteGrammar.php | 9 +++++++++ src/Database/Schema/Grammars/SqlServerGrammar.php | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php index e990c58dd..963acdcef 100644 --- a/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php +++ b/src/Database/Schema/Grammars/Concerns/MySqlBasedGrammar.php @@ -54,4 +54,13 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); } + + public function getDefaultValue($value) + { + if (is_string($value)) { + $value = preg_replace('#\'#', '', $value); + } + + return parent::getDefaultValue($value); + } } diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index 98ab4bed2..3c61f036d 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -58,4 +58,13 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); } + + public function getDefaultValue($value) + { + if (is_string($value)) { + $value = preg_replace('#\'#', '', $value); + } + + return parent::getDefaultValue($value); + } } diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index dcb79b25a..8a3e22e7e 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -147,4 +147,13 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection ) ); } + + public function getDefaultValue($value) + { + if (is_string($value)) { + $value = preg_replace('#\'#', '', $value); + } + + return parent::getDefaultValue($value); + } } diff --git a/src/Database/Schema/Grammars/SqlServerGrammar.php b/src/Database/Schema/Grammars/SqlServerGrammar.php index 2684a4d79..770b71dac 100755 --- a/src/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Database/Schema/Grammars/SqlServerGrammar.php @@ -55,4 +55,13 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection return $changes; } + + public function getDefaultValue($value) + { + if (is_string($value)) { + $value = preg_replace('#\'#', '', $value); + } + + return parent::getDefaultValue($value); + } } From a97f6552c86d916a78048753125f0d60d20b5e86 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 10 Apr 2024 11:39:21 -0400 Subject: [PATCH 058/111] add back doctrine functionality --- composer.json | 1 + phpstan-baseline.neon | 7 +- src/Database/Connections/Connection.php | 121 ++++++++++++ .../Connections/MariaDbConnection.php | 11 ++ src/Database/Connections/MySqlConnection.php | 11 ++ .../Connections/PostgresConnection.php | 11 ++ src/Database/Connections/SQLiteConnection.php | 11 ++ .../Connections/SqlServerConnection.php | 13 +- .../PDO/Concerns/ConnectsToDatabase.php | 30 +++ src/Database/PDO/Connection.php | 182 ++++++++++++++++++ src/Database/PDO/MySqlDriver.php | 19 ++ src/Database/PDO/PostgresDriver.php | 19 ++ src/Database/PDO/SQLiteDriver.php | 19 ++ src/Database/PDO/SqlServerConnection.php | 152 +++++++++++++++ src/Database/PDO/SqlServerDriver.php | 32 +++ 15 files changed, 635 insertions(+), 4 deletions(-) create mode 100644 src/Database/PDO/Concerns/ConnectsToDatabase.php create mode 100644 src/Database/PDO/Connection.php create mode 100644 src/Database/PDO/MySqlDriver.php create mode 100644 src/Database/PDO/PostgresDriver.php create mode 100644 src/Database/PDO/SQLiteDriver.php create mode 100644 src/Database/PDO/SqlServerConnection.php create mode 100644 src/Database/PDO/SqlServerDriver.php diff --git a/composer.json b/composer.json index a178e4911..1ca2e936b 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,7 @@ "ext-zip": "*", "assetic/framework": "^3.1", + "doctrine/dbal": "^3.0", "enshrined/svg-sanitize": "~0.16", "laravel/framework": "^11.0", "laravel/tinker": "^2.8.1", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index c5f878a90..e659a4ac6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -120,6 +120,7 @@ parameters: path: src/Support/Testing/Fakes/MailFake.php - - message: "#^Call to function is_null\\(\\) with Closure will always evaluate to false\\.$#" - count: 1 - path: src/Validation/Factory.php + message: "#^Call to function is_null\\(\\) with (Closure|Doctrine\\\\DBAL\\\\Connection) will always evaluate to false\\.$#" + paths: + - src/Validation/Factory.php + - src/Database/Connections/Connection.php diff --git a/src/Database/Connections/Connection.php b/src/Database/Connections/Connection.php index 50e7e5921..ce200c0b1 100644 --- a/src/Database/Connections/Connection.php +++ b/src/Database/Connections/Connection.php @@ -1,10 +1,28 @@ + */ + protected $doctrineTypeMappings = []; + /** * Get a new query builder instance. * @@ -70,4 +88,107 @@ protected function fireEvent(string $event, array|object $attributes = []): void $eventManager->dispatch($event, $attributes); } + + /** + * Is Doctrine available? + * + * @return bool + */ + public function isDoctrineAvailable() + { + return class_exists('Doctrine\DBAL\Connection'); + } + + /** + * Indicates whether native alter operations will be used when dropping or renaming columns, even if Doctrine DBAL is installed. + * + * @return bool + */ + public function usingNativeSchemaOperations() + { + return ! $this->isDoctrineAvailable(); + } + + /** + * Get a Doctrine Schema Column instance. + * + * @param string $table + * @param string $column + * @return \Doctrine\DBAL\Schema\Column + */ + public function getDoctrineColumn($table, $column) + { + $schema = $this->getDoctrineSchemaManager(); + + return $schema->listTableDetails($table)->getColumn($column); + } + + /** + * Get the Doctrine DBAL schema manager for the connection. + * + * @return \Doctrine\DBAL\Schema\AbstractSchemaManager + */ + public function getDoctrineSchemaManager() + { + $connection = $this->getDoctrineConnection(); + + // Doctrine v2 expects one parameter while v3 expects two. 2nd will be ignored on v2... + return $this->getDoctrineDriver()->getSchemaManager( + $connection, + $connection->getDatabasePlatform() + ); + } + + /** + * Get the Doctrine DBAL database connection instance. + * + * @return \Doctrine\DBAL\Connection + */ + public function getDoctrineConnection() + { + if (is_null($this->doctrineConnection)) { + $driver = $this->getDoctrineDriver(); + + $this->doctrineConnection = new DoctrineConnection(array_filter([ + 'pdo' => $this->getPdo(), + 'dbname' => $this->getDatabaseName(), + 'driver' => $driver->getName(), + 'serverVersion' => $this->getConfig('server_version'), + ]), $driver); + + foreach ($this->doctrineTypeMappings as $name => $type) { + $this->doctrineConnection + ->getDatabasePlatform() + ->registerDoctrineTypeMapping($type, $name); + } + } + + return $this->doctrineConnection; + } + + /** + * Register a custom Doctrine mapping type. + * + * @param Type|class-string $class + * @param string $name + * @param string $type + * @return void + * + * @throws \RuntimeException + */ + public function registerDoctrineType(Type|string $class, string $name, string $type): void + { + if (! $this->isDoctrineAvailable()) { + throw new RuntimeException( + 'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).' + ); + } + + if (! Type::hasType($name)) { + Type::getTypeRegistry() + ->register($name, is_string($class) ? new $class() : $class); + } + + $this->doctrineTypeMappings[$name] = $type; + } } diff --git a/src/Database/Connections/MariaDbConnection.php b/src/Database/Connections/MariaDbConnection.php index 35e185b8e..f03a425a0 100644 --- a/src/Database/Connections/MariaDbConnection.php +++ b/src/Database/Connections/MariaDbConnection.php @@ -4,6 +4,7 @@ use Illuminate\Database\Schema\MariaDbBuilder; use Illuminate\Database\Query\Processors\MariaDbProcessor; +use Winter\Storm\Database\PDO\MySqlDriver; use Winter\Storm\Database\Schema\Grammars\MariaDbGrammar as SchemaGrammar; use Winter\Storm\Database\Query\Grammars\MariaDbGrammar as QueryGrammar; @@ -73,4 +74,14 @@ public function bindValues($statement, $bindings) ); } } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Winter\Storm\Database\PDO\MySqlDriver + */ + protected function getDoctrineDriver() + { + return new MySqlDriver; + } } diff --git a/src/Database/Connections/MySqlConnection.php b/src/Database/Connections/MySqlConnection.php index 514dfb150..f77c03778 100644 --- a/src/Database/Connections/MySqlConnection.php +++ b/src/Database/Connections/MySqlConnection.php @@ -4,6 +4,7 @@ use Illuminate\Database\Schema\MySqlBuilder; use Illuminate\Database\Query\Processors\MySqlProcessor; +use Winter\Storm\Database\PDO\MySqlDriver; use Winter\Storm\Database\Query\Grammars\MySqlGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; @@ -75,4 +76,14 @@ public function bindValues($statement, $bindings) ); } } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Winter\Storm\Database\PDO\MySqlDriver + */ + protected function getDoctrineDriver() + { + return new MySqlDriver; + } } diff --git a/src/Database/Connections/PostgresConnection.php b/src/Database/Connections/PostgresConnection.php index 1730b5320..acda5bc7a 100644 --- a/src/Database/Connections/PostgresConnection.php +++ b/src/Database/Connections/PostgresConnection.php @@ -3,6 +3,7 @@ use Illuminate\Database\Schema\PostgresBuilder; use Illuminate\Database\Query\Processors\PostgresProcessor; +use Winter\Storm\Database\PDO\PostgresDriver; use Winter\Storm\Database\Query\Grammars\PostgresGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\PostgresGrammar as SchemaGrammar; @@ -56,4 +57,14 @@ protected function getDefaultPostProcessor() { return new PostgresProcessor; } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Winter\Storm\Database\PDO\PostgresDriver + */ + protected function getDoctrineDriver() + { + return new PostgresDriver; + } } diff --git a/src/Database/Connections/SQLiteConnection.php b/src/Database/Connections/SQLiteConnection.php index 95631baec..8c2b77ebf 100644 --- a/src/Database/Connections/SQLiteConnection.php +++ b/src/Database/Connections/SQLiteConnection.php @@ -3,6 +3,7 @@ use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Database\Query\Processors\SQLiteProcessor; +use Winter\Storm\Database\PDO\SQLiteDriver; use Winter\Storm\Database\Query\Grammars\SQLiteGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\SQLiteGrammar as SchemaGrammar; @@ -56,4 +57,14 @@ protected function getDefaultPostProcessor() { return new SQLiteProcessor; } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Winter\Storm\Database\PDO\SQLiteDriver + */ + protected function getDoctrineDriver() + { + return new SQLiteDriver; + } } diff --git a/src/Database/Connections/SqlServerConnection.php b/src/Database/Connections/SqlServerConnection.php index cbe0728b8..a9d96969a 100644 --- a/src/Database/Connections/SqlServerConnection.php +++ b/src/Database/Connections/SqlServerConnection.php @@ -6,8 +6,9 @@ use Illuminate\Database\Schema\SqlServerBuilder; use Illuminate\Database\Query\Processors\SqlServerProcessor; -use Winter\Storm\Database\Schema\Grammars\SqlServerGrammar as SchemaGrammar; +use Winter\Storm\Database\PDO\SqlServerDriver; use Winter\Storm\Database\Query\Grammars\SqlServerGrammar as QueryGrammar; +use Winter\Storm\Database\Schema\Grammars\SqlServerGrammar as SchemaGrammar; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar @@ -102,4 +103,14 @@ protected function getDefaultPostProcessor() { return new SqlServerProcessor; } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Winter\Storm\Database\PDO\SqlServerDriver + */ + protected function getDoctrineDriver() + { + return new SqlServerDriver; + } } diff --git a/src/Database/PDO/Concerns/ConnectsToDatabase.php b/src/Database/PDO/Concerns/ConnectsToDatabase.php new file mode 100644 index 000000000..cdffb75a2 --- /dev/null +++ b/src/Database/PDO/Concerns/ConnectsToDatabase.php @@ -0,0 +1,30 @@ +connection = $connection; + } + + /** + * Execute an SQL statement. + * + * @param string $statement + * @return int + */ + public function exec(string $statement): int + { + try { + $result = $this->connection->exec($statement); + + \assert($result !== false); + + return $result; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Prepare a new SQL statement. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\PDO\Statement + */ + public function prepare(string $sql): StatementInterface + { + try { + return $this->createStatement( + $this->connection->prepare($sql) + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Execute a new query against the connection. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Result + */ + public function query(string $sql): ResultInterface + { + try { + $stmt = $this->connection->query($sql); + + \assert($stmt instanceof PDOStatement); + + return new Result($stmt); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Get the last insert ID. + * + * @param string|null $name + * @return mixed + */ + public function lastInsertId($name = null) + { + try { + if ($name === null) { + return $this->connection->lastInsertId(); + } + + return $this->connection->lastInsertId($name); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * Create a new statement instance. + * + * @param \PDOStatement $stmt + * @return \Doctrine\DBAL\Driver\PDO\Statement + */ + protected function createStatement(PDOStatement $stmt): Statement + { + return new Statement($stmt); + } + + /** + * Begin a new database transaction. + * + * @return bool + */ + public function beginTransaction() + { + return $this->connection->beginTransaction(); + } + + /** + * Commit a database transaction. + * + * @return bool + */ + public function commit() + { + return $this->connection->commit(); + } + + /** + * Rollback a database transaction. + * + * @return bool + */ + public function rollBack() + { + return $this->connection->rollBack(); + } + + /** + * Wrap quotes around the given input. + * + * @param string $input + * @param int $type + * @return string + */ + public function quote($input, $type = ParameterType::STRING) + { + return $this->connection->quote($input, $type); + } + + /** + * Get the server version for the connection. + * + * @return string + */ + public function getServerVersion() + { + return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); + } + + /** + * Get the wrapped PDO connection. + * + * @return \PDO + */ + public function getWrappedConnection(): PDO + { + return $this->connection; + } +} diff --git a/src/Database/PDO/MySqlDriver.php b/src/Database/PDO/MySqlDriver.php new file mode 100644 index 000000000..5a3c449c4 --- /dev/null +++ b/src/Database/PDO/MySqlDriver.php @@ -0,0 +1,19 @@ +connection = $connection; + } + + /** + * Prepare a new SQL statement. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Statement + */ + public function prepare(string $sql): StatementInterface + { + return new Statement( + $this->connection->prepare($sql) + ); + } + + /** + * Execute a new query against the connection. + * + * @param string $sql + * @return \Doctrine\DBAL\Driver\Result + */ + public function query(string $sql): Result + { + return $this->connection->query($sql); + } + + /** + * Execute an SQL statement. + * + * @param string $statement + * @return int + */ + public function exec(string $statement): int + { + return $this->connection->exec($statement); + } + + /** + * Get the last insert ID. + * + * @param string|null $name + * @return mixed + */ + public function lastInsertId($name = null) + { + if ($name === null) { + return $this->connection->lastInsertId($name); + } + + return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') + ->execute([$name]) + ->fetchOne(); + } + + /** + * Begin a new database transaction. + * + * @return bool + */ + public function beginTransaction() + { + return $this->connection->beginTransaction(); + } + + /** + * Commit a database transaction. + * + * @return bool + */ + public function commit() + { + return $this->connection->commit(); + } + + /** + * Rollback a database transaction. + * + * @return bool + */ + public function rollBack() + { + return $this->connection->rollBack(); + } + + /** + * Wrap quotes around the given input. + * + * @param string $value + * @param int $type + * @return string + */ + public function quote($value, $type = ParameterType::STRING) + { + $val = $this->connection->quote($value, $type); + + // Fix for a driver version terminating all values with null byte... + if (\is_string($val) && str_contains($val, "\0")) { + $val = \substr($val, 0, -1); + } + + return $val; + } + + /** + * Get the server version for the connection. + * + * @return string + */ + public function getServerVersion() + { + return $this->connection->getServerVersion(); + } + + /** + * Get the wrapped PDO connection. + * + * @return \PDO + */ + public function getWrappedConnection(): PDO + { + return $this->connection->getWrappedConnection(); + } +} diff --git a/src/Database/PDO/SqlServerDriver.php b/src/Database/PDO/SqlServerDriver.php new file mode 100644 index 000000000..633565d9c --- /dev/null +++ b/src/Database/PDO/SqlServerDriver.php @@ -0,0 +1,32 @@ + Date: Mon, 15 Apr 2024 02:51:00 -0600 Subject: [PATCH 059/111] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1ca2e936b..a88836fd2 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "ext-zip": "*", "assetic/framework": "^3.1", - "doctrine/dbal": "^3.0", + "doctrine/dbal": "^3.0", "enshrined/svg-sanitize": "~0.16", "laravel/framework": "^11.0", "laravel/tinker": "^2.8.1", From 713f258d979410b1c48f2df6415ffe020e1fe02a Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Mon, 15 Apr 2024 02:51:08 -0600 Subject: [PATCH 060/111] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a88836fd2..de25bba4d 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ "squizlabs/php_codesniffer": "^3.2", "php-parallel-lint/php-parallel-lint": "^1.0", "meyfa/phpunit-assert-gd": "^4.0", - "mockery/mockery": "^1.6|^2.0", + "mockery/mockery": "^1.6|^2.0", "dms/phpunit-arraysubset-asserts": "^0.5", "orchestra/testbench": "^9.0", "larastan/larastan": "^2.8.1" From a9e164e9857a92f68e00d5d60cc0f1a059ffd98b Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Mon, 15 Apr 2024 02:51:15 -0600 Subject: [PATCH 061/111] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index de25bba4d..c58600b67 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "meyfa/phpunit-assert-gd": "^4.0", "mockery/mockery": "^1.6|^2.0", "dms/phpunit-arraysubset-asserts": "^0.5", - "orchestra/testbench": "^9.0", + "orchestra/testbench": "^9.0", "larastan/larastan": "^2.8.1" }, From f21710e00d8f1cddc0073dc8f42d105f5927ad2f Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Mon, 15 Apr 2024 02:51:28 -0600 Subject: [PATCH 062/111] Update composer.json --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index c58600b67..a8bf9f273 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,6 @@ "orchestra/testbench": "^9.0", "larastan/larastan": "^2.8.1" }, - "suggest": { "ext-pdo_dblib": "Required to use MS SQL Server databases", "ext-pdo_mysql": "Required to use MySQL databases", From 04882b5367441d2b8f93bd462887d8ca70b87724 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 10:10:58 -0400 Subject: [PATCH 063/111] fix composer dependencies --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a8bf9f273..f8ac38f81 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -52,6 +52,7 @@ "winter/laravel-config-writer": "^1.0.1" }, "require-dev": { + "phpunit/phpunit": "^10.5|^11.0", "squizlabs/php_codesniffer": "^3.2", "php-parallel-lint/php-parallel-lint": "^1.0", "meyfa/phpunit-assert-gd": "^4.0", From 478df3d9349096cb99c3795438e91943ad9e5f22 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 10:19:26 -0400 Subject: [PATCH 064/111] revert Connection trait into a class --- src/Database/Connections/Connection.php | 192 +---------------- .../Connections/MariaDbConnection.php | 3 + src/Database/Connections/MySqlConnection.php | 3 +- .../Connections/PostgresConnection.php | 3 +- src/Database/Connections/SQLiteConnection.php | 3 +- .../Connections/SqlServerConnection.php | 3 +- src/Database/Traits/HasConnection.php | 193 ++++++++++++++++++ 7 files changed, 207 insertions(+), 193 deletions(-) create mode 100644 src/Database/Traits/HasConnection.php diff --git a/src/Database/Connections/Connection.php b/src/Database/Connections/Connection.php index ce200c0b1..76022cb82 100644 --- a/src/Database/Connections/Connection.php +++ b/src/Database/Connections/Connection.php @@ -1,194 +1,8 @@ - */ - protected $doctrineTypeMappings = []; - - /** - * Get a new query builder instance. - * - * @return \Winter\Storm\Database\QueryBuilder - */ - public function query() - { - return new QueryBuilder( - $this, - $this->getQueryGrammar(), - $this->getPostProcessor() - ); - } - - /** - * Flush the memory cache. - * @return void - */ - public static function flushDuplicateCache() - { - MemoryCache::instance()->flush(); - } - - /** - * Log a query in the connection's query log. - * - * @param string $query - * @param array $bindings - * @param float|null $time - * @return void - */ - public function logQuery($query, $bindings, $time = null) - { - $this->fireEvent('illuminate.query', [$query, $bindings, $time, $this->getName()]); - - parent::logQuery($query, $bindings, $time); - } - - /** - * Fire an event for this connection. - * - * @param string $event - * @return array|null - */ - protected function fireConnectionEvent($event) - { - $this->fireEvent('connection.'.$this->getName().'.'.$event, $this); - - parent::fireConnectionEvent($event); - } - - /** - * Fire the given event if possible. - */ - protected function fireEvent(string $event, array|object $attributes = []): void - { - /** @var \Winter\Storm\Events\Dispatcher|null */ - $eventManager = $this->events; - - if (!isset($eventManager)) { - return; - } - - $eventManager->dispatch($event, $attributes); - } - - /** - * Is Doctrine available? - * - * @return bool - */ - public function isDoctrineAvailable() - { - return class_exists('Doctrine\DBAL\Connection'); - } - - /** - * Indicates whether native alter operations will be used when dropping or renaming columns, even if Doctrine DBAL is installed. - * - * @return bool - */ - public function usingNativeSchemaOperations() - { - return ! $this->isDoctrineAvailable(); - } - - /** - * Get a Doctrine Schema Column instance. - * - * @param string $table - * @param string $column - * @return \Doctrine\DBAL\Schema\Column - */ - public function getDoctrineColumn($table, $column) - { - $schema = $this->getDoctrineSchemaManager(); - - return $schema->listTableDetails($table)->getColumn($column); - } - - /** - * Get the Doctrine DBAL schema manager for the connection. - * - * @return \Doctrine\DBAL\Schema\AbstractSchemaManager - */ - public function getDoctrineSchemaManager() - { - $connection = $this->getDoctrineConnection(); - - // Doctrine v2 expects one parameter while v3 expects two. 2nd will be ignored on v2... - return $this->getDoctrineDriver()->getSchemaManager( - $connection, - $connection->getDatabasePlatform() - ); - } - - /** - * Get the Doctrine DBAL database connection instance. - * - * @return \Doctrine\DBAL\Connection - */ - public function getDoctrineConnection() - { - if (is_null($this->doctrineConnection)) { - $driver = $this->getDoctrineDriver(); - - $this->doctrineConnection = new DoctrineConnection(array_filter([ - 'pdo' => $this->getPdo(), - 'dbname' => $this->getDatabaseName(), - 'driver' => $driver->getName(), - 'serverVersion' => $this->getConfig('server_version'), - ]), $driver); - - foreach ($this->doctrineTypeMappings as $name => $type) { - $this->doctrineConnection - ->getDatabasePlatform() - ->registerDoctrineTypeMapping($type, $name); - } - } - - return $this->doctrineConnection; - } - - /** - * Register a custom Doctrine mapping type. - * - * @param Type|class-string $class - * @param string $name - * @param string $type - * @return void - * - * @throws \RuntimeException - */ - public function registerDoctrineType(Type|string $class, string $name, string $type): void - { - if (! $this->isDoctrineAvailable()) { - throw new RuntimeException( - 'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).' - ); - } - - if (! Type::hasType($name)) { - Type::getTypeRegistry() - ->register($name, is_string($class) ? new $class() : $class); - } - - $this->doctrineTypeMappings[$name] = $type; - } + use HasConnection; } diff --git a/src/Database/Connections/MariaDbConnection.php b/src/Database/Connections/MariaDbConnection.php index f03a425a0..a1cb86d0e 100644 --- a/src/Database/Connections/MariaDbConnection.php +++ b/src/Database/Connections/MariaDbConnection.php @@ -7,12 +7,15 @@ use Winter\Storm\Database\PDO\MySqlDriver; use Winter\Storm\Database\Schema\Grammars\MariaDbGrammar as SchemaGrammar; use Winter\Storm\Database\Query\Grammars\MariaDbGrammar as QueryGrammar; +use Winter\Storm\Database\Traits\HasConnection; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ class MariaDbConnection extends \Illuminate\Database\MariaDbConnection { + use HasConnection; + /** * Get the default query grammar instance. * diff --git a/src/Database/Connections/MySqlConnection.php b/src/Database/Connections/MySqlConnection.php index f77c03778..aab13d275 100644 --- a/src/Database/Connections/MySqlConnection.php +++ b/src/Database/Connections/MySqlConnection.php @@ -7,13 +7,14 @@ use Winter\Storm\Database\PDO\MySqlDriver; use Winter\Storm\Database\Query\Grammars\MySqlGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; +use Winter\Storm\Database\Traits\HasConnection; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ class MySqlConnection extends \Illuminate\Database\MySqlConnection { - use Connection; + use HasConnection; /** * Get the default query grammar instance. diff --git a/src/Database/Connections/PostgresConnection.php b/src/Database/Connections/PostgresConnection.php index acda5bc7a..24ade075c 100644 --- a/src/Database/Connections/PostgresConnection.php +++ b/src/Database/Connections/PostgresConnection.php @@ -6,13 +6,14 @@ use Winter\Storm\Database\PDO\PostgresDriver; use Winter\Storm\Database\Query\Grammars\PostgresGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\PostgresGrammar as SchemaGrammar; +use Winter\Storm\Database\Traits\HasConnection; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ class PostgresConnection extends \Illuminate\Database\PostgresConnection { - use Connection; + use HasConnection; /** * Get the default query grammar instance. diff --git a/src/Database/Connections/SQLiteConnection.php b/src/Database/Connections/SQLiteConnection.php index 8c2b77ebf..8bb67decc 100644 --- a/src/Database/Connections/SQLiteConnection.php +++ b/src/Database/Connections/SQLiteConnection.php @@ -6,13 +6,14 @@ use Winter\Storm\Database\PDO\SQLiteDriver; use Winter\Storm\Database\Query\Grammars\SQLiteGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\SQLiteGrammar as SchemaGrammar; +use Winter\Storm\Database\Traits\HasConnection; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ class SQLiteConnection extends \Illuminate\Database\SQLiteConnection { - use Connection; + use HasConnection; /** * Get the default query grammar instance. diff --git a/src/Database/Connections/SqlServerConnection.php b/src/Database/Connections/SqlServerConnection.php index a9d96969a..afcbc5b1f 100644 --- a/src/Database/Connections/SqlServerConnection.php +++ b/src/Database/Connections/SqlServerConnection.php @@ -9,13 +9,14 @@ use Winter\Storm\Database\PDO\SqlServerDriver; use Winter\Storm\Database\Query\Grammars\SqlServerGrammar as QueryGrammar; use Winter\Storm\Database\Schema\Grammars\SqlServerGrammar as SchemaGrammar; +use Winter\Storm\Database\Traits\HasConnection; /** * @phpstan-property \Illuminate\Database\Schema\Grammars\Grammar|null $schemaGrammar */ class SqlServerConnection extends \Illuminate\Database\SqlServerConnection { - use Connection; + use HasConnection; /** * Execute a Closure within a transaction. diff --git a/src/Database/Traits/HasConnection.php b/src/Database/Traits/HasConnection.php new file mode 100644 index 000000000..905ad264f --- /dev/null +++ b/src/Database/Traits/HasConnection.php @@ -0,0 +1,193 @@ + + */ + protected $doctrineTypeMappings = []; + + /** + * Get a new query builder instance. + * + * @return \Winter\Storm\Database\QueryBuilder + */ + public function query() + { + return new QueryBuilder( + $this, + $this->getQueryGrammar(), + $this->getPostProcessor() + ); + } + + /** + * Flush the memory cache. + * @return void + */ + public static function flushDuplicateCache() + { + MemoryCache::instance()->flush(); + } + + /** + * Log a query in the connection's query log. + * + * @param string $query + * @param array $bindings + * @param float|null $time + * @return void + */ + public function logQuery($query, $bindings, $time = null) + { + $this->fireEvent('illuminate.query', [$query, $bindings, $time, $this->getName()]); + + parent::logQuery($query, $bindings, $time); + } + + /** + * Fire an event for this connection. + * + * @param string $event + * @return array|null + */ + protected function fireConnectionEvent($event) + { + $this->fireEvent('connection.'.$this->getName().'.'.$event, $this); + + parent::fireConnectionEvent($event); + } + + /** + * Fire the given event if possible. + */ + protected function fireEvent(string $event, array|object $attributes = []): void + { + /** @var \Winter\Storm\Events\Dispatcher|null */ + $eventManager = $this->events; + + if (!isset($eventManager)) { + return; + } + + $eventManager->dispatch($event, $attributes); + } + + /** + * Is Doctrine available? + * + * @return bool + */ + public function isDoctrineAvailable() + { + return class_exists('Doctrine\DBAL\Connection'); + } + + /** + * Indicates whether native alter operations will be used when dropping or renaming columns, even if Doctrine DBAL is installed. + * + * @return bool + */ + public function usingNativeSchemaOperations() + { + return ! $this->isDoctrineAvailable(); + } + + /** + * Get a Doctrine Schema Column instance. + * + * @param string $table + * @param string $column + * @return \Doctrine\DBAL\Schema\Column + */ + public function getDoctrineColumn($table, $column) + { + $schema = $this->getDoctrineSchemaManager(); + + return $schema->listTableDetails($table)->getColumn($column); + } + + /** + * Get the Doctrine DBAL schema manager for the connection. + * + * @return \Doctrine\DBAL\Schema\AbstractSchemaManager + */ + public function getDoctrineSchemaManager() + { + $connection = $this->getDoctrineConnection(); + + // Doctrine v2 expects one parameter while v3 expects two. 2nd will be ignored on v2... + return $this->getDoctrineDriver()->getSchemaManager( + $connection, + $connection->getDatabasePlatform() + ); + } + + /** + * Get the Doctrine DBAL database connection instance. + * + * @return \Doctrine\DBAL\Connection + */ + public function getDoctrineConnection() + { + if (is_null($this->doctrineConnection)) { + $driver = $this->getDoctrineDriver(); + + $this->doctrineConnection = new DoctrineConnection(array_filter([ + 'pdo' => $this->getPdo(), + 'dbname' => $this->getDatabaseName(), + 'driver' => $driver->getName(), + 'serverVersion' => $this->getConfig('server_version'), + ]), $driver); + + foreach ($this->doctrineTypeMappings as $name => $type) { + $this->doctrineConnection + ->getDatabasePlatform() + ->registerDoctrineTypeMapping($type, $name); + } + } + + return $this->doctrineConnection; + } + + /** + * Register a custom Doctrine mapping type. + * + * @param Type|class-string $class + * @param string $name + * @param string $type + * @return void + * + * @throws \RuntimeException + */ + public function registerDoctrineType(Type|string $class, string $name, string $type): void + { + if (! $this->isDoctrineAvailable()) { + throw new RuntimeException( + 'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).' + ); + } + + if (! Type::hasType($name)) { + Type::getTypeRegistry() + ->register($name, is_string($class) ? new $class() : $class); + } + + $this->doctrineTypeMappings[$name] = $type; + } +} From e960492d513244f66f1bf2c1385b5121526bbd92 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 10:29:51 -0400 Subject: [PATCH 065/111] add abstract getDoctrineDriver() method --- phpstan-baseline.neon | 1 + src/Database/Connections/Connection.php | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e659a4ac6..4f1ba304f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -124,3 +124,4 @@ parameters: paths: - src/Validation/Factory.php - src/Database/Connections/Connection.php + - src/Database/Traits/HasConnection.php diff --git a/src/Database/Connections/Connection.php b/src/Database/Connections/Connection.php index 76022cb82..ad1adb05a 100644 --- a/src/Database/Connections/Connection.php +++ b/src/Database/Connections/Connection.php @@ -2,7 +2,9 @@ use Winter\Storm\Database\Traits\HasConnection; -class Connection +abstract class Connection extends \Illuminate\Database\Connection { use HasConnection; + + abstract protected function getDoctrineDriver(); } From 0373d4598b277eb14635d7cee6a1845909e03799 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 10:34:58 -0400 Subject: [PATCH 066/111] mark Database/Connections/Connection class deprecated --- src/Database/Connections/Connection.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Database/Connections/Connection.php b/src/Database/Connections/Connection.php index ad1adb05a..1b4b9a628 100644 --- a/src/Database/Connections/Connection.php +++ b/src/Database/Connections/Connection.php @@ -1,8 +1,12 @@ Date: Mon, 15 Apr 2024 10:58:54 -0400 Subject: [PATCH 067/111] try to remove exclusions and disableSchemaScan config --- phpstan.neon | 3 --- 1 file changed, 3 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 291360afc..54338d865 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,9 +10,6 @@ parameters: # Exclude PHP Parser files - src/Parse/PHP/ArrayFile.php - src/Parse/PHP/ArrayPrinter.php - - src/Foundation/Console/KeyGenerateCommand.php - - src/Scaffold/GeneratorCommand.php - disableSchemaScan: true databaseMigrationsPath: - src/Auth/Migrations - src/Database/Migrations From 051946f01f128e7ab8123c7b641cc5e05bc7cf97 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 11:04:09 -0400 Subject: [PATCH 068/111] ignore undefined tags() method --- phpstan-baseline.neon | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index cb96c36de..825d66510 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,7 +1,12 @@ parameters: ignoreErrors: - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\:\\:getQualifiedFirstKeyName\\(\\)\\.$#" + message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository::tags\\(\\)\\.$#" + count: 1 + path: src/Halcyon/Builder.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getQualifiedFirstKeyName\\(\\)\\.$#" count: 12 path: src/Database/Relations/Concerns/DefinedConstraints.php From 5da0cfd714c0c00f14338a33e36d7da909f4d855 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 11:23:22 -0400 Subject: [PATCH 069/111] disable schema scan in phpstan.neon --- phpstan-baseline.neon | 5 ----- phpstan.neon | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 825d66510..3a08494b8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository::tags\\(\\)\\.$#" - count: 1 - path: src/Halcyon/Builder.php - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation::getQualifiedFirstKeyName\\(\\)\\.$#" count: 12 diff --git a/phpstan.neon b/phpstan.neon index 54338d865..371ede82b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,6 +10,7 @@ parameters: # Exclude PHP Parser files - src/Parse/PHP/ArrayFile.php - src/Parse/PHP/ArrayPrinter.php + disableSchemaScan: true databaseMigrationsPath: - src/Auth/Migrations - src/Database/Migrations From dcf642d0c344498b9ea5468c7c73bf89412579c0 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 11:32:50 -0400 Subject: [PATCH 070/111] try another variation to appease phpstan --- phpstan.neon | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 371ede82b..0dbe2693b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,7 +10,8 @@ parameters: # Exclude PHP Parser files - src/Parse/PHP/ArrayFile.php - src/Parse/PHP/ArrayPrinter.php - disableSchemaScan: true + - src/Foundation/Console/KeyGenerateCommand.php + - src/Scaffold/GeneratorCommand.php databaseMigrationsPath: - src/Auth/Migrations - src/Database/Migrations From 0653451eafa67741b9f2b613aeaf3d17d38e22eb Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 11:46:59 -0400 Subject: [PATCH 071/111] use $total value if provided --- src/Auth/Manager.php | 2 +- src/Database/Builder.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Auth/Manager.php b/src/Auth/Manager.php index 57cecad18..419d4a19e 100644 --- a/src/Auth/Manager.php +++ b/src/Auth/Manager.php @@ -171,7 +171,7 @@ public function hasUser() * Sets the user * @phpstan-param Models\User $user */ - public function setUser(Authenticatable $user) : self + public function setUser(Authenticatable $user): self { $this->user = $user; return $this; diff --git a/src/Database/Builder.php b/src/Database/Builder.php index cd7c632d3..003f2b4a0 100644 --- a/src/Database/Builder.php +++ b/src/Database/Builder.php @@ -153,7 +153,7 @@ public function paginate($perPage = null, $currentPage = null, $columns = ['*'], $perPage = $this->model->getPerPage(); } - $total = $this->toBase()->getCountForPagination(); + $total = value($total) ?? $this->toBase()->getCountForPagination(); $this->forPage((int) $currentPage, (int) $perPage); return $this->paginator($this->get($columns), $total, $perPage, $currentPage, [ From 8140a94fa30658c247f2f26b7c0d9a156471ddcc Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 13:22:18 -0400 Subject: [PATCH 072/111] restore formatting --- phpunit.xml.dist | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 504abbbd5..3ec299c5f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,13 @@ - + ./tests From 2eecd05cf23e69d9804e2fd9e7eb958c3cf396b6 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 13:36:40 -0400 Subject: [PATCH 073/111] remove unused overriden CacheManager --- src/Cache/CacheManager.php | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/Cache/CacheManager.php diff --git a/src/Cache/CacheManager.php b/src/Cache/CacheManager.php deleted file mode 100644 index b6b40d720..000000000 --- a/src/Cache/CacheManager.php +++ /dev/null @@ -1,9 +0,0 @@ - Date: Mon, 15 Apr 2024 15:31:45 -0400 Subject: [PATCH 074/111] default value for total should be null --- src/Database/Builder.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Database/Builder.php b/src/Database/Builder.php index 003f2b4a0..345e16263 100644 --- a/src/Database/Builder.php +++ b/src/Database/Builder.php @@ -120,15 +120,16 @@ protected function searchWhereInternal($term, $columns, $mode, $boolean) * * This method also accepts the Laravel signature: * - * `paginate(int|null $perPage, array $columns, string $pageName, int|null $page)` + * `paginate(int|null $perPage, array $columns, string $pageName, int|null $page, \Closure|int|null $total)` * * @param int|null $perPage * @param array|int|null $currentPage * @param array|string $columns * @param string|int|null $pageName + * @param \Closure|int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function paginate($perPage = null, $currentPage = null, $columns = ['*'], $pageName = 'page', $total = 0) + public function paginate($perPage = null, $currentPage = null, $columns = ['*'], $pageName = 'page', $total = null) { /* * Engage Laravel signature support From 08b9211179ee987558f1bc8c74b23b09c18df86d Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 16:24:32 -0400 Subject: [PATCH 075/111] restore previous cache file name --- .gitignore | 1 - phpunit.xml.dist | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 06c24a826..baed57fce 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,5 @@ php_errors.log #phpunit tests/.phpunit.result.cache -.phpunit.result.cache tests/tmp tests/artifacts/* diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3ec299c5f..78a1b927a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,7 @@ Date: Mon, 15 Apr 2024 17:18:06 -0400 Subject: [PATCH 076/111] add missing name attribute --- src/Database/Schema/Grammars/SQLiteGrammar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 8a3e22e7e..8407d5d7a 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -46,6 +46,7 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection $isGenerated = ! is_null($column['generation']); $column = new ColumnDefinition([ 'change' => true, + 'name' => $column['name'], 'type' => $column['type_name'], 'nullable' => $column['nullable'], 'default' => $column['default'] ? new Expression($column['default']) : null, From 31d2c27eb9ba902b10a9cac147ae8ea2ca09a199 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 15 Apr 2024 17:27:16 -0400 Subject: [PATCH 077/111] add missing typeVarChar() method --- src/Database/Schema/Grammars/SQLiteGrammar.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 8407d5d7a..bbb6e7b44 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -157,4 +157,15 @@ public function getDefaultValue($value) return parent::getDefaultValue($value); } + + /** + * Create the column definition for a varchar type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeVarChar(Fluent $column) + { + return 'varchar'; + } } From 72531cc4a83427e73ce14fea9fe1dc3653082ae5 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 16 Apr 2024 14:38:26 -0400 Subject: [PATCH 078/111] freeze twig to 3.8.x until we figure out the breakage in 3.9.x --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f8ac38f81..15307f633 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "scssphp/scssphp": "~1.0", "symfony/console": "^6.4|^7.0", "symfony/yaml": "^6.4|^7.0", - "twig/twig": "~3.0", + "twig/twig": "~3.8.0", "wikimedia/less.php": "~3.0", "wikimedia/minify": "~2.2", "winter/laravel-config-writer": "^1.0.1" From 48883f6b5c4db5f154e48739a0bfa547c2b54b5b Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 16 Apr 2024 14:50:59 -0400 Subject: [PATCH 079/111] ignore twig for now --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 15307f633..3693ec13e 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,6 @@ "scssphp/scssphp": "~1.0", "symfony/console": "^6.4|^7.0", "symfony/yaml": "^6.4|^7.0", - "twig/twig": "~3.8.0", "wikimedia/less.php": "~3.0", "wikimedia/minify": "~2.2", "winter/laravel-config-writer": "^1.0.1" From eacaea2f0cff4cf10dc5f437957d0e06d481e85f Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 19 Apr 2024 13:06:24 -0400 Subject: [PATCH 080/111] pass the relation instead of fetching it each time --- src/Database/Concerns/HasRelationships.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Database/Concerns/HasRelationships.php b/src/Database/Concerns/HasRelationships.php index 6eeb377a6..d31c0e8b5 100644 --- a/src/Database/Concerns/HasRelationships.php +++ b/src/Database/Concerns/HasRelationships.php @@ -308,17 +308,17 @@ protected function handleRelation($relationName) switch ($relationType) { case 'hasOne': case 'hasMany': - $relation = $this->validateRelationArgs($relationName, ['key', 'otherKey']); + $relation = $this->validateRelationArgs($relation, $relationName, ['key', 'otherKey']); $relationObj = $this->$relationType($relation[0], $relation['key'], $relation['otherKey'], $relationName); break; case 'belongsTo': - $relation = $this->validateRelationArgs($relationName, ['key', 'otherKey']); + $relation = $this->validateRelationArgs($relation, $relationName, ['key', 'otherKey']); $relationObj = $this->$relationType($relation[0], $relation['key'], $relation['otherKey'], $relationName); break; case 'belongsToMany': - $relation = $this->validateRelationArgs($relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps']); + $relation = $this->validateRelationArgs($relation, $relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps']); $relationObj = $this->$relationType($relation[0], $relation['table'], $relation['key'], $relation['otherKey'], $relation['parentKey'], $relation['relatedKey'], $relationName); if (isset($relation['pivotModel'])) { @@ -328,18 +328,18 @@ protected function handleRelation($relationName) break; case 'morphTo': - $relation = $this->validateRelationArgs($relationName, ['name', 'type', 'id']); + $relation = $this->validateRelationArgs($relation, $relationName, ['name', 'type', 'id']); $relationObj = $this->$relationType($relation['name'] ?: $relationName, $relation['type'], $relation['id']); break; case 'morphOne': case 'morphMany': - $relation = $this->validateRelationArgs($relationName, ['type', 'id', 'key'], ['name']); + $relation = $this->validateRelationArgs($relation, $relationName, ['type', 'id', 'key'], ['name']); $relationObj = $this->$relationType($relation[0], $relation['name'], $relation['type'], $relation['id'], $relation['key'], $relationName); break; case 'morphToMany': - $relation = $this->validateRelationArgs($relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps'], ['name']); + $relation = $this->validateRelationArgs($relation, $relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps'], ['name']); $relationObj = $this->$relationType($relation[0], $relation['name'], $relation['table'], $relation['key'], $relation['otherKey'], $relation['parentKey'], $relation['relatedKey'], $relationName, false); if (isset($relation['pivotModel'])) { @@ -349,19 +349,19 @@ protected function handleRelation($relationName) break; case 'morphedByMany': - $relation = $this->validateRelationArgs($relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps'], ['name']); + $relation = $this->validateRelationArgs($relation, $relationName, ['table', 'key', 'otherKey', 'parentKey', 'relatedKey', 'pivot', 'timestamps'], ['name']); $relationObj = $this->$relationType($relation[0], $relation['name'], $relation['table'], $relation['key'], $relation['otherKey'], $relation['parentKey'], $relation['relatedKey'], $relationName); break; case 'attachOne': case 'attachMany': - $relation = $this->validateRelationArgs($relationName, ['public', 'key']); + $relation = $this->validateRelationArgs($relation, $relationName, ['public', 'key']); $relationObj = $this->$relationType($relation[0], $relation['public'], $relation['key'], $relationName); break; case 'hasOneThrough': case 'hasManyThrough': - $relation = $this->validateRelationArgs($relationName, ['key', 'throughKey', 'otherKey', 'secondOtherKey'], ['through']); + $relation = $this->validateRelationArgs($relation, $relationName, ['key', 'throughKey', 'otherKey', 'secondOtherKey'], ['through']); $relationObj = $this->$relationType($relation[0], $relation['through'], $relation['key'], $relation['throughKey'], $relation['otherKey'], $relation['secondOtherKey'], $relationName); break; @@ -375,10 +375,8 @@ protected function handleRelation($relationName) /** * Validate relation supplied arguments. */ - protected function validateRelationArgs($relationName, $optional, $required = []) + protected function validateRelationArgs($relation, $relationName, $optional, $required = []) { - $relation = $this->getRelationDefinition($relationName); - // Query filter arguments $filters = ['scope', 'conditions', 'order', 'pivot', 'timestamps', 'push', 'count', 'default']; From 36cae4877b2d2d0de9b1903a6d973dfe4516d628 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 13 May 2024 23:35:43 -0400 Subject: [PATCH 081/111] fix phpstan --- phpstan-baseline.neon | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 3a08494b8..9a6dff752 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -78,11 +78,14 @@ parameters: - messages: - - "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects array, int\\|null given\\.$#" + - "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::(simpleP|p)aginate\\(\\) expects array, int\\|null given\\.$#" - "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" - - "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" - - "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::paginate\\(\\) expects string, array given\\.$#" - - "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" + - "#^Parameter \\#2 \\$currentPage \\(int(\\|null)?\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::(simpleP|p)aginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::(simpleP|p)aginate\\(\\)$#" + - "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::(simpleP|p)aginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::(simpleP|p)aginate\\(\\)$#" + - "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::(simpleP|p)aginate\\(\\) expects string, array given\\.$#" + - "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::(simpleP|p)aginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::(simpleP|p)aginate\\(\\)$#" + - "#^Parameter \\#4 \\$page of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::(simpleP|p)aginate\\(\\) expects int\\|null, string given.$#" + paths: - src/Database/Relations/BelongsToMany.php - src/Database/Relations/MorphToMany.php From 83a5fbf8f6205c38d0a2c015c6f0dcea370ba45d Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 13:12:02 -0400 Subject: [PATCH 082/111] use latest symfony process --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index e6221b5d0..562432f3f 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,7 @@ "nikic/php-parser": "^4.10", "scssphp/scssphp": "~1.0", "symfony/console": "^6.4|^7.0", + "symfony/process": "^7.1", "symfony/yaml": "^6.4|^7.0", "twig/twig": "<3.9", "wikimedia/less.php": "~3.0", From d740fda506cd8a0fa6d912744051295a8aa36851 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 16:31:05 -0400 Subject: [PATCH 083/111] .github/workflows/code-analysis.yaml --- .github/workflows/code-analysis.yaml | 2 +- phpstan-baseline.neon | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml index 0432f6f6b..1674b671d 100644 --- a/.github/workflows/code-analysis.yaml +++ b/.github/workflows/code-analysis.yaml @@ -49,4 +49,4 @@ jobs: run: composer install --no-interaction --no-progress --no-scripts - name: Analyse code - run: ./vendor/bin/phpstan analyse --memory-limit=2G --no-progress + run: ./vendor/bin/phpstan analyse --memory-limit=2G --no-progress -V diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9a6dff752..108a92c83 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -133,3 +133,9 @@ parameters: - src/Validation/Factory.php - src/Database/Connections/Connection.php - src/Database/Traits/HasConnection.php + + - + message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository::tags\\(\\)\\.$#" + count: 0 + path: src/Halcyon/Builder.php + From bbddad7dc4cfc23575767132377862ff9b893330 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 16:37:59 -0400 Subject: [PATCH 084/111] Revert ".github/workflows/code-analysis.yaml" This reverts commit d740fda506cd8a0fa6d912744051295a8aa36851. --- .github/workflows/code-analysis.yaml | 2 +- phpstan-baseline.neon | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml index 1674b671d..0432f6f6b 100644 --- a/.github/workflows/code-analysis.yaml +++ b/.github/workflows/code-analysis.yaml @@ -49,4 +49,4 @@ jobs: run: composer install --no-interaction --no-progress --no-scripts - name: Analyse code - run: ./vendor/bin/phpstan analyse --memory-limit=2G --no-progress -V + run: ./vendor/bin/phpstan analyse --memory-limit=2G --no-progress diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 108a92c83..9a6dff752 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -133,9 +133,3 @@ parameters: - src/Validation/Factory.php - src/Database/Connections/Connection.php - src/Database/Traits/HasConnection.php - - - - message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository::tags\\(\\)\\.$#" - count: 0 - path: src/Halcyon/Builder.php - From 41c8b9b829c6a91e235c2842fb2e6be4d1c072f0 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 16:44:38 -0400 Subject: [PATCH 085/111] add ignore rule for tags method on Cache Repository --- phpstan-baseline.neon | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9a6dff752..6b014d6c3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -133,3 +133,7 @@ parameters: - src/Validation/Factory.php - src/Database/Connections/Connection.php - src/Database/Traits/HasConnection.php + + - + message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository::tags\\(\\)\\.$#" + path: src/Halcyon/Builder.php From f710dbac24bbf6a265d98ae481e50f1092cffb21 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 16:56:13 -0400 Subject: [PATCH 086/111] try clearing phpstan cache in case it exists --- .github/workflows/code-analysis.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml index 0432f6f6b..26b112465 100644 --- a/.github/workflows/code-analysis.yaml +++ b/.github/workflows/code-analysis.yaml @@ -48,5 +48,8 @@ jobs: - name: Install Composer dependencies run: composer install --no-interaction --no-progress --no-scripts + - name: Clear phpstan cache + run: ./vendor/bin/phpstan clear-result-cache + - name: Analyse code run: ./vendor/bin/phpstan analyse --memory-limit=2G --no-progress From 65fe80de665d03d2a18670712eb89e3063ad1342 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 17:00:42 -0400 Subject: [PATCH 087/111] test commit --- src/Halcyon/Builder.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Halcyon/Builder.php b/src/Halcyon/Builder.php index de7313be3..2fbb246d0 100644 --- a/src/Halcyon/Builder.php +++ b/src/Halcyon/Builder.php @@ -703,6 +703,7 @@ protected function isCacheBusted($result) */ protected function getCache() { + $var = "value"; $cache = $this->model->getCacheManager()->driver($this->cacheDriver); return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache; From d7c9f9a0fbc91493813b2f908868923e94857f18 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 17 May 2024 17:02:55 -0400 Subject: [PATCH 088/111] Revert "test commit" This reverts commit 65fe80de665d03d2a18670712eb89e3063ad1342. --- src/Halcyon/Builder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Halcyon/Builder.php b/src/Halcyon/Builder.php index 2fbb246d0..de7313be3 100644 --- a/src/Halcyon/Builder.php +++ b/src/Halcyon/Builder.php @@ -703,7 +703,6 @@ protected function isCacheBusted($result) */ protected function getCache() { - $var = "value"; $cache = $this->model->getCacheManager()->driver($this->cacheDriver); return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache; From a269f289011a2eb2784d78839815b7eb6576f44d Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 18 Jun 2024 14:56:14 -0400 Subject: [PATCH 089/111] registerEloquentFactory() has been removed from Laravel --- src/Database/DatabaseServiceProvider.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Database/DatabaseServiceProvider.php b/src/Database/DatabaseServiceProvider.php index abfd728fc..f5872ee0f 100644 --- a/src/Database/DatabaseServiceProvider.php +++ b/src/Database/DatabaseServiceProvider.php @@ -33,8 +33,6 @@ public function register() Model::flushDuplicateCache(); Model::flushEventListeners(); - $this->registerEloquentFactory(); - $this->registerQueueableEntityResolver(); // The connection factory is used to create the actual connection instances on From 0e4dc334bb098fb30386e7e4810630ddc59bdce4 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Jul 2024 14:54:24 -0400 Subject: [PATCH 090/111] remove extra phpstan ignore rules --- phpstan-baseline.neon | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 96ad8c654..485b5c525 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -127,17 +127,6 @@ parameters: - "#^Return type \\(void\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::send\\(\\) should be compatible with return type \\(Illuminate\\\\Mail\\\\SentMessage\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\Mailer::send\\(\\)$#" path: src/Support/Testing/Fakes/MailFake.php - - - message: "#^Call to function is_null\\(\\) with (Closure|Doctrine\\\\DBAL\\\\Connection) will always evaluate to false\\.$#" - paths: - - src/Validation/Factory.php - - src/Database/Connections/Connection.php - - src/Database/Traits/HasConnection.php - - - - message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Cache\\\\Repository::tags\\(\\)\\.$#" - path: src/Halcyon/Builder.php - - message: "#^Call to function is_null\\(\\) with Closure will always evaluate to false\\.$#" count: 1 From 6e9eaa3e764807a9a7a4fc5eb7f8035d7a74cd75 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Jul 2024 14:57:24 -0400 Subject: [PATCH 091/111] silence invalid phpstan warning --- phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon b/phpstan.neon index 0dbe2693b..b77fcb7a5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -17,3 +17,4 @@ parameters: - src/Database/Migrations stubFiles: - tests/stubs/Facades.stub + treatPhpDocTypesAsCertain: false From 9bd20800d69ccc83bb4c1571df85c5346e25efd8 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 3 Jul 2024 14:59:48 -0400 Subject: [PATCH 092/111] remove other ignore rules --- phpstan-baseline.neon | 6 ------ 1 file changed, 6 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 485b5c525..451da8f0f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -73,7 +73,6 @@ parameters: - "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Attach|(Belongs|Morph)To)(One|Many)::(flushDuplicateCache|getRelationExistenceQueryForSelfJoin)\\(\\)\\.$#" - "#^Call to private method .+ of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Has|Morph)(One|Many)\\\\.$#" - - "#^If condition is always true\\.$#" path: src/Database/Relations/*.php - @@ -127,11 +126,6 @@ parameters: - "#^Return type \\(void\\) of method Winter\\\\Storm\\\\Support\\\\Testing\\\\Fakes\\\\MailFake::send\\(\\) should be compatible with return type \\(Illuminate\\\\Mail\\\\SentMessage\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\Mailer::send\\(\\)$#" path: src/Support/Testing/Fakes/MailFake.php - - - message: "#^Call to function is_null\\(\\) with Closure will always evaluate to false\\.$#" - count: 1 - path: src/Validation/Factory.php - - message: "#^Call to an undefined method Illuminate\\\\Routing\\\\Router\\:\\:before\\(\\)\\.$#" count: 1 From b3fabc6068f9d7c4afa510546832c9fb0adc305a Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 3 Sep 2024 10:36:30 -0400 Subject: [PATCH 093/111] follow Laravel method signature --- src/Translation/Translator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Translation/Translator.php b/src/Translation/Translator.php index aef6454f1..3045d3203 100644 --- a/src/Translation/Translator.php +++ b/src/Translation/Translator.php @@ -128,9 +128,9 @@ protected function getValidationSpecific($key, $replace, $locale) /** * @inheritDoc */ - protected function localeForChoice($locale) + protected function localeForChoice($key, $locale) { - $locale = parent::localeForChoice($locale); + $locale = parent::localeForChoice($key, locale); if (str_contains($locale, '-')) { $localeParts = explode('-', $locale, 2); From 3ca2c68afab3d82071152f471f8c6bb237481d61 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 3 Sep 2024 10:38:50 -0400 Subject: [PATCH 094/111] fix typo --- src/Translation/Translator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Translation/Translator.php b/src/Translation/Translator.php index 3045d3203..a9609f354 100644 --- a/src/Translation/Translator.php +++ b/src/Translation/Translator.php @@ -130,7 +130,7 @@ protected function getValidationSpecific($key, $replace, $locale) */ protected function localeForChoice($key, $locale) { - $locale = parent::localeForChoice($key, locale); + $locale = parent::localeForChoice($key, $locale); if (str_contains($locale, '-')) { $localeParts = explode('-', $locale, 2); From 99ddfa2c9c2023e00166997d8fa425262611c2fc Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 15 Sep 2024 15:37:51 -0400 Subject: [PATCH 095/111] use newer twig --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 562432f3f..b17348b85 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "symfony/console": "^6.4|^7.0", "symfony/process": "^7.1", "symfony/yaml": "^6.4|^7.0", - "twig/twig": "<3.9", + "twig/twig": "^3.9", "wikimedia/less.php": "~3.0", "wikimedia/minify": "~2.2", "winter/laravel-config-writer": "^1.0.1" From 659cdb5924296b63f31066546a1f1e1aa63f274f Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 15 Sep 2024 15:49:12 -0400 Subject: [PATCH 096/111] use latest 3.14+ twig, they fixed their shit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b17348b85..21949f579 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "symfony/console": "^6.4|^7.0", "symfony/process": "^7.1", "symfony/yaml": "^6.4|^7.0", - "twig/twig": "^3.9", + "twig/twig": "^3.14", "wikimedia/less.php": "~3.0", "wikimedia/minify": "~2.2", "winter/laravel-config-writer": "^1.0.1" From 91164e87705ff19d7fb6ec3690c93023f778e148 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 15 Sep 2024 16:12:20 -0400 Subject: [PATCH 097/111] force twig 3.x --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 21949f579..d8f293a75 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "symfony/console": "^6.4|^7.0", "symfony/process": "^7.1", "symfony/yaml": "^6.4|^7.0", - "twig/twig": "^3.14", + "twig/twig": "^3", "wikimedia/less.php": "~3.0", "wikimedia/minify": "~2.2", "winter/laravel-config-writer": "^1.0.1" From 3fff08ec4acc80bf63e0d5ba2aceb0cd5d8c1ecc Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 7 Oct 2024 10:37:36 -0400 Subject: [PATCH 098/111] use static return type to broaden the extension possibilities --- src/Auth/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Auth/Manager.php b/src/Auth/Manager.php index 419d4a19e..02935431c 100644 --- a/src/Auth/Manager.php +++ b/src/Auth/Manager.php @@ -171,7 +171,7 @@ public function hasUser() * Sets the user * @phpstan-param Models\User $user */ - public function setUser(Authenticatable $user): self + public function setUser(Authenticatable $user): static { $this->user = $user; return $this; From 3ffb684f2bc9c34365fb39e1ea9595d158b60345 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 21 Oct 2024 12:30:32 -0400 Subject: [PATCH 099/111] add GrammarTestCase --- tests/bootstrap.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index a89265b24..6a1b420f6 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,3 +2,4 @@ class_alias('Winter\Storm\Tests\TestCase', 'TestCase'); class_alias('Winter\Storm\Tests\DbTestCase', 'DbTestCase'); +class_alias('Winter\Storm\Tests\GrammarTestCase', 'GrammarTestCase'); From c3aa137bdb3e9d6f19a735b8180b690c3fc7d0c8 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 21 Oct 2024 13:23:51 -0400 Subject: [PATCH 100/111] fix phpstan --- phpstan-baseline.neon | 23 ++++++----------------- phpstan.neon | 4 ---- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e6b429dac..daaaca3c3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -7,11 +7,6 @@ parameters: - src/Auth/Models/Role.php - src/Auth/Models/User.php - - - messages: - - "# is not covariant with PHPDoc type TModel #" - path: src/Database/Builder.php - - messages: - "#^Parameter \\#1 \\$app of class Illuminate\\\\Database\\\\DatabaseManager constructor expects Illuminate\\\\Contracts\\\\Foundation\\\\Application, Illuminate\\\\Contracts\\\\Container\\\\Container given\\.$#" @@ -62,7 +57,6 @@ parameters: - messages: - "#^Call to an undefined method Illuminate\\\\Database\\\\ConnectionInterface::getName\\(\\)\\.$#" - - "#^Property Illuminate\\\\Database\\\\Query\\\\Builder::\\$orders \\(array\\) does not accept null\\.$#" path: src/Database/QueryBuilder.php - @@ -71,23 +65,18 @@ parameters: - "#^Call to an undefined method (TDeclaringModel of )?Illuminate\\\\Database\\\\Eloquent\\\\Model::((un)?bind(Deferred|EventOnce)|fireEvent|getRelationDefinition|newRelationPivot|reloadRelations)\\(\\)\\.$#" - "#^Call to an undefined method Illuminate\\\\Database\\\\Query\\\\Builder::lists\\(\\)\\.$#" - "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Attach|(Belongs|Morph)To)(One|Many)::(flushDuplicateCache|getRelationExistenceQueryForSelfJoin)\\(\\)\\.$#" - - "#^Call to private method .+ of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Has|Morph)(One|Many)\\\\.$#" + - "#^Call to private method .+ of parent class Illuminate\\\\Database\\\\Eloquent\\\\Relations#" paths: - src/Database/Relations/*.php - messages: - - "#^Parameter \\#2 \\$columns of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::(simpleP|p)aginate\\(\\) expects array, int\\|null given\\.$#" - - "#^Parameter \\#2 \\$currentPage \\(int\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::paginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::paginate\\(\\)$#" - - "#^Parameter \\#2 \\$currentPage \\(int(\\|null)?\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::(simpleP|p)aginate\\(\\) should be compatible with parameter \\$columns \\(array\\\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::(simpleP|p)aginate\\(\\)$#" - - "#^Parameter \\#3 \\$columns \\(array\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::(simpleP|p)aginate\\(\\) should be compatible with parameter \\$pageName \\(string\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::(simpleP|p)aginate\\(\\)$#" + - "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$(children|sessionKey)\\.$#" - "#^Parameter \\#3 \\$pageName of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::(simpleP|p)aginate\\(\\) expects string, array given\\.$#" - - "#^Parameter \\#4 \\$pageName \\(string\\) of method Winter\\\\Storm\\\\Database\\\\Relations\\\\(Belongs|Morph)ToMany::(simpleP|p)aginate\\(\\) should be compatible with parameter \\$page \\(int\\|null\\) of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\(Belongs|Morph)ToMany\\::(simpleP|p)aginate\\(\\)$#" - "#^Parameter \\#4 \\$page of method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\::(simpleP|p)aginate\\(\\) expects int\\|null, string given.$#" paths: - - src/Database/Relations/BelongsToMany.php - - src/Database/Relations/MorphToMany.php + - src/Database/Relations/* - messages: @@ -119,7 +108,7 @@ parameters: - messages: - - "#^Call to an undefined method Illuminate\\\\Routing\\\\Router\\:\\:(after|before)\\(\\)\\.$#" + - "#^Call to an undefined method Illuminate\\\\Routing\\\\Router::(after|before)\\(\\)\\.$#" path: src/Foundation/Application.php - @@ -137,9 +126,9 @@ parameters: - messages: - - "#^Access to an undefined property TDeclaringModel of Illuminate\\\\Database\\\\Eloquent\\\\Model::\\$sessionKey\\.#" + - "#^Parameter .+ of method (Illuminate|Winter).+::(paginate|simplePaginate).+ (expects|should be compatible with)#" paths: - - src/Database/Relations/BelongsToMany.php + - src/Database/Relations/Concerns/BelongsOrMorphsToMany.php - messages: diff --git a/phpstan.neon b/phpstan.neon index c56c5ca5b..423e6134d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,10 +12,6 @@ parameters: - src/Parse/PHP/ArrayPrinter.php - src/Foundation/Console/KeyGenerateCommand.php - src/Scaffold/GeneratorCommand.php - ignoreErrors: - - message: '#Call to private method select\(\)#' - paths: - - src/Database/Relations/Concerns/CanBeCounted.php disableSchemaScan: true databaseMigrationsPath: - src/Auth/Migrations From e06e4b49eae5138bf0a16eb06ab4df8d5cd918e5 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 21 Oct 2024 14:53:08 -0400 Subject: [PATCH 101/111] fix translator tests --- tests/Translation/TranslatorTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/Translation/TranslatorTest.php b/tests/Translation/TranslatorTest.php index 29b6f8cd5..e26745f60 100644 --- a/tests/Translation/TranslatorTest.php +++ b/tests/Translation/TranslatorTest.php @@ -221,8 +221,9 @@ public function testSetMethodCanOverwriteAnEntireGroupForALocale() public function testChoiceMethodProperlyLoadsAndRetrievesItem() { - $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock(); + $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock(); $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line'); + $t->expects($this->once())->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en'); $t->setSelector($selector = m::mock(MessageSelector::class)); $selector->shouldReceive('choose')->once()->with('line', 10, 'en')->andReturn('choiced'); @@ -231,8 +232,9 @@ public function testChoiceMethodProperlyLoadsAndRetrievesItem() public function testChoiceMethodProperlyCountsCollectionsAndLoadsAndRetrievesItem() { - $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock(); + $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock(); $t->expects($this->exactly(2))->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line'); + $t->expects($this->exactly(2))->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en'); $t->setSelector($selector = m::mock(MessageSelector::class)); $selector->shouldReceive('choose')->twice()->with('line', 3, 'en')->andReturn('choiced'); From 545aaf2bb9da86cefc0592305d1d93d51cdf56d2 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 21 Oct 2024 15:08:58 -0400 Subject: [PATCH 102/111] add method used in parent SQLiteGrammar --- tests/GrammarTestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/GrammarTestCase.php b/tests/GrammarTestCase.php index cd1953215..b95ffd25f 100644 --- a/tests/GrammarTestCase.php +++ b/tests/GrammarTestCase.php @@ -20,6 +20,7 @@ protected function tearDown(): void protected function setupConnection(Blueprint $blueprint) { $connection = m::mock(Connection::class); + $connection->shouldReceive('getServerVersion')->andReturn('3.35'); $connection->shouldReceive('getSchemaBuilder')->andReturn($this->getSchemaBuilder($blueprint)); $connection->shouldReceive('scalar')->andReturn(''); $this->connection = $connection; From 549cf4ca9d01b99941b43ff47bb4abbe29954bea Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Mon, 21 Oct 2024 23:46:35 -0400 Subject: [PATCH 103/111] fix logic bug in laravel sqlite grammar --- src/Database/Schema/Grammars/SQLiteGrammar.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index bbb6e7b44..33497cb96 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -13,6 +13,20 @@ class SQLiteGrammar extends SQLiteGrammarBase { + /** + * @inheritDoc + */ + public function getAlterCommands(Connection $connection) + { + $alterCommands = ['change', 'primary', 'dropPrimary', 'foreign', 'dropForeign']; + + if (version_compare($connection->getServerVersion(), '3.35', '>=')) { + $alterCommands[] = 'dropColumn'; + } + + return $alterCommands; + } + /** * Compile a change column command into a series of SQL statements. * From 9161946f7e71f2a1483dcc052e00c7720b21fd0d Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 22 Oct 2024 00:35:22 -0400 Subject: [PATCH 104/111] remove extra whitespaces --- src/Database/Schema/Grammars/SQLiteGrammar.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 33497cb96..af4c1472e 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -17,7 +17,9 @@ class SQLiteGrammar extends SQLiteGrammarBase * @inheritDoc */ public function getAlterCommands(Connection $connection) - { + { + // Can be removed when the following PR gets merged: + // https://github.com/laravel/framework/pull/53262 $alterCommands = ['change', 'primary', 'dropPrimary', 'foreign', 'dropForeign']; if (version_compare($connection->getServerVersion(), '3.35', '>=')) { From 1c9acc9b4337fbab355dcf2ca833e22cb2b02f7a Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 22 Oct 2024 22:52:30 -0400 Subject: [PATCH 105/111] Revert "remove extra whitespaces" This reverts commit 9161946f7e71f2a1483dcc052e00c7720b21fd0d. --- src/Database/Schema/Grammars/SQLiteGrammar.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index af4c1472e..33497cb96 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -17,9 +17,7 @@ class SQLiteGrammar extends SQLiteGrammarBase * @inheritDoc */ public function getAlterCommands(Connection $connection) - { - // Can be removed when the following PR gets merged: - // https://github.com/laravel/framework/pull/53262 + { $alterCommands = ['change', 'primary', 'dropPrimary', 'foreign', 'dropForeign']; if (version_compare($connection->getServerVersion(), '3.35', '>=')) { From bcd83bb3e7b1d348310ab56563072508d6d88827 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 22 Oct 2024 23:07:09 -0400 Subject: [PATCH 106/111] logic is good, revert the change --- src/Database/Schema/Grammars/SQLiteGrammar.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Database/Schema/Grammars/SQLiteGrammar.php b/src/Database/Schema/Grammars/SQLiteGrammar.php index 33497cb96..bbb6e7b44 100755 --- a/src/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Database/Schema/Grammars/SQLiteGrammar.php @@ -13,20 +13,6 @@ class SQLiteGrammar extends SQLiteGrammarBase { - /** - * @inheritDoc - */ - public function getAlterCommands(Connection $connection) - { - $alterCommands = ['change', 'primary', 'dropPrimary', 'foreign', 'dropForeign']; - - if (version_compare($connection->getServerVersion(), '3.35', '>=')) { - $alterCommands[] = 'dropColumn'; - } - - return $alterCommands; - } - /** * Compile a change column command into a series of SQL statements. * From 8627fab4421f6f00fca9d2f3df1a7091bbde7c32 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 17 Nov 2024 07:16:49 -0500 Subject: [PATCH 107/111] fix ignore pattern --- phpstan-baseline.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index daaaca3c3..3171b0363 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -92,7 +92,7 @@ parameters: - messages: - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::queue\\(\\)$#" - - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::queue\\(\\)$#" + - "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queue\\(\\) should be compatible with parameter \\$queue \\(BackedEnum\\|string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::queue\\(\\)$#" - "#^Parameter \\#2 \\$view \\(array\\|string\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::queueOn\\(\\) should be compatible with parameter \\$view \\(Illuminate\\\\Contracts\\\\Mail\\\\Mailable\\) of method Illuminate\\\\Mail\\\\Mailer::queueOn\\(\\)$#" - "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue::later\\(\\)$#" - "#^Parameter \\#3 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer::later\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Mail\\\\Mailer::later\\(\\)$#" From 76c096ded468463582aba180474ae2598a16beae Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 17 Nov 2024 07:17:01 -0500 Subject: [PATCH 108/111] add namespace --- tests/GrammarTestCase.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/GrammarTestCase.php b/tests/GrammarTestCase.php index b95ffd25f..c5418e2a7 100644 --- a/tests/GrammarTestCase.php +++ b/tests/GrammarTestCase.php @@ -1,5 +1,7 @@ Date: Sun, 17 Nov 2024 09:15:32 -0500 Subject: [PATCH 109/111] update TranslatorTest after Laravel changes to choice() method --- tests/Translation/TranslatorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Translation/TranslatorTest.php b/tests/Translation/TranslatorTest.php index e26745f60..03ee57195 100644 --- a/tests/Translation/TranslatorTest.php +++ b/tests/Translation/TranslatorTest.php @@ -222,7 +222,7 @@ public function testSetMethodCanOverwriteAnEntireGroupForALocale() public function testChoiceMethodProperlyLoadsAndRetrievesItem() { $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock(); - $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line'); + $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line'); $t->expects($this->once())->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en'); $t->setSelector($selector = m::mock(MessageSelector::class)); $selector->shouldReceive('choose')->once()->with('line', 10, 'en')->andReturn('choiced'); @@ -233,7 +233,7 @@ public function testChoiceMethodProperlyLoadsAndRetrievesItem() public function testChoiceMethodProperlyCountsCollectionsAndLoadsAndRetrievesItem() { $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock(); - $t->expects($this->exactly(2))->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line'); + $t->expects($this->exactly(2))->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line'); $t->expects($this->exactly(2))->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en'); $t->setSelector($selector = m::mock(MessageSelector::class)); $selector->shouldReceive('choose')->twice()->with('line', 3, 'en')->andReturn('choiced'); From 13d31845f41b752946881aa0fae1142f9b00f469 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 17 Nov 2024 09:21:02 -0500 Subject: [PATCH 110/111] update property signature to match Laravel --- src/Config/Repository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Config/Repository.php b/src/Config/Repository.php index 719802dfe..04249f97b 100644 --- a/src/Config/Repository.php +++ b/src/Config/Repository.php @@ -31,7 +31,7 @@ class Repository extends BaseRepository implements ArrayAccess, RepositoryContra /** * All of the configuration items. * - * @var array + * @var array */ protected $items = []; From 38364d170704fc343f77951369ccc420f22f2025 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sat, 8 Feb 2025 13:28:39 -0500 Subject: [PATCH 111/111] Revert #191, this has been merged upstream. This reverts commit 752c16253ca7945e68423e91aa0e8ecbeb4fa064. --- src/Database/Connectors/ConnectionFactory.php | 17 -------- src/Database/Connectors/SQLiteConnector.php | 43 ------------------- 2 files changed, 60 deletions(-) delete mode 100644 src/Database/Connectors/SQLiteConnector.php diff --git a/src/Database/Connectors/ConnectionFactory.php b/src/Database/Connectors/ConnectionFactory.php index a9debce91..a193640fc 100644 --- a/src/Database/Connectors/ConnectionFactory.php +++ b/src/Database/Connectors/ConnectionFactory.php @@ -39,23 +39,6 @@ protected function createPdoResolverWithHosts(array $config) }; } - /** - * Create a connector instance based on the configuration. - * - * @param array $config - * @return \Illuminate\Database\Connectors\ConnectorInterface - * - * @throws \InvalidArgumentException - */ - public function createConnector(array $config) - { - if (array_get($config, 'driver') === 'sqlite') { - return new SQLiteConnector; - } else { - return parent::createConnector($config); - } - } - /** * Create a new connection instance. * diff --git a/src/Database/Connectors/SQLiteConnector.php b/src/Database/Connectors/SQLiteConnector.php deleted file mode 100644 index d9209ca1d..000000000 --- a/src/Database/Connectors/SQLiteConnector.php +++ /dev/null @@ -1,43 +0,0 @@ -getOptions($config); - - // SQLite supports "in-memory" databases that only last as long as the owning - // connection does. These are useful for tests or for short lifetime store - // querying. In-memory databases may only have a single open connection. - if ($config['database'] === ':memory:') { - return $this->createConnection('sqlite::memory:', $config, $options); - } - - $path = realpath($config['database']); - if (!file_exists($path)) { - $path = realpath(base_path($config['database'])); - } - - // Here we'll verify that the SQLite database exists before going any further - // as the developer probably wants to know if the database exists and this - // SQLite driver will not throw any exception if it does not by default. - if ($path === false) { - throw new SQLiteDatabaseDoesNotExistException($config['database']); - } - - return $this->createConnection("sqlite:{$path}", $config, $options); - } -}