Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  specify next release
  add unique constraint
  fix values collision
  • Loading branch information
Baptouuuu committed Feb 10, 2024
2 parents 8ee1464 + ac9a77b commit 068dc8e
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 2.15.0 - 2024-02-10

### Added

- `Formal\AccessLayer\Query\CreateTable::unique()`
- `Formal\AccessLayer\Query\Constraint\Unique`

## 2.14.0 - 2024-02-10

### Added
Expand Down
44 changes: 44 additions & 0 deletions proofs/connection/pdo.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,50 @@ static function($assert) use ($connection) {
},
);

yield proof(
'Unique constraint',
given(Set\Integers::between(0, 1_000_000)),
static function($assert, $int) use ($connection) {
$table = Table\Name::of('test_unique');
$connection(CreateTable::ifNotExists(
$table,
Column::of(
Column\Name::of('id'),
Column\Type::int(),
),
Column::of(
Column\Name::of('other'),
Column\Type::varchar(3),
),
)->unique(Column\Name::of('id'), Column\Name::of('other')));

$connection(Insert::into(
$table,
Row::of([
'id' => $int,
'other' => 'foo',
]),
));
$connection(Insert::into(
$table,
Row::of([
'id' => $int,
'other' => 'bar',
]),
));

$assert->throws(fn() => $connection(Insert::into(
$table,
Row::of([
'id' => $int,
'other' => 'foo',
]),
)));

$connection(DropTable::named($table));
},
);

yield properties(
'PDO properties',
Properties::any(),
Expand Down
12 changes: 6 additions & 6 deletions properties/Connection/SelectWhereInQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ public function __construct(
string $uuid2,
string $username,
int $number,
string $value1,
string $value2,
array $values,
) {
$this->uuid1 = $uuid1;
$this->uuid2 = $uuid2;
$this->username = $username;
$this->number = $number;
$this->value1 = $value1;
$this->value2 = $value2;
[$this->value1, $this->value2] = $values;
}

public static function any(): Set
Expand All @@ -58,8 +56,10 @@ public static function any(): Set
Set\Uuid::any(),
Set\Strings::madeOf(Set\Chars::ascii())->between(0, 255),
Set\Integers::any(),
Set\Strings::madeOf(Set\Chars::ascii())->between(0, 255),
Set\Strings::madeOf(Set\Chars::ascii())->between(0, 255),
Set\MutuallyExclusive::of(
Set\Strings::madeOf(Set\Chars::ascii())->between(0, 255),
Set\Strings::madeOf(Set\Chars::ascii())->between(0, 255),
),
);
}

Expand Down
94 changes: 94 additions & 0 deletions src/Query/Constraint/Unique.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
declare(strict_types = 1);

namespace Formal\AccessLayer\Query\Constraint;

use Formal\AccessLayer\Table\{
Name,
Column,
};
use Innmind\Immutable\{
Maybe,
Sequence,
Str,
Monoid\Concat,
};

/**
* @psalm-immutable
*/
final class Unique
{
private Column\Name $column;
/** @var Sequence<Column\Name> */
private Sequence $columns;
/** @var Maybe<non-empty-string> */
private Maybe $name;

/**
* @param Sequence<Column\Name> $columns
* @param Maybe<non-empty-string> $name
*/
private function __construct(
Column\Name $column,
Sequence $columns,
Maybe $name,
) {
$this->column = $column;
$this->columns = $columns;
$this->name = $name;
}

/**
* @psalm-pure
* @no-named-arguments
*/
public static function of(
Column\Name $column,
Column\Name ...$columns,
): self {
/** @var Maybe<non-empty-string> */
$name = Maybe::nothing();

return new self($column, Sequence::of(...$columns), $name);
}

/**
* @param non-empty-string $name
*/
public function named(string $name): self
{
return new self(
$this->column,
$this->columns,
Maybe::just($name),
);
}

/**
* @return non-empty-string
*/
public function sql(): string
{
$columns = $this
->columns
->map(static fn($column) => ', '.$column->sql())
->map(Str::of(...))
->fold(new Concat)
->toString();

return $this->name->match(
fn($name) => \sprintf(
'CONSTRAINT UC_%s UNIQUE (%s%s)',
$name,
$this->column->sql(),
$columns,
),
fn() => \sprintf(
'UNIQUE (%s%s)',
$this->column->sql(),
$columns,
),
);
}
}
15 changes: 12 additions & 3 deletions src/Query/CreateTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Query,
Query\Constraint\PrimaryKey,
Query\Constraint\ForeignKey,
Query\Constraint\Unique,
Table\Name,
Table\Column,
};
Expand All @@ -23,13 +24,13 @@ final class CreateTable implements Query
private Name $name;
/** @var Sequence<Column> */
private Sequence $columns;
/** @var Sequence<PrimaryKey|ForeignKey> */
/** @var Sequence<PrimaryKey|ForeignKey|Unique> */
private Sequence $constraints;
private bool $ifNotExists;

/**
* @param Sequence<Column> $columns
* @param Sequence<PrimaryKey|ForeignKey> $constraints
* @param Sequence<PrimaryKey|ForeignKey|Unique> $constraints
*/
private function __construct(
bool $ifNotExists,
Expand Down Expand Up @@ -81,7 +82,15 @@ public function foreignKey(Column\Name $column, Name $target, Column\Name $refer
return $this->constraint(ForeignKey::of($column, $target, $reference));
}

public function constraint(PrimaryKey|ForeignKey $constraint): self
/**
* @no-named-arguments
*/
public function unique(Column\Name $column, Column\Name ...$columns): self
{
return $this->constraint(Unique::of($column, ...$columns));
}

public function constraint(PrimaryKey|ForeignKey|Unique $constraint): self
{
return new self(
$this->ifNotExists,
Expand Down

0 comments on commit 068dc8e

Please sign in to comment.