diff --git a/src/Language/Cast.php b/src/Language/Cast.php new file mode 100644 index 0000000..6388e73 --- /dev/null +++ b/src/Language/Cast.php @@ -0,0 +1,58 @@ +stringize($grammar, $this->expression); + $type = match ($this->type) { + 'bigint' => $this->typeBigInt($grammar), + + 'int' => $this->typeInt($grammar), + default => throw new RuntimeException("Unknown casting type '{$this->type}'."), + }; + + return match ($this->identify($grammar)) { + 'pgsql' => "({$expression})::{$type}", + default => "(cast({$expression} as {$type}))", + }; + } + + private function typeBigInt(Grammar $grammar): string + { + return match ($this->identify($grammar)) { + 'mysql' => 'signed', + default => 'bigint', + }; + } + + private function typeInt(Grammar $grammar): string + { + return match ($this->identify($grammar)) { + 'mysql' => 'signed', + default => 'int', + }; + } +} diff --git a/tests/Language/CastTest.php b/tests/Language/CastTest.php new file mode 100644 index 0000000..391185e --- /dev/null +++ b/tests/Language/CastTest.php @@ -0,0 +1,49 @@ +expect(new Cast('val', 'bigint')) + ->toBeExecutable(function (Blueprint $table) { + $table->string('val'); + }) + ->toBeMysql('cast(`val` as signed)') + ->toBePgsql('("val")::bigint') + ->toBeSqlite('cast("val" as bigint)') + ->toBeSqlsrv('cast([val] as bigint)'); + +it('can cast an expression to an bigint') + ->expect(new Cast(new Expression(3.1415), 'bigint')) + ->toBeExecutable() + ->toBeMysql('cast(3.1415` as signed)') + ->toBePgsql('(3.1415)::bigint') + ->toBeSqlite('cast(3.1415 as bigint)') + ->toBeSqlsrv('cast(3.1415 as bigint)'); + +it('can cast a column to an int') + ->expect(new Cast('val', 'int')) + ->toBeExecutable(function (Blueprint $table) { + $table->string('val'); + }) + ->toBeMysql('cast(`val` as signed)') + ->toBePgsql('("val")::int') + ->toBeSqlite('cast("val" as int)') + ->toBeSqlsrv('cast([val] as int)'); + +it('can cast an expression to an int') + ->expect(new Cast(new Expression(3.1415), 'int')) + ->toBeExecutable() + ->toBeMysql('cast(3.1415` as signed)') + ->toBePgsql('(3.1415)::int') + ->toBeSqlite('cast(3.1415 as int)') + ->toBeSqlsrv('cast(3.1415 as int)'); + +it('throws an exception for unknown types', fn (string $type) => new Cast('0', $type))->with([ + 'enum', + 'varchar', + 'timestamptz', +]);