-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInsert.php
More file actions
88 lines (69 loc) · 2.53 KB
/
Insert.php
File metadata and controls
88 lines (69 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php
declare(strict_types=1);
namespace Phenix\Database\Dialects\Postgres\Compilers;
use Phenix\Database\Dialects\CompiledClause;
use Phenix\Database\Dialects\Compilers\InsertCompiler;
use Phenix\Database\Dialects\Postgres\Concerns\HasPlaceholders;
use Phenix\Database\QueryAst;
use Phenix\Util\Arr;
/**
* Supports:
* - INSERT ... ON CONFLICT DO NOTHING (ignore conflicts)
* - INSERT ... ON CONFLICT (...) DO UPDATE SET (upsert functionality)
*/
class Insert extends InsertCompiler
{
use HasPlaceholders;
protected function compileInsertIgnore(): string
{
return 'INSERT INTO';
}
protected function compileUpsert(QueryAst $ast): string
{
$conflictColumns = Arr::implodeDeeply($ast->uniqueColumns, ', ');
$updateColumns = array_map(function (string $column): string {
return "{$column} = EXCLUDED.{$column}";
}, $ast->uniqueColumns);
return sprintf(
'ON CONFLICT (%s) DO UPDATE SET %s',
$conflictColumns,
Arr::implodeDeeply($updateColumns, ', ')
);
}
public function compile(QueryAst $ast): CompiledClause
{
if ($ast->ignore && empty($ast->uniqueColumns)) {
$parts = [];
$parts[] = 'INSERT INTO';
$parts[] = $ast->table;
$parts[] = '(' . Arr::implodeDeeply($ast->columns, ', ') . ')';
if ($ast->rawStatement !== null) {
$parts[] = $ast->rawStatement;
} else {
$parts[] = 'VALUES';
$placeholders = array_map(function (array $value): string {
return '(' . Arr::implodeDeeply($value, ', ') . ')';
}, $ast->values);
$parts[] = Arr::implodeDeeply(array_values($placeholders), ', ');
}
$parts[] = 'ON CONFLICT DO NOTHING';
if (! empty($ast->returning)) {
$parts[] = 'RETURNING';
$parts[] = Arr::implodeDeeply($ast->returning, ', ');
}
$sql = Arr::implodeDeeply($parts);
$sql = $this->convertPlaceholders($sql);
return new CompiledClause($sql, $ast->params);
}
$result = parent::compile($ast);
$parts = [$result->sql];
if (! empty($ast->returning)) {
$parts[] = 'RETURNING';
$parts[] = Arr::implodeDeeply($ast->returning, ', ');
}
return new CompiledClause(
$this->convertPlaceholders(Arr::implodeDeeply($parts)),
$result->params
);
}
}