Skip to content

Commit 4364eed

Browse files
committed
feat: add more options to views
1 parent 0e8b0c7 commit 4364eed

13 files changed

+311
-47
lines changed

src/Grammars/Grammar.php

+25
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,29 @@ public function compileDrop(SqlEntity $entity): string
4141
abstract protected function compileViewCreate(View $entity): string;
4242

4343
abstract protected function compileViewDrop(View $entity): string;
44+
45+
/** @param list<string>|null $columns */
46+
protected function compileColumnsList(?array $columns): string
47+
{
48+
if ($columns === null) {
49+
return '';
50+
}
51+
52+
return ' (' . implode(', ', $columns) . ')';
53+
}
54+
55+
protected function compileCheckOption(string|true|null $option): string
56+
{
57+
if ($option === null) {
58+
return '';
59+
}
60+
61+
if ($option === true) {
62+
return 'WITH CHECK OPTION';
63+
}
64+
65+
$option = strtoupper($option);
66+
67+
return "WITH {$option} CHECK OPTION";
68+
}
4469
}

src/Grammars/MariaDbGrammar.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ class MariaDbGrammar extends Grammar
1212
#[Override]
1313
protected function compileViewCreate(View $entity): string
1414
{
15+
$columns = $this->compileColumnsList($entity->columns());
16+
$checkOption = $this->compileCheckOption($entity->checkOption());
17+
1518
return <<<SQL
16-
CREATE VIEW {$entity->name()} AS
17-
{$entity}
19+
CREATE VIEW {$entity->name()}{$columns} AS
20+
{$entity->toString()}
21+
{$checkOption}
1822
SQL;
1923
}
2024

src/Grammars/MySqlGrammar.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ class MySqlGrammar extends Grammar
1212
#[Override]
1313
protected function compileViewCreate(View $entity): string
1414
{
15+
$columns = $this->compileColumnsList($entity->columns());
16+
$checkOption = $this->compileCheckOption($entity->checkOption());
17+
1518
return <<<SQL
16-
CREATE VIEW {$entity->name()} AS
17-
{$entity}
19+
CREATE VIEW {$entity->name()}{$columns} AS
20+
{$entity->toString()}
21+
{$checkOption}
1822
SQL;
1923
}
2024

src/Grammars/PostgresGrammar.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ class PostgresGrammar extends Grammar
1212
#[Override]
1313
protected function compileViewCreate(View $entity): string
1414
{
15+
$checkOption = $this->compileCheckOption($entity->checkOption());
16+
$columns = $this->compileColumnsList($entity->columns());
17+
$recursive = $entity->isRecursive() ? ' RECURSIVE' : '';
18+
1519
return <<<SQL
16-
CREATE VIEW {$entity->name()} AS
17-
{$entity}
20+
CREATE{$recursive} VIEW {$entity->name()}{$columns} AS
21+
{$entity->toString()}
22+
{$checkOption}
1823
SQL;
1924
}
2025

src/Grammars/SQLiteGrammar.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ class SQLiteGrammar extends Grammar
1212
#[Override]
1313
protected function compileViewCreate(View $entity): string
1414
{
15+
$columns = $this->compileColumnsList($entity->columns());
16+
1517
return <<<SQL
16-
CREATE VIEW {$entity->name()} AS
17-
{$entity}
18+
CREATE VIEW {$entity->name()}{$columns} AS
19+
{$entity->toString()}
1820
SQL;
1921
}
2022

src/Grammars/SqlServerGrammar.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ class SqlServerGrammar extends Grammar
1212
#[Override]
1313
protected function compileViewCreate(View $entity): string
1414
{
15+
$checkOption = $this->compileCheckOption($entity->checkOption());
16+
$columns = $this->compileColumnsList($entity->columns());
17+
1518
return <<<SQL
16-
CREATE VIEW {$entity->name()} AS
17-
{$entity}
19+
CREATE VIEW {$entity->name()}{$columns} AS
20+
{$entity->toString()}
21+
{$checkOption}
1822
SQL;
1923
}
2024

src/View.php

+44-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,48 @@
99

