diff --git a/src/Tempest/Database/src/Exceptions/InvalidValue.php b/src/Tempest/Database/src/Exceptions/InvalidValue.php new file mode 100644 index 000000000..25c49e714 --- /dev/null +++ b/src/Tempest/Database/src/Exceptions/InvalidValue.php @@ -0,0 +1,15 @@ +statements[] = new SetStatement( + name: $name, + values: $values, + nullable: $nullable, + default: $default, + ); + + return $this; + } + public function compile(DatabaseDialect $dialect): string { $compiled = sprintf( diff --git a/src/Tempest/Database/src/QueryStatements/SetStatement.php b/src/Tempest/Database/src/QueryStatements/SetStatement.php new file mode 100644 index 000000000..0ab0a9e29 --- /dev/null +++ b/src/Tempest/Database/src/QueryStatements/SetStatement.php @@ -0,0 +1,39 @@ +values)) { + throw new InvalidValue($this->name, json_encode($this->values)); + } + + return match($dialect) { + DatabaseDialect::MYSQL => sprintf( + '`%s` SET (%s) %s %s', + $this->name, + "'" . implode("', '", $this->values) . "'", + $this->default ? "DEFAULT '$this->default'" : '', + $this->nullable ? '' : 'NOT NULL', + ), + default => throw new UnsupportedDialect() + }; + } +} diff --git a/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php b/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php index bd6366cfb..4ff65375e 100644 --- a/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php +++ b/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php @@ -4,11 +4,14 @@ namespace Tests\Tempest\Integration\Database\QueryStatements; +use Tempest\Database\DatabaseDialect; use Tempest\Database\Exceptions\InvalidDefaultValue; +use Tempest\Database\Exceptions\InvalidValue; use Tempest\Database\Migration; use Tempest\Database\Migrations\CreateMigrationsTable; use Tempest\Database\QueryStatement; use Tempest\Database\QueryStatements\CreateTableStatement; +use Tempest\Database\UnsupportedDialect; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; /** @@ -53,6 +56,40 @@ public function down(): QueryStatement|null $this->assertTrue(true); } + public function test_set_statement(): void + { + $migration = new class () implements Migration { + public function getName(): string + { + return '0'; + } + + public function up(): QueryStatement|null + { + return (new CreateTableStatement('table')) + ->set('set', values: ['foo', 'bar'], default: 'foo'); + } + + public function down(): QueryStatement|null + { + return null; + } + }; + + match($this->container->get(DatabaseDialect::class)) { + DatabaseDialect::MYSQL => '', + DatabaseDialect::SQLITE => $this->expectException(UnsupportedDialect::class), + DatabaseDialect::POSTGRESQL => $this->expectException(UnsupportedDialect::class), + }; + + $this->migrate( + CreateMigrationsTable::class, + $migration + ); + + $this->assertTrue(true); + } + public function test_invalid_json_default(): void { $migration = new class () implements Migration { @@ -81,4 +118,33 @@ public function down(): QueryStatement|null $migration ); } + + public function test_invalid_set_values(): void + { + $migration = new class () implements Migration { + public function getName(): string + { + return '0'; + } + + public function up(): QueryStatement|null + { + return (new CreateTableStatement('table')) + ->set('set', values: []); + } + + public function down(): QueryStatement|null + { + return null; + } + }; + + $this->expectException(InvalidValue::class); + $this->expectExceptionMessage("Value '[]' provided for set is not valid"); + + $this->migrate( + CreateMigrationsTable::class, + $migration + ); + } }