Skip to content

Commit d278227

Browse files
committed
feat: add triggers
1 parent 778a082 commit d278227

16 files changed

+500
-5
lines changed

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,41 @@ class Add extends Function_
300300

301301
<!-- #### 📤 Procedure -->
302302
<!---->
303-
<!-- #### ⚡ Trigger -->
304-
<!---->
303+
304+
#### ⚡ Trigger
305+
306+
The `Trigger` class is used to create triggers in the database.
307+
In addition to the options above, you can use the following options to further customize the trigger:
308+
309+
```php
310+
<?php
311+
312+
namespace Database\Entities\Triggers;
313+
314+
use CalebDW\SqlEntities\Trigger;
315+
316+
class AccountAuditTrigger extends Trigger
317+
{
318+
// if the trigger is a constraint trigger
319+
// PostgreSQL only
320+
protected bool $constraint = false;
321+
322+
protected string $timing = 'AFTER';
323+
324+
protected array $events = ['UPDATE'];
325+
326+
protected string $table = 'accounts';
327+
328+
#[Override]
329+
public function definition(): string
330+
{
331+
return $this->definition ?? <<<'SQL'
332+
EXECUTE FUNCTION record_account_audit();
333+
SQL;
334+
}
335+
}
336+
```
337+
305338
<!-- #### 🔢 Sequence -->
306339
<!---->
307340
<!-- #### 🧳 Domain -->