1010
abstract class View implements SqlEntity
1111
{
12-
use Concerns\DefaultSqlEntityBehaviour;
12+
use DefaultSqlEntityBehaviour;
13+
14+
/**
15+
* The check option for the view.
16+
*
17+
* @var 'cascaded'|'local'|true|null
18+
*/
19+
protected string|true|null $checkOption = null;
20+
21+
/**
22+
* The explicit column list for the view.
23+
*
24+
* @var ?list<string>
25+
*/
26+
protected ?array $columns = null;
27+
28+
/** If the view is recursive. */
29+
protected bool $recursive = false;
30+
31+
/**
32+
* The check option for the view.
33+
*
34+
* @return 'cascaded'|'local'|true|null
35+
*/
36+
public function checkOption(): string|true|null
37+
{
38+
return $this->checkOption;
39+
}
40+
41+
/**
42+
* The explicit column list for the view.
43+
*
44+
* @return ?list<string>
45+
*/
46+
public function columns(): ?array
47+
{
48+
return $this->columns;
49+
}
50+
51+
/** If the view is recursive. */
52+
public function isRecursive(): bool
53+
{
54+
return $this->recursive;
55+
}
1356
}

tests/Unit/Grammars/MariaDbGrammarTest.php

+42-7
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,54 @@
1010
$connection = Mockery::mock(Connection::class);
1111

1212
test()->grammar = new MariaDbGrammar($connection);
13+
test()->entity = new UserView();
1314
});
1415

