Skip to content

Commit

Permalink
feat: move default time precision to schema builder
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdw committed Jul 2, 2024
1 parent 2dc1cd1 commit 991aae2
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 42 deletions.
8 changes: 0 additions & 8 deletions src/Illuminate/Database/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,6 @@ public function getDateFormat()
return 'Y-m-d H:i:s';
}

/**
* Get the precision for storing datetimes (null uses the database default).
*/
public function getDatetimePrecision(): ?int
{
return 0;
}

/**
* Get the grammar's table prefix.
*
Expand Down
18 changes: 9 additions & 9 deletions src/Illuminate/Database/Schema/Blueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ public function date($column)
*/
public function dateTime($column, $precision = null)
{
$precision ??= $this->defaultDatetimePrecision();
$precision ??= $this->defaultTimePrecision();

return $this->addColumn('dateTime', $column, compact('precision'));
}
Expand All @@ -1120,7 +1120,7 @@ public function dateTime($column, $precision = null)
*/
public function dateTimeTz($column, $precision = null)
{
$precision ??= $this->defaultDatetimePrecision();
$precision ??= $this->defaultTimePrecision();

return $this->addColumn('dateTimeTz', $column, compact('precision'));
}
Expand All @@ -1134,7 +1134,7 @@ public function dateTimeTz($column, $precision = null)
*/
public function time($column, $precision = null)
{
$precision ??= $this->defaultDatetimePrecision();
$precision ??= $this->defaultTimePrecision();

return $this->addColumn('time', $column, compact('precision'));
}
Expand All @@ -1148,7 +1148,7 @@ public function time($column, $precision = null)
*/
public function timeTz($column, $precision = null)
{
$precision ??= $this->defaultDatetimePrecision();
$precision ??= $this->defaultTimePrecision();

return $this->addColumn('timeTz', $column, compact('precision'));
}
Expand All @@ -1162,7 +1162,7 @@ public function timeTz($column, $precision = null)
*/
public function timestamp($column, $precision = null)
{
$precision ??= $this->defaultDatetimePrecision();
$precision ??= $this->defaultTimePrecision();

return $this->addColumn('timestamp', $column, compact('precision'));
}
Expand All @@ -1176,7 +1176,7 @@ public function timestamp($column, $precision = null)
*/
public function timestampTz($column, $precision = null)
{
$precision ??= $this->defaultDatetimePrecision();
$precision ??= $this->defaultTimePrecision();

return $this->addColumn('timestampTz', $column, compact('precision'));
}
Expand Down Expand Up @@ -1778,10 +1778,10 @@ public function getChangedColumns()
}

/**
* Get the default datetime precision.
* Get the default time precision.
*/
protected function defaultDatetimePrecision(): ?int
protected function defaultTimePrecision(): ?int
{
return $this->grammar->getDatetimePrecision();
return $this->connection->getSchemaBuilder()::$defaultTimePrecision;
}
}
13 changes: 13 additions & 0 deletions src/Illuminate/Database/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class Builder
*/
public static $defaultStringLength = 255;

/**
* The default time precision for migrations.
*/
public static ?int $defaultTimePrecision = 0;

/**
* The default relationship morph key type.
*
Expand Down Expand Up @@ -71,6 +76,14 @@ public static function defaultStringLength($length)
static::$defaultStringLength = $length;
}

/**
* Set the default time precision for migrations.
*/
public static function defaultTimePrecision(?int $precision): void
{
static::$defaultTimePrecision = $precision;
}

