Skip to content

Commit 4450dab

Browse files
committed
idea from tempestphp#1972 integer in standard sql supports bigint (8 bytes), integer (4 bytes) and smallint (2 bytes). Tiny INT is SQL.
1 parent 46aea20 commit 4450dab

5 files changed

Lines changed: 105 additions & 8 deletions

File tree

packages/database/src/QueryStatements/CreateTableStatement.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,13 @@ public function char(string $name, bool $nullable = false, ?string $default = nu
199199
/**
200200
* Adds an `INTEGER` column to the table.
201201
*/
202-
public function integer(string $name, bool $unsigned = false, bool $nullable = false, ?int $default = null): self
202+
public function integer(string $name, bool $unsigned = false, bool $nullable = false, int $bytes = 4, ?int $default = null): self
203203
{
204204
$this->statements[] = new IntegerStatement(
205205
name: $name,
206206
unsigned: $unsigned,
207207
nullable: $nullable,
208+
bytes: $bytes,
208209
default: $default,
209210
);
210211

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Database\QueryStatements;
6+
7+
enum IntegerBytes: int
8+
{
9+
case SMALL = 2;
10+
case DEFAULT = 4;
11+
case BIG = 8;
12+
13+
public static function fromBytes(int $bytes): self
14+
{
15+
return match (true) {
16+
$bytes > self::DEFAULT->value => IntegerBytes::BIG,
17+
$bytes > self::SMALL->value => IntegerBytes::DEFAULT,
18+
DEFAULT => IntegerBytes::SMALL,
19+
};
20+
}
21+
22+
public function toString(): string
23+
{
24+
return match($this) {
25+
IntegerBytes::SMALL => 'SMALLINT',
26+
IntegerBytes::DEFAULT => 'INTEGER',
27+
IntegerBytes::BIG => 'BIGINT',
28+
};
29+
}
30+
}

packages/database/src/QueryStatements/IntegerStatement.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,28 @@ public function __construct(
1313
private string $name,
1414
private bool $unsigned = false,
1515
private bool $nullable = false,
16+
private int $bytes = 4,
1617
private ?int $default = null,
1718
) {}
1819

1920
public function compile(DatabaseDialect $dialect): string
2021
{
21-
return sprintf(
22-
'`%s` INTEGER %s %s %s',
23-
$this->name,
24-
$this->unsigned ? 'UNSIGNED' : '',
25-
$this->default !== null ? "DEFAULT {$this->default}" : '',
26-
$this->nullable ? '' : 'NOT NULL',
27-
);
22+
return match($dialect) {
23+
DatabaseDialect::SQLITE => sprintf(
24+
'`%s` INTEGER %s %s %s',
25+
$this->name,
26+
$this->unsigned ? 'UNSIGNED' : '',
27+
$this->default !== null ? "DEFAULT {$this->default}" : '',
28+
$this->nullable ? '' : 'NOT NULL',
29+
),
30+
DEFAULT => sprintf(
31+
'`%s` %s %s %s %s',
32+
$this->name,
33+
IntegerBytes::fromBytes($this->bytes)->toString(),
34+
$this->unsigned ? 'UNSIGNED' : '',
35+
$this->default !== null ? "DEFAULT {$this->default}" : '',
36+
$this->nullable ? '' : 'NOT NULL',
37+
)
38+
};
2839
}
2940
}

packages/database/tests/QueryStatements/CreateTableStatementTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
*/
1919
final class CreateTableStatementTest extends TestCase
2020
{
21+
public function test_integer_table_database_dialect(): void
22+
{
23+
24+
}
2125
#[DataProvider('provide_create_table_database_dialects')]
2226
public function test_create_a_table(DatabaseDialect $dialect, string $validSql): void
2327
{

tests/Integration/Database/QueryStatements/CreateTableStatementTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,57 @@ public function test_object_method_produces_same_sql_as_json_and_dto(): void
287287
$this->assertSame($jsonStatement, $objectStatement);
288288
$this->assertSame($dtoStatement, $objectStatement);
289289
}
290+
291+
public function test_integer_field_with_bytes_mysql(): void
292+
{
293+
$bigInteger = new CreateTableStatement('test-table')
294+
->integer('content', false, false, 6)
295+
->compile(dialect: DatabaseDialect::MYSQL);
296+
$defaultInteger = new CreateTableStatement('test-table')
297+
->integer('content', false, false, 3)
298+
->compile(dialect: DatabaseDialect::MYSQL);
299+
$smallInteger = new CreateTableStatement('test-table')
300+
->integer('content', false, false, 2)
301+
->compile(dialect: DatabaseDialect::MYSQL);
302+
303+
$this->assertStringContainsString('BIGINT', $bigInteger);
304+
$this->assertStringContainsString('INTEGER', $defaultInteger);
305+
$this->assertStringContainsString('SMALL', $smallInteger);
306+
}
307+
308+
public function test_integer_field_with_bytes_postgresql(): void
309+
{
310+
$bigInteger = new CreateTableStatement('test-table')
311+
->integer('content', false, false, 6)
312+
->compile(dialect: DatabaseDialect::POSTGRESQL);
313+
$defaultInteger = new CreateTableStatement('test-table')
314+
->integer('content', false, false, 3)
315+
->compile(dialect: DatabaseDialect::POSTGRESQL);
316+
$smallInteger = new CreateTableStatement('test-table')
317+
->integer('content', false, false, 2)
318+
->compile(dialect: DatabaseDialect::POSTGRESQL);
319+
320+
$this->assertStringContainsString('BIGINT', $bigInteger);
321+
$this->assertStringContainsString('INTEGER', $defaultInteger);
322+
$this->assertStringContainsString('SMALL', $smallInteger);
323+
}
324+
325+
public function test_integer_field_with_bytes_sqlite(): void
326+
{
327+
$bigInteger = new CreateTableStatement('test-table')
328+
->integer('content', false, false, 6)
329+
->compile(dialect: DatabaseDialect::SQLITE);
330+
$defaultInteger = new CreateTableStatement('test-table')
331+
->integer('content', false, false, 3)
332+
->compile(dialect: DatabaseDialect::SQLITE);
333+
$smallInteger = new CreateTableStatement('test-table')
334+
->integer('content', false, false, 2)
335+
->compile(dialect: DatabaseDialect::SQLITE);
336+
337+
$this->assertStringContainsString('INTEGER', $bigInteger);
338+
$this->assertStringContainsString('INTEGER', $defaultInteger);
339+
$this->assertStringContainsString('INTEGER', $smallInteger);
340+
}
290341
}
291342

292343
enum CreateTableStatementTestEnumForCreateTable: string

0 commit comments

Comments
 (0)