15-
it('compiles view drop', function () {
16-
$sql = test()->grammar->compileCreate(new UserView());
16+
describe('create', function () {
17+
it('compiles view create', function () {
18+
$sql = test()->grammar->compileCreate(test()->entity);
1719

18-
expect($sql)->toBe(<<<'SQL'
19-
CREATE VIEW user_view AS
20-
SELECT id, name FROM users
21-
SQL);
20+
expect($sql)->toBe(<<<'SQL'
21+
CREATE VIEW user_view AS
22+
SELECT id, name FROM users
23+
24+
SQL);
25+
});
26+
27+
it('compiles columns', function (array $columns, string $expected) {
28+
test()->entity->columns = $columns;
29+
30+
$sql = test()->grammar->compileCreate(test()->entity);
31+
32+
expect($sql)->toBe(<<<SQL
33+
CREATE VIEW user_view{$expected} AS
34+
SELECT id, name FROM users
35+
36+
SQL);
37+
})->with([
38+
'one column' => [['id'], ' (id)'],
39+
'two columns' => [['id', 'name'], ' (id, name)'],
40+
]);
41+
42+
it('compiles check option', function (string|bool $option, string $expected) {
43+
test()->entity->checkOption = $option;
44+
45+
$sql = test()->grammar->compileCreate(test()->entity);
46+
47+
expect($sql)->toBe(<<<SQL
48+
CREATE VIEW user_view AS
49+
SELECT id, name FROM users
50+
{$expected}
51+
SQL);
52+
})->with([
53+
'local' => ['local', 'WITH LOCAL CHECK OPTION'],
54+
'cascaded' => ['cascaded', 'WITH CASCADED CHECK OPTION'],
55+
'true' => [true, 'WITH CHECK OPTION'],
56+
]);
2257
});
2358

2459
it('compiles view create', function () {
25-
$sql = test()->grammar->compileDrop(new UserView());
60+
$sql = test()->grammar->compileDrop(test()->entity);
2661

2762
expect($sql)->toBe(<<<'SQL'
2863
DROP VIEW IF EXISTS user_view

tests/Unit/Grammars/MySqlGrammarTest.php

+42-7
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,54 @@
1010
$connection = Mockery::mock(Connection::class);
1111

1212
test()->grammar = new MySqlGrammar($connection);
13+
test()->entity = new UserView();
1314
});
1415

15-
it('compiles view drop', function () {
16-
$sql = test()->grammar->compileCreate(new UserView());
16+
describe('create', function () {
17+
it('compiles view create', function () {
18+
$sql = test()->grammar->compileCreate(test()->entity);
1719

18-
expect($sql)->toBe(<<<'SQL'
19-
CREATE VIEW user_view AS
20-
SELECT id, name FROM users
21-
SQL);
20+
expect($sql)->toBe(<<<'SQL'
21+
CREATE VIEW user_view AS
22+
SELECT id, name FROM users
23+
24+
SQL);
25+
});
26+
27+
it('compiles columns', function (array $columns, string $expected) {
28+
test()->entity->columns = $columns;
29+
30+
$sql = test()->grammar->compileCreate(test()->entity);
31+
32+
expect($sql)->toBe(<<<SQL
33+
CREATE VIEW user_view{$expected} AS
34+
SELECT id, name FROM users
35+
36+
SQL);
37+
})->with([
38+
'one column' => [['id'], ' (id)'],
39+
'two columns' => [['id', 'name'], ' (id, name)'],
40+
]);
41+
42+
it('compiles check option', function (string|bool $option, string $expected) {
43+
test()->entity->checkOption = $option;
44+
45+
$sql = test()->grammar->compileCreate(test()->entity);
46+
47+
expect($sql)->toBe(<<<SQL
48+
CREATE VIEW user_view AS
49+
SELECT id, name FROM users
50+
{$expected}
51+
SQL);
52+
})->with([
53+
'local' => ['local', 'WITH LOCAL CHECK OPTION'],
54+
'cascaded' => ['cascaded', 'WITH CASCADED CHECK OPTION'],
55+
'true' => [true, 'WITH CHECK OPTION'],
56+
]);
2257
});
2358

2459
it('compiles view create', function () {
25-
$sql = test()->grammar->compileDrop(new UserView());
60+
$sql = test()->grammar->compileDrop(test()->entity);
2661

2762
expect($sql)->toBe(<<<'SQL'
2863
DROP VIEW IF EXISTS user_view

tests/Unit/Grammars/PostgresGrammarTest.php

+54-7
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,66 @@
1010
$connection = Mockery::mock(Connection::class);
1111

1212
test()->grammar = new PostgresGrammar($connection);
13+
test()->entity = new UserView();
1314
});
1415

15-
it('compiles view create', function () {
16-
$sql = test()->grammar->compileCreate(new UserView());
16+
describe('create', function () {
17+
it('compiles view create', function () {
18+
$sql = test()->grammar->compileCreate(test()->entity);
1719

18-
expect($sql)->toBe(<<<'SQL'
19-
CREATE VIEW user_view AS
20-
SELECT id, name FROM users
21-
SQL);
20+
expect($sql)->toBe(<<<'SQL'
21+
CREATE VIEW user_view AS
22+
SELECT id, name FROM users
23+
24+
SQL);
25+
});
26+
27+
it('compiles recursive', function () {
28+
test()->entity->recursive = true;
29+
30+
$sql = test()->grammar->compileCreate(test()->entity);
31+
32+
expect($sql)->toBe(<<<SQL
33+
CREATE RECURSIVE VIEW user_view AS
34+
SELECT id, name FROM users
35+
36+
SQL);
37+
});
38+
39+
it('compiles columns', function (array $columns, string $expected) {
40+
test()->entity->columns = $columns;
41+
42+
$sql = test()->grammar->compileCreate(test()->entity);
43+
44+
expect($sql)->toBe(<<<SQL
45+
CREATE VIEW user_view{$expected} AS
46+
SELECT id, name FROM users
47+
48+
SQL);
49+
})->with([
50+
'one column' => [['id'], ' (id)'],
51+
'two columns' => [['id', 'name'], ' (id, name)'],
52+
]);
53+
54+
it('compiles check option', function (string|bool $option, string $expected) {
55+
test()->entity->checkOption = $option;
56+
57+
$sql = test()->grammar->compileCreate(test()->entity);
58+
59+
expect($sql)->toBe(<<<SQL
60+
CREATE VIEW user_view AS
61+
SELECT id, name FROM users
62+
{$expected}
63+
SQL);
64+
})->with([
65+
'local' => ['local', 'WITH LOCAL CHECK OPTION'],
66+
'cascaded' => ['cascaded', 'WITH CASCADED CHECK OPTION'],
67+
'true' => [true, 'WITH CHECK OPTION'],
68+
]);
2269
});
2370

2471
it('compiles view drop', function () {
25-
$sql = test()->grammar->compileDrop(new UserView());
72+
$sql = test()->grammar->compileDrop(test()->entity);
2673

2774
expect($sql)->toBe(<<<'SQL'
2875
DROP VIEW IF EXISTS user_view CASCADE

0 commit comments

Comments
 (0)