/**
* Set the default morph key type for migrations.
*
Expand Down
17 changes: 14 additions & 3 deletions tests/Database/DatabaseMariaDbSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
namespace Database;

use Illuminate\Database\Connection;
use Illuminate\Database\MariaDbConnection;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\MariaDbGrammar;
use Illuminate\Database\Schema\MariaDbBuilder;
use Illuminate\Tests\Database\Fixtures\Enums\Foo;
use Mockery as m;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -1456,17 +1458,26 @@ public function testGrammarsAreMacroable()
$this->assertTrue($c);
}

protected function getConnection(MariaDbGrammar $grammar = null)
{
protected function getConnection(
?MariaDbGrammar $grammar = null,
?MariaDbBuilder $builder = null,
) {
$grammar ??= $this->getGrammar();
$builder ??= $this->getBuilder();

return m::mock(Connection::class)
return m::mock(MariaDbConnection::class)
->shouldReceive('getSchemaGrammar')->andReturn($grammar)
->shouldReceive('getSchemaBuilder')->andReturn($builder)
->getMock();
}

public function getGrammar()
{
return new MariaDbGrammar;
}

public function getBuilder()
{
return mock(MariaDbBuilder::class);
}
}
14 changes: 12 additions & 2 deletions tests/Database/DatabaseMySqlSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\MySqlGrammar;
use Illuminate\Database\Schema\MySqlBuilder;
use Illuminate\Tests\Database\Fixtures\Enums\Foo;
use Mockery as m;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -1456,17 +1457,26 @@ public function testGrammarsAreMacroable()
$this->assertTrue($c);
}

protected function getConnection(MySqlGrammar $grammar = null)
{
protected function getConnection(
?MySqlGrammar $grammar = null,
?MySqlBuilder $builder = null,
) {
$grammar ??= $this->getGrammar();
$builder ??= $this->getBuilder();

return m::mock(Connection::class)
->shouldReceive('getSchemaGrammar')->andReturn($grammar)
->shouldReceive('getSchemaBuilder')->andReturn($builder)
->getMock();
}

public function getGrammar()
{
return new MySqlGrammar;
}

public function getBuilder()
{
return mock(MySqlBuilder::class);
}
}
29 changes: 16 additions & 13 deletions tests/Database/DatabasePostgresSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Database\Schema\Builder;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\PostgresGrammar;
use Illuminate\Database\Schema\PostgresBuilder;
use Mockery as m;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\TestWith;
Expand Down Expand Up @@ -697,8 +698,8 @@ public function testAddingJsonb()
#[DataProvider('datetimeAndPrecisionProvider')]
public function testAddingDatetimeMethods(string $method, string $type, ?int $userPrecision, false|int|null $grammarPrecision, ?int $expected)
{
$grammar = $this->getGrammar($grammarPrecision);
$blueprint = new Blueprint($this->getConnection($grammar), 'users');
PostgresBuilder::defaultTimePrecision($grammarPrecision);
$blueprint = new Blueprint($this->getConnection(), 'users');
$blueprint->{$method}('created_at', $userPrecision);
$statements = $blueprint->toSql();
$type = is_null($expected) ? $type : "{$type}({$expected})";
Expand All @@ -711,6 +712,7 @@ public function testAddingDatetimeMethods(string $method, string $type, ?int $us
#[TestWith(['timestampsTz'])]
public function testAddingTimestamps(string $method)
{
PostgresBuilder::defaultTimePrecision(0);
$blueprint = new Blueprint($this->getConnection(), 'users');
$blueprint->{$method}();
$statements = $blueprint->toSql();
Expand Down Expand Up @@ -1074,26 +1076,27 @@ public function testCompileColumns()
$this->assertStringContainsString("where c.relname = 'table' and n.nspname = 'public'", $statement);
}

protected function getConnection(PostgresGrammar $grammar = null)
{
protected function getConnection(
?PostgresGrammar $grammar = null,
?PostgresBuilder $builder = null
) {
$grammar ??= $this->getGrammar();
$builder ??= $this->getBuilder();

return m::mock(Connection::class)
->shouldReceive('getSchemaGrammar')->andReturn($grammar)
->shouldReceive('getSchemaBuilder')->andReturn($builder)
->getMock();
}

public function getGrammar(false|int|null $precision = false)
public function getGrammar()
{
if ($precision === false) {
return new PostgresGrammar;
}
return new PostgresGrammar;
}

return m::mock(PostgresGrammar::class)
->makePartial()
->shouldReceive('getDatetimePrecision')
->andReturn($precision)
->getMock();
public function getBuilder()
{
return mock(PostgresBuilder::class);
}

/** @return list<array{method: string, type: string, user: int|null, grammar: false|int|null, expected: int|null}> */
Expand Down
14 changes: 12 additions & 2 deletions tests/Database/DatabaseSQLiteSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\SQLiteGrammar;
use Illuminate\Database\Schema\SQLiteBuilder;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use RuntimeException;
Expand Down Expand Up @@ -925,17 +926,26 @@ public function testCreateTableWithStoredAsColumn()
$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(SQLiteGrammar $grammar = null)
{
protected function getConnection(
?SQLiteGrammar $grammar = null,
?SQLiteBuilder $builder = null,
) {
$grammar ??= $this->getGrammar();
$builder ??= $this->getBuilder();

return m::mock(Connection::class)
->shouldReceive('getSchemaGrammar')->andReturn($grammar)
->shouldReceive('getSchemaBuilder')->andReturn($builder)
->getMock();
}

public function getGrammar()
{
return new SQLiteGrammar;
}

public function getBuilder()
{
return mock(SQLiteBuilder::class);
}
}
21 changes: 18 additions & 3 deletions tests/Database/DatabaseSchemaBlueprintTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
use Illuminate\Database\Schema\Grammars\PostgresGrammar;
use Illuminate\Database\Schema\Grammars\SQLiteGrammar;
use Illuminate\Database\Schema\Grammars\SqlServerGrammar;
use Illuminate\Database\Schema\MariaDbBuilder;
use Illuminate\Database\Schema\SqlServerBuilder;
use Illuminate\Database\Schema\SQLiteBuilder;
use Illuminate\Database\Schema\PostgresBuilder;
use Illuminate\Database\Schema\MySqlBuilder;
use Mockery as m;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -170,7 +175,7 @@ public function testNativeRenameColumnOnMysql57()
$connection = $this->getConnection(new MySqlGrammar);
$connection->shouldReceive('isMaria')->andReturn(false);
$connection->shouldReceive('getServerVersion')->andReturn('5.7');
$connection->shouldReceive('getSchemaBuilder->getColumns')->andReturn([
$connection->getSchemaBuilder()->shouldReceive('getColumns')->andReturn([
['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false, 'generation' => null],
['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true, 'generation' => null],
['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],
Expand All @@ -194,7 +199,7 @@ public function testNativeRenameColumnOnLegacyMariaDB()
$connection = $this->getConnection(new MariaDbGrammar);
$connection->shouldReceive('isMaria')->andReturn(true);
$connection->shouldReceive('getServerVersion')->andReturn('10.1.35');
$connection->shouldReceive('getSchemaBuilder->getColumns')->andReturn([
$connection->getSchemaBuilder()->shouldReceive('getColumns')->andReturn([
['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false, 'generation' => null],
['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true, 'generation' => null],
['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],
Expand Down Expand Up @@ -484,12 +489,22 @@ public function testTableComment()
$this->assertEquals(['comment on table "posts" is \'Look at my comment, it is amazing\''], $getSql(new PostgresGrammar));
}

protected function getConnection(Grammar $grammar = null)
protected function getConnection(?Grammar $grammar = null)
{
$grammar ??= new MySqlGrammar;

$builder = mock(match ($grammar::class) {
MySqlGrammar::class => MySqlBuilder::class,
PostgresGrammar::class => PostgresBuilder::class,
SQLiteGrammar::class => SQLiteBuilder::class,
SqlServerGrammar::class => SqlServerBuilder::class,
MariaDbGrammar::class => MariaDbBuilder::class,
default => Builder::class,
});

return m::mock(Connection::class)
->shouldReceive('getSchemaGrammar')->andReturn($grammar)
->shouldReceive('getSchemaBuilder')->andReturn($builder)
->getMock();
}

Expand Down
14 changes: 12 additions & 2 deletions tests/Database/DatabaseSqlServerSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;
use Illuminate\Database\Schema\Grammars\SqlServerGrammar;
use Illuminate\Database\Schema\SqlServerBuilder;
use Mockery as m;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -923,17 +924,26 @@ public function testDropDatabaseIfExists()
);
}

protected function getConnection(SqlServerGrammar $grammar = null)
{
protected function getConnection(
?SqlServerGrammar $grammar = null,
?SqlServerBuilder $builder = null
) {
$grammar ??= $this->getGrammar();
$builder ??= $this->getBuilder();

return m::mock(Connection::class)
->shouldReceive('getSchemaGrammar')->andReturn($grammar)
->shouldReceive('getSchemaBuilder')->andReturn($builder)
->getMock();
}

public function getGrammar()
{
return new SqlServerGrammar;
}

public function getBuilder()
{
return mock(SqlServerBuilder::class);
}
}

0 comments on commit 991aae2

Please sign in to comment.