Skip to content
Merged
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
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1983,9 +1983,9 @@ $result = $schema->table('users')
->createIfNotExists();
```

Available column types: `id`, `uuid`, `string`, `text`, `mediumText`, `longText`, `tinyInteger`, `smallInteger`, `integer`, `bigInteger`, `serial`, `bigSerial`, `smallSerial`, `float`, `decimal`, `boolean`, `datetime`, `timestamp`, `json`, `binary`, `enum`, `point`, `linestring`, `polygon`, `vector` (PostgreSQL, ClickHouse, MongoDB), `timestamps`.
Available column types: `id`, `uuid`, `string`, `text`, `mediumText`, `longText`, `tinyInteger`, `smallInteger`, `integer`, `bigInteger`, `serial`, `bigSerial`, `smallSerial`, `float`, `decimal`, `boolean`, `datetime`, `timestamp`, `json`, `binary`, `enum`, `point`, `linestring`, `polygon`, `vector` (PostgreSQL, ClickHouse, MongoDB — only PostgreSQL takes a `$dimensions` argument), `timestamps`.

Column modifiers available on every dialect: `nullable()`, `default($value)`, `defaultRaw($expression)`, `primary()`, `unsigned()`, `autoIncrement()`, `srid($srid)` (spatial columns), `dimensions($dimensions)` (vector columns).
Column modifiers available on every dialect: `nullable()`, `default($value)`, `defaultRaw($expression)`, `primary()`, `unsigned()`.

The rest are only on the dialects that emit them, so an unsupported combination is a type error rather than something silently dropped:

Expand All @@ -2000,10 +2000,15 @@ The rest are only on the dialects that emit them, so an unsupported combination
| `comment($text)` | MySQL, MariaDB, SQLite, ClickHouse, MongoDB | PostgreSQL needs a separate statement — use `commentOnColumn()` |
| `ttl($expression)` | ClickHouse | — |
| `userType($name)` | PostgreSQL | — |
| `srid($srid)` | MySQL, MariaDB, PostgreSQL | SQLite stores geometry as `TEXT`, ClickHouse as a `Tuple`, MongoDB as an object — none carry an SRID |
| `dimensions($dimensions)` | PostgreSQL | ClickHouse's `Array(Float64)` and MongoDB's array bsonType are unsized |
| `autoIncrement()` | MySQL, MariaDB, PostgreSQL, SQLite | ClickHouse has none; MongoDB assigns `_id` itself |

Likewise `serial()` / `bigSerial()` / `smallSerial()` are absent from the ClickHouse table, and `dropColumn()` / `renameColumn()` are absent from the MongoDB table.

> **Known gaps.** `unsigned()` is accepted everywhere but renders nothing on PostgreSQL and SQLite, which have no unsigned integer types — you get a signed column. `srid()`, `autoIncrement()` and the `$dimensions` argument to `vector()` are likewise accepted on dialects that cannot express them, because the library's own column factories set them internally. Treat those four as advisory rather than guaranteed.
The column factories still work everywhere: `point($name, $srid)`, `id()` and `serial()` set the SRID and auto-increment flag intrinsically, so portable schema code is unaffected — only the standalone modifiers are scoped. `Table\ClickHouse::vector()` and `Table\MongoDB::vector()` take no `$dimensions` argument, since neither type records one.

> **Known gap.** `unsigned()` is accepted everywhere but renders nothing on PostgreSQL and SQLite, which have no unsigned integer types — you get a signed column. This one is a deliberate dialect mapping via an overridable `compileUnsigned()` hook, not an oversight.

**Raw default expressions** — use `defaultRaw($expression)` for dialect-specific server-generated defaults that `default()` would otherwise quote as a string literal (`now()`, `CURRENT_TIMESTAMP`, `gen_random_uuid()`, `generateUUIDv4()`, `UUID()`, …). The expression is emitted verbatim and must come from a trusted source; it must not be empty or contain a semicolon. Takes precedence over `default()` when both are set.

Expand Down
33 changes: 12 additions & 21 deletions src/Query/Schema/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ class Column
public protected(set) ?string $userTypeName = null;

/**
* $srid, $dimensions and $autoIncrement are intrinsic to the column the way
* $length is, and are set by the Table factories that create it (point(),
* vector(), id(), serial()). They are constructor parameters rather than
* modifier calls so that the factories do not depend on modifier methods
* that only some dialects expose.
*
* @param TTable $table
*/
public function __construct(
Expand All @@ -71,7 +77,13 @@ public function __construct(
public ?int $length = null,
public ?int $precision = null,
public ?int $scale = null,
?int $srid = null,
?int $dimensions = null,
bool $autoIncrement = false,
Comment thread
abnegate marked this conversation as resolved.
) {
$this->srid = $srid;
$this->dimensions = $dimensions;
$this->isAutoIncrement = $autoIncrement;
}

public function nullable(): static
Expand Down Expand Up @@ -135,13 +147,6 @@ public function primary(): static|Table
return $this;
}

public function autoIncrement(): static
{
$this->isAutoIncrement = true;

return $this;
}

/**
* Set the allowed values on this enum column (when called with one array
* argument), or add a new enum column to the parent table (when called
Expand All @@ -167,20 +172,6 @@ public function enum(string|array $nameOrValues, ?array $values = null): static|
return $this->table->enum($nameOrValues, $values ?? []);
}

public function srid(int $srid): static
{
$this->srid = $srid;

return $this;
}

public function dimensions(int $dimensions): static
{
$this->dimensions = $dimensions;

return $this;
}

public function modify(): static
{
$this->isModify = true;
Expand Down
2 changes: 2 additions & 0 deletions src/Query/Schema/Column/MySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*/
class MySQL extends Column
{
use Trait\Srid;
use Trait\AutoIncrement;
use Trait\Collation;
use Trait\Positioning;
use Trait\Comment;
Expand Down
3 changes: 3 additions & 0 deletions src/Query/Schema/Column/PostgreSQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
*/
class PostgreSQL extends Column
{
use Trait\Srid;
use Trait\Dimensions;
use Trait\AutoIncrement;
use Trait\Collation;
use Trait\Unique;
use Trait\Generated;
Expand Down
1 change: 1 addition & 0 deletions src/Query/Schema/Column/SQLite.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
class SQLite extends Column
{
use Trait\AutoIncrement;
use Trait\Collation;
use Trait\Comment;
use Trait\Unique;
Expand Down
17 changes: 17 additions & 0 deletions src/Query/Schema/Column/Trait/AutoIncrement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Utopia\Query\Schema\Column\Trait;

/**
* Marking a column as server-incremented. ClickHouse has no auto-increment and
* MongoDB assigns _id itself, so neither emits anything for it.
*/
trait AutoIncrement
{
public function autoIncrement(): static
{
$this->isAutoIncrement = true;

return $this;
}
}
18 changes: 18 additions & 0 deletions src/Query/Schema/Column/Trait/Dimensions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Utopia\Query\Schema\Column\Trait;

/**
* Overriding the declared width of a vector column. PostgreSQL emits
* VECTOR(n); ClickHouse's Array(Float64) and MongoDB's array bsonType are
* unsized, so neither exposes this.
*/
trait Dimensions
{
public function dimensions(int $dimensions): static
{
$this->dimensions = $dimensions;

return $this;
}
}
21 changes: 21 additions & 0 deletions src/Query/Schema/Column/Trait/Srid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Utopia\Query\Schema\Column\Trait;

/**
* Overriding the spatial reference system of a geometry column.
*
* Only MySQL, MariaDB and PostgreSQL encode an SRID in the column type. SQLite
* stores geometry as TEXT, ClickHouse as a Tuple and MongoDB as an object, none
* of which carry one -- the factories still accept an $srid there so portable
* code keeps working, but nothing is emitted, so the modifier is absent.
*/
trait Srid
{
public function srid(int $srid): static
{
$this->srid = $srid;

return $this;
}
}
4 changes: 2 additions & 2 deletions src/Query/Schema/Forwarder/ClickHouse.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
*/
trait ClickHouse
{
public function vector(string $name, int $dimensions): Column\ClickHouse
public function vector(string $name): Column\ClickHouse
{
return $this->table->vector($name, $dimensions);
return $this->table->vector($name);
}

public function fixedString(string $name, int $length): Column\ClickHouse
Expand Down
4 changes: 2 additions & 2 deletions src/Query/Schema/Forwarder/MongoDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
*/
trait MongoDB
{
public function vector(string $name, int $dimensions): Column\MongoDB
public function vector(string $name): Column\MongoDB
{
return $this->table->vector($name, $dimensions);
return $this->table->vector($name);
}
public function serial(string $name): Column\MongoDB
{
Expand Down
16 changes: 6 additions & 10 deletions src/Query/Schema/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ private function requireSchema(): Schema
*
* @return TColumn
*/
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null): Column
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null, ?int $srid = null, ?int $dimensions = null, bool $autoIncrement = false): Column
{
/** @var TColumn */
return new Column($this, $name, $type, $length, $precision, $scale);
return new Column($this, $name, $type, $length, $precision, $scale, $srid, $dimensions, $autoIncrement);
}

/**
Expand All @@ -141,9 +141,8 @@ protected function newForeignKey(string $column): ForeignKey
/** @return TColumn */
public function id(string $name = 'id'): Column
{
$col = $this->newColumn($name, ColumnType::BigInteger);
$col = $this->newColumn($name, ColumnType::BigInteger, autoIncrement: true);
$col->unsigned();
$col->autoIncrement();
$col->primary();
$this->columns[] = $col;

Expand Down Expand Up @@ -348,8 +347,7 @@ public function enum(string $name, array $values): Column
/** @return TColumn */
public function point(string $name, int $srid = 4326): Column
{
$col = $this->newColumn($name, ColumnType::Point);
$col->srid($srid);
$col = $this->newColumn($name, ColumnType::Point, srid: $srid);
$this->columns[] = $col;

return $col;
Expand All @@ -358,8 +356,7 @@ public function point(string $name, int $srid = 4326): Column
/** @return TColumn */
public function linestring(string $name, int $srid = 4326): Column
{
$col = $this->newColumn($name, ColumnType::Linestring);
$col->srid($srid);
$col = $this->newColumn($name, ColumnType::Linestring, srid: $srid);
$this->columns[] = $col;

return $col;
Expand All @@ -368,8 +365,7 @@ public function linestring(string $name, int $srid = 4326): Column
/** @return TColumn */
public function polygon(string $name, int $srid = 4326): Column
{
$col = $this->newColumn($name, ColumnType::Polygon);
$col->srid($srid);
$col = $this->newColumn($name, ColumnType::Polygon, srid: $srid);
$this->columns[] = $col;

return $col;
Expand Down
7 changes: 3 additions & 4 deletions src/Query/Schema/Table/ClickHouse.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ class ClickHouse extends Table
public protected(set) ?string $orderByRaw = null;

#[\Override]
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null): Column\ClickHouse
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null, ?int $srid = null, ?int $dimensions = null, bool $autoIncrement = false): Column\ClickHouse
{
return new Column\ClickHouse($this, $name, $type, $length, $precision, $scale);
return new Column\ClickHouse($this, $name, $type, $length, $precision, $scale, $srid, $dimensions, $autoIncrement);
}

public function vector(string $name, int $dimensions): Column\ClickHouse
public function vector(string $name): Column\ClickHouse
{
$col = $this->newColumn($name, ColumnType::Vector);
$col->dimensions($dimensions);
$this->columns[] = $col;

return $col;
Expand Down
7 changes: 3 additions & 4 deletions src/Query/Schema/Table/MongoDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ class MongoDB extends Table
/** @use Trait\Serial<Column\MongoDB> */
use Trait\Serial;
#[\Override]
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null): Column\MongoDB
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null, ?int $srid = null, ?int $dimensions = null, bool $autoIncrement = false): Column\MongoDB
{
return new Column\MongoDB($this, $name, $type, $length, $precision, $scale);
return new Column\MongoDB($this, $name, $type, $length, $precision, $scale, $srid, $dimensions, $autoIncrement);
}

public function vector(string $name, int $dimensions): Column\MongoDB
public function vector(string $name): Column\MongoDB
{
$col = $this->newColumn($name, ColumnType::Vector);
$col->dimensions($dimensions);
$this->columns[] = $col;

return $col;
Expand Down
4 changes: 2 additions & 2 deletions src/Query/Schema/Table/MySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class MySQL extends Table
use Trait\StandardPartitioning;

#[\Override]
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null): Column\MySQL
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null, ?int $srid = null, ?int $dimensions = null, bool $autoIncrement = false): Column\MySQL
{
return new Column\MySQL($this, $name, $type, $length, $precision, $scale);
return new Column\MySQL($this, $name, $type, $length, $precision, $scale, $srid, $dimensions, $autoIncrement);
}

#[\Override]
Expand Down
7 changes: 3 additions & 4 deletions src/Query/Schema/Table/PostgreSQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class PostgreSQL extends Table
use Trait\StandardPartitioning;

#[\Override]
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null): Column\PostgreSQL
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null, ?int $srid = null, ?int $dimensions = null, bool $autoIncrement = false): Column\PostgreSQL
{
return new Column\PostgreSQL($this, $name, $type, $length, $precision, $scale);
return new Column\PostgreSQL($this, $name, $type, $length, $precision, $scale, $srid, $dimensions, $autoIncrement);
}

#[\Override]
Expand All @@ -36,8 +36,7 @@ protected function newForeignKey(string $column): ForeignKey\PostgreSQL

public function vector(string $name, int $dimensions): Column\PostgreSQL
{
$col = $this->newColumn($name, ColumnType::Vector);
$col->dimensions($dimensions);
$col = $this->newColumn($name, ColumnType::Vector, dimensions: $dimensions);
$this->columns[] = $col;

return $col;
Expand Down
4 changes: 2 additions & 2 deletions src/Query/Schema/Table/SQLite.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class SQLite extends Table
use Trait\InlineForeignKey;

#[\Override]
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null): Column\SQLite
protected function newColumn(string $name, ColumnType $type, ?int $length = null, ?int $precision = null, ?int $scale = null, ?int $srid = null, ?int $dimensions = null, bool $autoIncrement = false): Column\SQLite
{
return new Column\SQLite($this, $name, $type, $length, $precision, $scale);
return new Column\SQLite($this, $name, $type, $length, $precision, $scale, $srid, $dimensions, $autoIncrement);
}

#[\Override]
Expand Down
9 changes: 3 additions & 6 deletions src/Query/Schema/Table/Trait/Serial.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ trait Serial
*/
public function serial(string $name): Column
{
$col = $this->newColumn($name, ColumnType::Serial);
$col->autoIncrement();
$col = $this->newColumn($name, ColumnType::Serial, autoIncrement: true);
$this->columns[] = $col;

return $col;
Expand All @@ -41,8 +40,7 @@ public function serial(string $name): Column
*/
public function bigSerial(string $name): Column
{
$col = $this->newColumn($name, ColumnType::BigSerial);
$col->autoIncrement();
$col = $this->newColumn($name, ColumnType::BigSerial, autoIncrement: true);
$this->columns[] = $col;

return $col;
Expand All @@ -57,8 +55,7 @@ public function bigSerial(string $name): Column
*/
public function smallSerial(string $name): Column
{
$col = $this->newColumn($name, ColumnType::SmallSerial);
$col->autoIncrement();
$col = $this->newColumn($name, ColumnType::SmallSerial, autoIncrement: true);
$this->columns[] = $col;

return $col;
Expand Down
Loading
Loading