Passed
Pull Request — 2.x (#231)
by
unknown
20:48
created

UpsertQuery::run()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 13
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Database\Query;
6
7
use Cycle\Database\Driver\CompilerInterface;
8
use Cycle\Database\Injection\Parameter;
9
10
class UpsertQuery extends ActiveQuery
11
{
12
    protected string $table;
13
    protected array $columns   = [];
14
    protected array $values    = [];
15
    protected array $conflicts = [];
16
17
    public function __construct(?string $table = null)
18
    {
19
        $this->table = $table ?? '';
20
    }
21
22
    /**
23
     * Set upsert target table.
24
     *
25
     * @psalm-param non-empty-string $into
26
     */
27
    public function into(string $into): self
28
    {
29
        $this->table = $into;
30
31
        return $this;
32
    }
33
34
    /**
35
     * Set upsert column names. Names can be provided as array, set of parameters or comma
36
     * separated string.
37
     *
38
     * Examples:
39
     * $upsert->columns(["name", "email"]);
40
     * $upsert->columns("name", "email");
41
     * $upsert->columns("name, email");
42
     */
43
    public function columns(array|string ...$columns): self
44
    {
45
        $this->columns = $this->fetchIdentifiers($columns);
46
47
        return $this;
48
    }
49
50
    /**
51
     * Set upsert rowset values or multiple rowsets. Values can be provided in multiple forms
52
     * (method parameters, array of values, array of rowsets). Columns names will be automatically
53
     * fetched (if not already specified) from first provided rowset based on rowset keys.
54
     *
55
     * Examples:
56
     * $upsert->columns("name", "balance")->values("Wolfy-J", 10);
57
     * $upsert->values([
58
     *      "name" => "Wolfy-J",
59
     *      "balance" => 10
60
     * ]);
61
     * $upsert->values([
62
     *  [
63
     *      "name" => "Wolfy-J",
64
     *      "balance" => 10
65
     *  ],
66
     *  [
67
     *      "name" => "Ben",
68
     *      "balance" => 20
69
     *  ]
70
     * ]);
71
     */
72
    public function values(mixed $rowsets): self
73
    {
74
        if (!\is_array($rowsets)) {
75
            return $this->values(\func_get_args());
76
        }
77
78
        if ($rowsets === []) {
79
            return $this;
80
        }
81
82
        //Checking if provided set is array of multiple
83
        \reset($rowsets);
84
85
        if (!\is_array($rowsets[\key($rowsets)])) {
86
            if ($this->columns === []) {
87
                $this->columns = \array_keys($rowsets);
88
            }
89
90
            $this->values[] = new Parameter(\array_values($rowsets));
91
        } else {
92
            if ($this->columns === []) {
93
                $this->columns = \array_keys($rowsets[\key($rowsets)]);
94
            }
95
96
            foreach ($rowsets as $values) {
97
                $this->values[] = new Parameter(\array_values($values));
98
            }
99
        }
100
101
        return $this;
102
    }
103
104
    /**
105
     * Set upsert conflicting index column names. Names can be provided as array, set of parameters or comma
106
     * separated string.
107
     *
108
     * Examples:
109
     * $upsert->conflicts(["identifier", "email"]);
110
     * $upsert->conflicts("identifier", "email");
111
     * $upsert->conflicts("identifier, email");
112
     */
113
    public function conflicts(array|string ...$conflicts): self
114
    {
115
        $this->conflicts = $this->fetchIdentifiers($conflicts);
116
117
        return $this;
118
    }
119
120
    /**
121
     * Run the query and return last insert id.
122
     * Returns an assoc array of values if multiple columns were specified as returning columns.
123
     *
124
     * @return array<non-empty-string, mixed>|int|non-empty-string|null
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<non-empty-string, ...t|non-empty-string|null at position 2 could not be parsed: Unknown type name 'non-empty-string' at position 2 in array<non-empty-string, mixed>|int|non-empty-string|null.
Loading history...
125
     */
126
    public function run(): mixed
127
    {
128
        $params = new QueryParameters();
129
        $queryString = $this->sqlStatement($params);
130
131
        $this->driver->execute(
0 ignored issues
show
Bug introduced by
The method execute() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

131
        $this->driver->/** @scrutinizer ignore-call */ 
132
                       execute(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
132
            $queryString,
133
            $params->getParameters(),
134
        );
135
136
        $lastID = $this->driver->lastInsertID();
137
138
        return \is_numeric($lastID) ? (int) $lastID : $lastID;
139
    }
140
141
    public function getType(): int
142
    {
143
        return CompilerInterface::UPSERT_QUERY;
144
    }
145
146
    public function getTokens(): array
147
    {
148
        return [
149
            'table'     => $this->table,
150
            'columns'   => $this->columns,
151
            'values'    => $this->values,
152
            'conflicts' => $this->conflicts,
153
        ];
154
    }
155
}
156