diff --git a/CHANGELOG.md b/CHANGELOG.md index f7d00497..954b9e52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # v8.3.0 (2024-11-08) +- add support for IDENTITY columns (#243) - consolidate schema options formatting (#241) - add support for invisible columns (#240) - add support for change streams using Blueprint (#230) diff --git a/compose.yaml b/compose.yaml index f5a9fb60..6aafb16b 100644 --- a/compose.yaml +++ b/compose.yaml @@ -8,4 +8,4 @@ services: depends_on: - emulator emulator: - image: "gcr.io/cloud-spanner-emulator/emulator:1.5.23" + image: "gcr.io/cloud-spanner-emulator/emulator:1.5.28" diff --git a/phpstan.neon b/phpstan.neon index 822d7bda..bbfce752 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,13 +9,13 @@ parameters: path: src/Concerns/ManagesPartitionedDml.php - message: '#^Unable to resolve the template type TKey in call to function collect$#' path: src/Concerns/ManagesSessionPool.php - - message: "#^Strict comparison using \\=\\=\\= between Illuminate\\\\Database\\\\Query\\\\IndexHint and null will always evaluate to false\\.$#" - count: 1 - path: src/Query/Builder.php - message: '#^Parameter \#1 \$pdo of method Illuminate\\Database\\Connection::__construct\(\) expects Closure|PDO, null given\.$#' path: src/Connection.php - message: '#^Method Colopl\\Spanner\\Connection::selectWithOptions\(\) should return array but returns mixed\.$#' path: src/Connection.php + - message: "#^Method Colopl\\\\Spanner\\\\Connection\\:\\:cursor\\(\\) should return Generator\\ but returns Generator\\\\.$#" + path: src/Connection.php + count: 1 - message: '#^Generator expects value type array, mixed given.$#' path: src/Connection.php count: 1 diff --git a/src/Schema/ColumnDefinition.php b/src/Schema/ColumnDefinition.php index 94b1fc6c..d0532ad3 100644 --- a/src/Schema/ColumnDefinition.php +++ b/src/Schema/ColumnDefinition.php @@ -20,6 +20,7 @@ namespace Colopl\Spanner\Schema; +use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\ColumnDefinition as BaseColumnDefinition; /** @@ -33,6 +34,7 @@ * @property int|null $precision * @property int|null $scale * @property bool|null $useCurrent + * @property string|Expression|true|null $generatedAs * @property string|null $virtualAs * @property bool|null $storedAs */ diff --git a/src/Schema/Grammar.php b/src/Schema/Grammar.php index 247cf20e..9289a79e 100644 --- a/src/Schema/Grammar.php +++ b/src/Schema/Grammar.php @@ -38,7 +38,7 @@ class Grammar extends BaseGrammar /** * @inheritdoc */ - protected $modifiers = ['Nullable', 'Default', 'Invisible', 'UseSequence']; + protected $modifiers = ['Nullable', 'Default', 'GeneratedAs', 'Invisible', 'UseSequence']; /** * Compile the query to determine the tables. @@ -733,6 +733,30 @@ protected function modifyInvisible(Blueprint $blueprint, Fluent $column) : null; } + /** + * Get the SQL for an identity column modifier. + * + * @param Blueprint $blueprint + * @param ColumnDefinition $column + * @return string|null + */ + protected function modifyGeneratedAs(Blueprint $blueprint, Fluent $column): ?string + { + $as = $column->generatedAs; + + if ($as === null) { + return null; + } + + $expression = match (true) { + $as === true => 'bit_reversed_positive', + $as instanceof Expression => $this->getValue($as), + default => $as, + }; + + return " generated by default as identity ({$expression})"; + } + /** * @param Blueprint $blueprint * @param IntColumnDefinition $column diff --git a/tests/Schema/BlueprintTest.php b/tests/Schema/BlueprintTest.php index ba649661..6bb46992 100644 --- a/tests/Schema/BlueprintTest.php +++ b/tests/Schema/BlueprintTest.php @@ -694,6 +694,8 @@ public function test_default_values(): void $table->uuid('id'); $table->integer('null')->default(null)->nullable(); $table->integer('int')->default(1); + $table->integer('int_gen')->generatedAs(); + $table->integer('int_genc')->generatedAs('bit_reversed_positive start counter with 2'); $table->integer('int_seq')->useSequence(); $table->bigInteger('bigint')->default(1); $table->integer('bigint_seq')->useSequence(); @@ -733,6 +735,8 @@ public function test_default_values(): void '`id` string(36) not null', '`null` int64', '`int` int64 not null default (1)', + '`int_gen` int64 not null generated by default as identity (bit_reversed_positive)', + '`int_genc` int64 not null generated by default as identity (bit_reversed_positive start counter with 2)', '`int_seq` int64 not null default (get_next_sequence_value(sequence `' . $tableName . '_int_seq_sequence`))', '`bigint` int64 not null default (1)', '`bigint_seq` int64 not null default (get_next_sequence_value(sequence `' . $tableName . '_bigint_seq_sequence`))', @@ -772,6 +776,8 @@ public function test_default_values(): void $this->assertSame(null, $result['null']); $this->assertSame(1, $result['int']); + $this->assertIsInt($result['int_gen']); + $this->assertIsInt($result['int_genc']); $this->assertIsInt($result['int_seq']); $this->assertSame(1, $result['bigint']); $this->assertIsInt($result['bigint_seq']);