Skip to content

Commit f84cf41

Browse files
authored
feat(database): add current to date (#2100)
1 parent cf812eb commit f84cf41

4 files changed

Lines changed: 84 additions & 5 deletions

File tree

packages/database/src/Config/DatabaseDialect.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ public function quoteIdentifier(string $identifier): string
2929
};
3030
}
3131

32+
public function encloseExpressionDefault(string $expression): string
33+
{
34+
return match ($this) {
35+
self::MYSQL => sprintf('(%s)', $expression),
36+
default => sprintf('%s', $expression),
37+
};
38+
}
39+
3240
public function isTableNotFoundError(QueryWasInvalid $queryWasInvalid): bool
3341
{
3442
$pdoException = $queryWasInvalid->pdoException;

packages/database/src/QueryStatements/CreateTableStatement.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,13 @@ public function datetime(string $name, bool $nullable = false, ?string $default
249249
/**
250250
* Adds a `DATE` column to the table.
251251
*/
252-
public function date(string $name, bool $nullable = false, ?string $default = null): self
252+
public function date(string $name, bool $nullable = false, ?string $default = null, bool $current = false): self
253253
{
254254
$this->statements[] = new DateStatement(
255255
name: $name,
256256
nullable: $nullable,
257257
default: $default,
258+
current: $current,
258259
);
259260

260261
return $this;

packages/database/src/QueryStatements/DateStatement.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tempest\Database\QueryStatements;
66

7+
use InvalidArgumentException;
78
use Tempest\Database\Config\DatabaseDialect;
89
use Tempest\Database\QueryStatement;
910

@@ -13,15 +14,28 @@ public function __construct(
1314
private string $name,
1415
private bool $nullable = false,
1516
private ?string $default = null,
17+
private bool $current = false,
1618
) {}
1719

1820
public function compile(DatabaseDialect $dialect): string
1921
{
22+
if ($this->default !== null && $this->current) {
23+
throw new InvalidArgumentException("Cannot set both `default` and `current` for date column `{$this->name}`.");
24+
}
25+
26+
$default = match (true) {
27+
$this->current => $dialect->encloseExpressionDefault('CURRENT_DATE'),
28+
$this->default !== null => "'{$this->default}'",
29+
default => null,
30+
};
31+
32+
$name = $dialect->quoteIdentifier($this->name);
33+
2034
return sprintf(
21-
'%s DATE %s %s',
22-
$dialect->quoteIdentifier($this->name),
23-
$this->default !== null ? "DEFAULT '{$this->default}'" : '',
24-
$this->nullable ? '' : 'NOT NULL',
35+
'%s DATE%s%s',
36+
$name,
37+
$default !== null ? " DEFAULT {$default}" : '',
38+
$this->nullable ? '' : ' NOT NULL',
2539
);
2640
}
2741
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Tempest\Database\Tests\QueryStatements;
4+
5+
use PHPUnit\Framework\Attributes\Test;
6+
use PHPUnit\Framework\TestCase;
7+
use Tempest\Database\Config\DatabaseDialect;
8+
use Tempest\Database\QueryStatements\DateStatement;
9+
10+
final class DateStatementTest extends TestCase
11+
{
12+
#[Test]
13+
public function test_date(): void
14+
{
15+
$statement = new DateStatement(
16+
name: 'foo',
17+
default: '2026-01-01',
18+
);
19+
20+
$expectedMysql = '`foo` DATE DEFAULT \'2026-01-01\' NOT NULL';
21+
$expectedPgsql = '"foo" DATE DEFAULT \'2026-01-01\' NOT NULL';
22+
23+
$this->assertSame($expectedMysql, $statement->compile(DatabaseDialect::MYSQL));
24+
$this->assertSame($expectedPgsql, $statement->compile(DatabaseDialect::POSTGRESQL));
25+
}
26+
27+
#[Test]
28+
public function test_date_with_current(): void
29+
{
30+
$statement = new DateStatement(
31+
name: 'foo',
32+
nullable: true,
33+
current: true,
34+
);
35+
36+
$expectedMysql = '`foo` DATE DEFAULT (CURRENT_DATE)';
37+
$expectedPgsql = '"foo" DATE DEFAULT CURRENT_DATE';
38+
39+
$this->assertSame($expectedMysql, $statement->compile(DatabaseDialect::MYSQL));
40+
$this->assertSame($expectedPgsql, $statement->compile(DatabaseDialect::POSTGRESQL));
41+
}
42+
43+
#[Test]
44+
public function test_date_with_default_and_current(): void
45+
{
46+
$this->expectException(\InvalidArgumentException::class);
47+
48+
$statement = new DateStatement(
49+
name: 'foo',
50+
nullable: true,
51+
default: '2026-01-01',
52+
current: true,
53+
);
54+
$statement->compile(DatabaseDialect::MYSQL);
55+
}
56+
}

0 commit comments

Comments
 (0)