diff --git a/config/blueprint.php b/config/blueprint.php index a533b8d8..c4256bf9 100644 --- a/config/blueprint.php +++ b/config/blueprint.php @@ -106,6 +106,21 @@ */ 'use_guarded' => false, + /* + |-------------------------------------------------------------------------- + | Default Data Types + |-------------------------------------------------------------------------- + | + | By default, Blueprint will set the primary key data type to `id` and the + | timestamps data type to `timestamp`. While you may customize these in + | your draft file, you may also configure your own defaults below. + | + */ + 'types' => [ + 'primary' => 'id', + 'timestamps' => 'timestamp', + ], + /* |-------------------------------------------------------------------------- | Singular route names diff --git a/src/Lexers/ModelLexer.php b/src/Lexers/ModelLexer.php index fadb2503..31927d9e 100644 --- a/src/Lexers/ModelLexer.php +++ b/src/Lexers/ModelLexer.php @@ -165,6 +165,10 @@ private function buildModel(string $name, array $columns): Model } elseif (isset($columns['timestampstz'])) { $model->enableTimestamps(true); unset($columns['timestampstz']); + } elseif (config('blueprint.types.timestamps') === false) { + $model->disableTimestamps(); + } else { + $model->enableTimestamps(strtolower(config('blueprint.types.timestamps', 'timestamp')) === 'timestamptz'); } if (isset($columns['softdeletes'])) { @@ -203,8 +207,12 @@ private function buildModel(string $name, array $columns): Model } if (!isset($columns['id']) && $model->usesPrimaryKey()) { - $column = $this->buildColumn('id', 'id'); - $model->addColumn($column); + if (config('blueprint.types.primary')) { + $column = $this->buildColumn('id', config('blueprint.types.primary', 'id')); + $model->addColumn($column); + } else { + $model->disablePrimaryKey(); + } } foreach ($columns as $name => $definition) { diff --git a/tests/Feature/Lexers/ModelLexerTest.php b/tests/Feature/Lexers/ModelLexerTest.php index e98e5f1a..0d0051e2 100644 --- a/tests/Feature/Lexers/ModelLexerTest.php +++ b/tests/Feature/Lexers/ModelLexerTest.php @@ -3,6 +3,7 @@ namespace Tests\Feature\Lexers; use Blueprint\Lexers\ModelLexer; +use Illuminate\Support\Arr; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use Tests\TestCase; @@ -124,6 +125,42 @@ public function it_defaults_the_id_column(): void $this->assertEquals(['nullable'], $columns['title']->modifiers()); } + #[Test] + public function it_defaults_the_id_column_based_on_configuration(): void + { + $type = Arr::random(['id', 'uuid', 'ulid']); + config(['blueprint.types.primary' => $type]); + + $tokens = [ + 'models' => [ + 'Model' => [ + 'title' => 'string nullable', + ], + ], + ]; + + $actual = $this->subject->analyze($tokens); + + $this->assertIsArray($actual['models']); + $this->assertCount(1, $actual['models']); + + $model = $actual['models']['Model']; + $this->assertEquals('Model', $model->name()); + $this->assertTrue($model->usesTimestamps()); + $this->assertFalse($model->usesSoftDeletes()); + + $columns = $model->columns(); + $this->assertCount(2, $columns); + $this->assertEquals('id', $columns['id']->name()); + $this->assertEquals($type, $columns['id']->dataType()); + $this->assertEquals([], $columns['id']->attributes()); + $this->assertEquals([], $columns['id']->modifiers()); + $this->assertEquals('title', $columns['title']->name()); + $this->assertEquals('string', $columns['title']->dataType()); + $this->assertEquals([], $columns['title']->attributes()); + $this->assertEquals(['nullable'], $columns['title']->modifiers()); + } + #[Test] public function it_disables_the_id_column(): void { @@ -147,6 +184,73 @@ public function it_disables_the_id_column(): void $this->assertFalse($model->usesPrimaryKey()); } + #[Test] + public function it_disables_the_id_column_based_on_configuration(): void + { + config(['blueprint.types.primary' => false]); + + $tokens = [ + 'models' => [ + 'Model' => [ + 'name' => 'string', + ], + ], + ]; + + $actual = $this->subject->analyze($tokens); + + $this->assertIsArray($actual['models']); + $this->assertCount(1, $actual['models']); + + $model = $actual['models']['Model']; + $this->assertEquals('Model', $model->name()); + $this->assertFalse($model->usesPrimaryKey()); + $this->assertCount(1, $model->columns()); + + $columns = $model->columns(); + $this->assertEquals('name', $columns['name']->name()); + $this->assertEquals('string', $columns['name']->dataType()); + $this->assertEquals([], $columns['name']->attributes()); + $this->assertEquals([], $columns['name']->modifiers()); + } + + #[Test] + public function it_sets_timestamps_data_type_based_on_configuration(): void + { + $type = Arr::random(['timestampTz', 'timestamptz']); + config(['blueprint.types.timestamps' => $type]); + + $tokens = [ + 'models' => [ + 'Model' => [ + 'name' => 'string', + ], + ], + ]; + + $actual = $this->subject->analyze($tokens); + + $this->assertIsArray($actual['models']); + $this->assertCount(1, $actual['models']); + + $model = $actual['models']['Model']; + $this->assertEquals('Model', $model->name()); + $this->assertTrue($model->usesTimestamps()); + $this->assertSame('timestampsTz', $model->timestampsDataType()); + $this->assertFalse($model->usesSoftDeletes()); + $this->assertCount(2, $model->columns()); + + $columns = $model->columns(); + $this->assertEquals('id', $columns['id']->name()); + $this->assertEquals('id', $columns['id']->dataType()); + $this->assertEquals([], $columns['id']->attributes()); + $this->assertEquals([], $columns['id']->modifiers()); + $this->assertEquals('name', $columns['name']->name()); + $this->assertEquals('string', $columns['name']->dataType()); + $this->assertEquals([], $columns['name']->attributes()); + $this->assertEquals([], $columns['name']->modifiers()); + } + #[Test] public function it_disables_timestamps(): void { @@ -169,6 +273,40 @@ public function it_disables_timestamps(): void $this->assertFalse($model->usesSoftDeletes()); } + #[Test] + public function it_disables_timestamps_based_on_configuration(): void + { + config(['blueprint.types.timestamps' => false]); + + $tokens = [ + 'models' => [ + 'Model' => [ + 'name' => 'string', + ], + ], + ]; + + $actual = $this->subject->analyze($tokens); + + $this->assertIsArray($actual['models']); + $this->assertCount(1, $actual['models']); + + $model = $actual['models']['Model']; + $this->assertEquals('Model', $model->name()); + $this->assertFalse($model->usesSoftDeletes()); + $this->assertCount(2, $model->columns()); + + $columns = $model->columns(); + $this->assertEquals('id', $columns['id']->name()); + $this->assertEquals('id', $columns['id']->dataType()); + $this->assertEquals([], $columns['id']->attributes()); + $this->assertEquals([], $columns['id']->modifiers()); + $this->assertEquals('name', $columns['name']->name()); + $this->assertEquals('string', $columns['name']->dataType()); + $this->assertEquals([], $columns['name']->attributes()); + $this->assertEquals([], $columns['name']->modifiers()); + } + #[Test] public function it_defaults_to_string_datatype(): void {