Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,13 @@ public function char(string $name, bool $nullable = false, ?string $default = nu
/**
* Adds an `INTEGER` column to the table.
*/
public function integer(string $name, bool $unsigned = false, bool $nullable = false, ?int $default = null): self
public function integer(string $name, bool $unsigned = false, bool $nullable = false, int $bytes = 4, ?int $default = null): self
{
$this->statements[] = new IntegerStatement(
name: $name,
unsigned: $unsigned,
nullable: $nullable,
bytes: $bytes,
default: $default,
);

Expand Down
30 changes: 30 additions & 0 deletions packages/database/src/QueryStatements/IntegerBytes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Tempest\Database\QueryStatements;

enum IntegerBytes: int
{
case SMALL = 2;
case DEFAULT = 4;
case BIG = 8;

public static function fromBytes(int $bytes): self
{
return match (true) {
$bytes > self::DEFAULT->value => self::BIG,
$bytes > self::SMALL->value => self::DEFAULT,
DEFAULT => self::SMALL,
};
}

public function toString(): string
{
return match($this) {
self::SMALL => 'SMALLINT',
self::DEFAULT => 'INTEGER',
self::BIG => 'BIGINT',
};
}
}
25 changes: 18 additions & 7 deletions packages/database/src/QueryStatements/IntegerStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,28 @@ public function __construct(
private string $name,
private bool $unsigned = false,
private bool $nullable = false,
private int $bytes = 4,
private ?int $default = null,
) {}

public function compile(DatabaseDialect $dialect): string
{
return sprintf(
'`%s` INTEGER %s %s %s',
$this->name,
$this->unsigned ? 'UNSIGNED' : '',
$this->default !== null ? "DEFAULT {$this->default}" : '',
$this->nullable ? '' : 'NOT NULL',
);
return match($dialect) {
DatabaseDialect::SQLITE => sprintf(
'`%s` INTEGER %s %s %s',
$this->name,
$this->unsigned ? 'UNSIGNED' : '',
$this->default !== null ? "DEFAULT {$this->default}" : '',
$this->nullable ? '' : 'NOT NULL',
),
DEFAULT => sprintf(
'`%s` %s %s %s %s',
$this->name,
IntegerBytes::fromBytes($this->bytes)->toString(),
$this->unsigned ? 'UNSIGNED' : '',
$this->default !== null ? "DEFAULT {$this->default}" : '',
$this->nullable ? '' : 'NOT NULL',
)
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
*/
final class CreateTableStatementTest extends TestCase
{
public function test_integer_table_database_dialect(): void
{

}
#[DataProvider('provide_create_table_database_dialects')]
public function test_create_a_table(DatabaseDialect $dialect, string $validSql): void
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,57 @@ public function test_object_method_produces_same_sql_as_json_and_dto(): void
$this->assertSame($jsonStatement, $objectStatement);
$this->assertSame($dtoStatement, $objectStatement);
}

public function test_integer_field_with_bytes_mysql(): void
{
$bigInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 6)
->compile(dialect: DatabaseDialect::MYSQL);
$defaultInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 3)
->compile(dialect: DatabaseDialect::MYSQL);
$smallInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 2)
->compile(dialect: DatabaseDialect::MYSQL);

$this->assertStringContainsString('BIGINT', $bigInteger);
$this->assertStringContainsString('INTEGER', $defaultInteger);
$this->assertStringContainsString('SMALL', $smallInteger);
}

public function test_integer_field_with_bytes_postgresql(): void
{
$bigInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 6)
->compile(dialect: DatabaseDialect::POSTGRESQL);
$defaultInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 3)
->compile(dialect: DatabaseDialect::POSTGRESQL);
$smallInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 2)
->compile(dialect: DatabaseDialect::POSTGRESQL);

$this->assertStringContainsString('BIGINT', $bigInteger);
$this->assertStringContainsString('INTEGER', $defaultInteger);
$this->assertStringContainsString('SMALL', $smallInteger);
}

public function test_integer_field_with_bytes_sqlite(): void
{
$bigInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 6)
->compile(dialect: DatabaseDialect::SQLITE);
$defaultInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 3)
->compile(dialect: DatabaseDialect::SQLITE);
$smallInteger = new CreateTableStatement('test-table')
->integer('content', false, false, 2)
->compile(dialect: DatabaseDialect::SQLITE);

$this->assertStringContainsString('INTEGER', $bigInteger);
$this->assertStringContainsString('INTEGER', $defaultInteger);
$this->assertStringContainsString('INTEGER', $smallInteger);
}
}

enum CreateTableStatementTestEnumForCreateTable: string
Expand Down