src/Grammars/Grammar.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use CalebDW\SqlEntities\Contracts\SqlEntity;
88
use CalebDW\SqlEntities\Function_;
9+
use CalebDW\SqlEntities\Trigger;
910
use CalebDW\SqlEntities\View;
1011
use Illuminate\Database\Connection;
1112
use Illuminate\Support\Str;
@@ -23,6 +24,7 @@ public function compileCreate(SqlEntity $entity): string
2324
{
2425
$statement = match (true) {
2526
$entity instanceof Function_ => $this->compileFunctionCreate($entity),
27+
$entity instanceof Trigger => $this->compileTriggerCreate($entity),
2628
$entity instanceof View => $this->compileViewCreate($entity),
2729

2830
default => throw new InvalidArgumentException(
@@ -38,6 +40,7 @@ public function compileDrop(SqlEntity $entity): string
3840
{
3941
$statement = match (true) {
4042
$entity instanceof Function_ => $this->compileFunctionDrop($entity),
43+
$entity instanceof Trigger => $this->compileTriggerDrop($entity),
4144
$entity instanceof View => $this->compileViewDrop($entity),
4245

4346
default => throw new InvalidArgumentException(
@@ -53,6 +56,7 @@ public function supportsEntity(SqlEntity $entity): bool
5356
{
5457
return match (true) {
5558
$entity instanceof Function_ => true,
59+
$entity instanceof Trigger => true,
5660
$entity instanceof View => true,
5761
default => false,
5862
};
@@ -67,6 +71,15 @@ protected function compileFunctionDrop(Function_ $entity): string
6771
SQL;
6872
}
6973

74+
abstract protected function compileTriggerCreate(Trigger $entity): string;
75+
76+
protected function compileTriggerDrop(Trigger $entity): string
77+
{
78+
return <<<SQL
79+
DROP TRIGGER IF EXISTS {$entity->name()}
80+
SQL;
81+
}
82+
7083
abstract protected function compileViewCreate(View $entity): string;
7184

7285
protected function compileViewDrop(View $entity): string

src/Grammars/MariaDbGrammar.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace CalebDW\SqlEntities\Grammars;
66

77
use CalebDW\SqlEntities\Function_;
8+
use CalebDW\SqlEntities\Trigger;
89
use CalebDW\SqlEntities\View;
910
use Override;
1011

@@ -31,6 +32,20 @@ protected function compileFunctionCreate(Function_ $entity): string
3132
SQL;
3233
}
3334

35+
#[Override]
36+
protected function compileTriggerCreate(Trigger $entity): string
37+
{
38+
$characteristics = implode("\n", $entity->characteristics());
39+
40+
return <<<SQL
41+
CREATE OR REPLACE TRIGGER {$entity->name()}
42+
{$entity->timing()} {$entity->events()[0]}
43+
ON {$entity->table()} FOR EACH ROW
44+
{$characteristics}
45+
{$entity->toString()}
46+
SQL;
47+
}
48+
3449
#[Override]
3550
protected function compileViewCreate(View $entity): string
3651
{

src/Grammars/MySqlGrammar.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace CalebDW\SqlEntities\Grammars;
66

77
use CalebDW\SqlEntities\Function_;
8+
use CalebDW\SqlEntities\Trigger;
89
use CalebDW\SqlEntities\View;
910
use Override;
1011

@@ -32,6 +33,20 @@ protected function compileFunctionCreate(Function_ $entity): string
3233
SQL;
3334
}
3435

36+
#[Override]
37+
protected function compileTriggerCreate(Trigger $entity): string
38+
{
39+
$characteristics = implode("\n", $entity->characteristics());
40+
41+
return <<<SQL
42+
CREATE TRIGGER IF NOT EXISTS {$entity->name()}
43+
{$entity->timing()} {$entity->events()[0]}
44+
ON {$entity->table()} FOR EACH ROW
45+
{$characteristics}
46+
{$entity->toString()}
47+
SQL;
48+
}
49+
3550
#[Override]
3651
protected function compileViewCreate(View $entity): string
3752
{

src/Grammars/PostgresGrammar.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace CalebDW\SqlEntities\Grammars;
66

77
use CalebDW\SqlEntities\Function_;
8+
use CalebDW\SqlEntities\Trigger;
89
use CalebDW\SqlEntities\View;
910
use Override;
1011

@@ -43,6 +44,30 @@ protected function compileFunctionDrop(Function_ $entity): string
4344
SQL;
4445
}
4546

47+
#[Override]
48+
protected function compileTriggerCreate(Trigger $entity): string
49+
{
50+
$contraint = $entity->constraint() ? 'CONSTRAINT' : '';
51+
$events = implode(' OR ', $entity->events());
52+
$characteristics = implode("\n", $entity->characteristics());
53+
54+
return <<<SQL
55+
CREATE OR REPLACE {$contraint} TRIGGER {$entity->name()}
56+
{$entity->timing()} {$events}
57+
ON {$entity->table()}
58+
{$characteristics}
59+
{$entity->toString()}
60+
SQL;
61+
}
62+
63+
#[Override]
64+
protected function compileTriggerDrop(Trigger $entity): string
65+
{
66+
return <<<SQL
67+
DROP TRIGGER IF EXISTS {$entity->name()} ON {$entity->table()}
68+
SQL;
69+
}
70+
4671
#[Override]
4772
protected function compileViewCreate(View $entity): string
4873
{

src/Grammars/SQLiteGrammar.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use CalebDW\SqlEntities\Contracts\SqlEntity;
88
use CalebDW\SqlEntities\Function_;
9+
use CalebDW\SqlEntities\Trigger;
910
use CalebDW\SqlEntities\View;
1011
use Override;
1112
use RuntimeException;
@@ -28,6 +29,20 @@ protected function compileFunctionCreate(Function_ $entity): string
2829
throw new RuntimeException('SQLite does not support user-defined functions.');
2930
}
3031

32+
#[Override]
33+
protected function compileTriggerCreate(Trigger $entity): string
34+
{
35+
$characteristics = implode("\n", $entity->characteristics());
36+
37+
return <<<SQL
38+
CREATE TRIGGER IF NOT EXISTS {$entity->name()}
39+
{$entity->timing()} {$entity->events()[0]}
40+
ON {$entity->table()}
41+
{$characteristics}
42+
{$entity->toString()}
43+
SQL;
44+
}
45+
3146
#[Override]
3247
protected function compileViewCreate(View $entity): string
3348
{

src/Grammars/SqlServerGrammar.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace CalebDW\SqlEntities\Grammars;
66

77
use CalebDW\SqlEntities\Function_;
8+
use CalebDW\SqlEntities\Trigger;
89
use CalebDW\SqlEntities\View;
910
use Override;
1011

@@ -29,6 +30,21 @@ protected function compileFunctionCreate(Function_ $entity): string
2930
SQL;
3031
}
3132

33+
#[Override]
34+
protected function compileTriggerCreate(Trigger $entity): string
35+
{
36+
$events = implode(', ', $entity->events());
37+
$characteristics = implode("\n", $entity->characteristics());
38+
39+
return <<<SQL
40+
CREATE OR ALTER TRIGGER {$entity->name()}
41+
ON {$entity->table()}
42+
{$entity->timing()} {$events}
43+
{$characteristics}
44+
{$entity->toString()}
45+
SQL;
46+
}
47+
3248
#[Override]
3349
protected function compileViewCreate(View $entity): string
3450
{

src/Trigger.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CalebDW\SqlEntities;
6+
7+
use CalebDW\SqlEntities\Concerns\DefaultSqlEntityBehaviour;
8+
use CalebDW\SqlEntities\Contracts\SqlEntity;
9+
10+
abstract class Trigger implements SqlEntity
11+
{
12+
use DefaultSqlEntityBehaviour;
13+
14+
/**
15+
* The trigger characteristics.
16+
*
17+
* @var list<string>
18+
*/
19+
protected array $characteristics = [];
20+
21+
/** If the trigger is a constraint trigger. */
22+
protected bool $constraint = false;
23+
24+
/**
25+
* The trigger events.
26+
*
27+
* @var list<string>
28+
*/
29+
protected array $events;
30+
31+
/** The table the trigger is associated with. */
32+
protected string $table;
33+
34+
/** The trigger timing. */
35+
protected string $timing;
36+
37+
/**
38+
* The function characteristics.
39+
*
40+
* @return list<string>
41+
*/
42+
public function characteristics(): array
43+
{
44+
return $this->characteristics;
45+
}
46+
47+
/** If the trigger is a constraint trigger. */
48+
public function constraint(): bool
49+
{
50+
return $this->constraint;
51+
}
52+
53+
/**
54+
* The trigger events.
55+
*
56+
* @return list<string>
57+
*/
58+
public function events(): array
59+
{
60+
return $this->events;
61+
}
62+
63+
/** The table the trigger is associated with. */
64+
public function table(): string
65+
{
66+
return $this->table;
67+
}
68+
69+
/** The trigger timing. */
70+
public function timing(): string
71+
{
72+
return $this->timing;
73+
}
74+
}

tests/Feature/SqlEntityManagerTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
]);
2424

2525
dataset('typesAndConnections', [
26-
'default args' => ['types' => null, 'connections' => null, 'times' => 4],
26+
'default args' => ['types' => null, 'connections' => null, 'times' => 5],
2727
'single specific type' => ['types' => UserView::class, 'connections' => null, 'times' => 1],
28-
'single connection' => ['types' => null, 'connections' => 'default', 'times' => 3],
29-
'multiple connections' => ['types' => null, 'connections' => ['default', 'foo'], 'times' => 4],
28+
'single connection' => ['types' => null, 'connections' => 'default', 'times' => 4],
29+
'multiple connections' => ['types' => null, 'connections' => ['default', 'foo'], 'times' => 5],
3030
'single abstract type' => ['types' => View::class, 'connections' => null, 'times' => 3],
3131
'multiple types' => ['types' => [UserView::class, FooConnectionUserView::class], 'connections' => null, 'times' => 2],
3232
]);

tests/Unit/Grammars/GrammarTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
use CalebDW\SqlEntities\Contracts\SqlEntity;
77
use CalebDW\SqlEntities\Function_;
88
use CalebDW\SqlEntities\Grammars\Grammar;
9+
use CalebDW\SqlEntities\Trigger;
910
use CalebDW\SqlEntities\View;
1011
use Illuminate\Database\Connection;
1112
use Illuminate\Database\Query\Builder;
1213
use Workbench\Database\Entities\functions\AddFunction;
14+
use Workbench\Database\Entities\triggers\AccountAuditTrigger;
1315
use Workbench\Database\Entities\views\UserView;
1416

1517
beforeEach(function () {
@@ -38,6 +40,14 @@
3840
SQL);
3941
});
4042

43+
it('compiles trigger drop', function () {
44+
$sql = test()->grammar->compileDrop(new AccountAuditTrigger());
45+
46+
expect($sql)->toBe(<<<'SQL'
47+
DROP TRIGGER IF EXISTS account_audit_trigger
48+
SQL);
49+
});
50+
4151
it('compiles view drop', function () {
4252
$sql = test()->grammar->compileDrop(new UserView());
4353

@@ -57,6 +67,11 @@ protected function compileFunctionCreate(Function_ $entity): string
5767
{
5868
return '';
5969
}
70+
71+
protected function compileTriggerCreate(Trigger $entity): string
72+
{
73+
return '';
74+
}
6075
}
6176

6277
class UnknownSqlEntity implements SqlEntity

0 commit comments

Comments
 (0)