Completed
Push — master ( 4174bd...a2828a )
by Jared
02:06
created

DbalDriver::updateModel()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
namespace Pulsar\Driver;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\DBALException;
7
use JAQB\Query\DeleteQuery;
8
use JAQB\Query\InsertQuery;
9
use JAQB\Query\SelectQuery;
10
use JAQB\Query\UpdateQuery;
11
use Pulsar\Exception\DriverException;
12
use Pulsar\Model;
13
use Pulsar\Query;
14
15
class DbalDriver extends AbstractDriver
16
{
17
    /**
18
     * @var Connection
19
     */
20
    private $database;
21
22
    public function __construct(Connection $connection)
23
    {
24
        $this->database = $connection;
25
    }
26
27
    public function getConnection($connection): Connection
28
    {
29
        if ($connection) {
30
            throw new DriverException('Currently multiple connections are not supported');
31
        }
32
33
        return $this->database;
34
    }
35
36
    public function createModel(Model $model, array $parameters)
37
    {
38
        // build the SQL query
39
        $tablename = $model->getTablename();
40
        $values = $this->serialize($parameters);
41
        $dbQuery = new InsertQuery();
42
        $dbQuery->into($tablename)->values($values);
43
44
        // then execute the query through DBAL
45
        $db = $this->getConnection($model->getConnection());
46
47
        try {
48
            $db->executeQuery($dbQuery->build(), $dbQuery->getValues());
49
50
            return true;
51
        } catch (DBALException $original) {
52
            $e = new DriverException('An error occurred in the database driver when creating the '.$model::modelName().': '.$original->getMessage());
53
            $e->setException($original);
54
            throw $e;
55
        }
56
    }
57
58
    public function getCreatedID(Model $model, $propertyName)
59
    {
60
        try {
61
            $id = $this->getConnection($model->getConnection())->lastInsertId();
62
        } catch (DBALException $original) {
63
            $e = new DriverException('An error occurred in the database driver when getting the ID of the new '.$model::modelName().': '.$original->getMessage());
64
            $e->setException($original);
65
            throw $e;
66
        }
67
68
        return Model::cast($model::getProperty($propertyName), $id);
0 ignored issues
show
Bug introduced by
It seems like $model::getProperty($propertyName) targeting Pulsar\Model::getProperty() can also be of type null; however, Pulsar\Model::cast() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
69
    }
70
71
    public function loadModel(Model $model)
72
    {
73
        // build the SQL query
74
        $tablename = $model->getTablename();
75
        $dbQuery = new SelectQuery();
76
        $dbQuery->select('*')
77
            ->from($tablename)
78
            ->where($model->ids());
79
80
        // then execute the query through DBAL
81
        $db = $this->getConnection($model->getConnection());
82
83
        try {
84
            $row = $db->fetchAssoc($dbQuery->build(), $dbQuery->getValues());
85
        } catch (DBALException $original) {
86
            $e = new DriverException('An error occurred in the database driver when loading an instance of '.$model::modelName().': '.$original->getMessage());
87
            $e->setException($original);
88
            throw $e;
89
        }
90
91
        if (!is_array($row)) {
92
            return false;
93
        }
94
95
        return $row;
96
    }
97
98
    public function queryModels(Query $query)
99
    {
100
        // build the SQL query
101
        $modelClass = $query->getModel();
102
        $model = new $modelClass();
103
104
        $tablename = $model->getTablename();
105
        $dbQuery = $this->buildSelectQuery($query, $tablename);
106
        $dbQuery->select($this->prefixSelect('*', $tablename))
107
            ->limit($query->getLimit(), $query->getStart())
108
            ->orderBy($this->prefixSort($query->getSort(), $tablename));
109
110
        // then execute the query through DBAL
111
        $db = $this->getConnection($model->getConnection());
112
113
        try {
114
            return $db->fetchAll($dbQuery->build(), $dbQuery->getValues());
115
        } catch (DBALException $original) {
116
            $e = new DriverException('An error occurred in the database driver while performing the '.$model::modelName().' query: '.$original->getMessage());
117
            $e->setException($original);
118
            throw $e;
119
        }
120
    }
121
122
    public function updateModel(Model $model, array $parameters)
123
    {
124
        if (0 == count($parameters)) {
125
            return true;
126
        }
127
128
        // build the SQL query
129
        $tablename = $model->getTablename();
130
        $values = $this->serialize($parameters);
131
        $dbQuery = new UpdateQuery();
132
        $dbQuery->table($tablename)
133
            ->values($values)
134
            ->where($model->ids());
135
136
        // then execute the query through DBAL
137
        $db = $this->getConnection($model->getConnection());
138
139
        try {
140
            $db->executeQuery($dbQuery->build(), $dbQuery->getValues());
141
142
            return true;
143
        } catch (DBALException $original) {
144
            $e = new DriverException('An error occurred in the database driver when updating the '.$model::modelName().': '.$original->getMessage());
145
            $e->setException($original);
146
            throw $e;
147
        }
148
    }
149
150
    public function deleteModel(Model $model)
151
    {
152
        // build the SQL query
153
        $tablename = $model->getTablename();
154
        $dbQuery = new DeleteQuery();
155
        $dbQuery->from($tablename)
156
            ->where($model->ids());
157
158
        // then execute the query through DBAL
159
        $db = $this->getConnection($model->getConnection());
160
161
        try {
162
            $db->executeQuery($dbQuery->build(), $dbQuery->getValues());
163
164
            return true;
165
        } catch (DBALException $original) {
166
            $e = new DriverException('An error occurred in the database driver while deleting the '.$model::modelName().': '.$original->getMessage());
167
            $e->setException($original);
168
            throw $e;
169
        }
170
    }
171
172
    public function count(Query $query)
173
    {
174
        // build the SQL query
175
        $modelClass = $query->getModel();
176
        $model = new $modelClass();
177
178
        $tablename = $model->getTablename();
179
        $dbQuery = $this->buildSelectQuery($query, $tablename);
180
        $dbQuery->count();
181
182
        // then execute the query through DBAL
183
        return (int) $this->executeScalar($dbQuery, $model, 'count');
184
    }
185
186
    public function sum(Query $query, $field)
187
    {
188
        // build the SQL query
189
        $modelClass = $query->getModel();
190
        $model = new $modelClass();
191
192
        $tablename = $model->getTablename();
193
        $dbQuery = $this->buildSelectQuery($query, $tablename);
194
        $dbQuery->sum($this->prefixColumn($field, $tablename));
195
196
        // then execute the query through DBAL
197
        return (int) $this->executeScalar($dbQuery, $model, $field);
198
    }
199
200
    public function average(Query $query, $field)
201
    {
202
        // build the SQL query
203
        $modelClass = $query->getModel();
204
        $model = new $modelClass();
205
206
        $tablename = $model->getTablename();
207
        $dbQuery = $this->buildSelectQuery($query, $tablename);
208
        $dbQuery->average($this->prefixColumn($field, $tablename));
209
210
        // then execute the query through DBAL
211
        return (int) $this->executeScalar($dbQuery, $model, $field);
212
    }
213
214
    public function max(Query $query, $field)
215
    {
216
        // build the SQL query
217
        $modelClass = $query->getModel();
218
        $model = new $modelClass();
219
220
        $tablename = $model->getTablename();
221
        $dbQuery = $this->buildSelectQuery($query, $tablename);
222
        $dbQuery->max($this->prefixColumn($field, $tablename));
223
224
        // then execute the query through DBAL
225
        return (int) $this->executeScalar($dbQuery, $model, $field);
226
    }
227
228
    public function min(Query $query, $field)
229
    {
230
        // build the SQL query
231
        $modelClass = $query->getModel();
232
        $model = new $modelClass();
233
234
        $tablename = $model->getTablename();
235
        $dbQuery = $this->buildSelectQuery($query, $tablename);
236
        $dbQuery->min($this->prefixColumn($field, $tablename));
237
238
        // then execute the query through DBAL
239
        return (int) $this->executeScalar($dbQuery, $model, $field);
240
    }
241
242
    //////////////////////////
243
    /// Helpers
244
    //////////////////////////
245
246
    /**
247
     * Builds a new select query.
248
     *
249
     * @param Query  $query
250
     * @param string $tablename
251
     *
252
     * @return SelectQuery
253
     */
254
    private function buildSelectQuery(Query $query, string $tablename): SelectQuery
255
    {
256
        $dbQuery = new SelectQuery();
257
        $dbQuery->from($tablename)
258
            ->where($this->prefixWhere($query->getWhere(), $tablename));
259
260
        $this->addJoins($query, $tablename, $dbQuery);
261
262
        return $dbQuery;
263
    }
264
265
    /**
266
     * Executes a select query through DBAL and returns a scalar result.
267
     *
268
     * @param SelectQuery $query
269
     * @param Model       $model
270
     * @param string      $field
271
     *
272
     * @throws DriverException
273
     *
274
     * @return false|mixed
275
     */
276
    private function executeScalar(SelectQuery $query, Model $model, string $field)
277
    {
278
        $db = $this->getConnection($model->getConnection());
279
280
        try {
281
            return $db->fetchColumn($query->build(), $query->getValues());
282
        } catch (DBALException $original) {
283
            $e = new DriverException('An error occurred in the database driver while getting the value of '.$model::modelName().'.'.$field.': '.$original->getMessage());
284
            $e->setException($original);
285
            throw $e;
286
        }
287
    }
288
289
    public function startTransaction(?string $connection): void
290
    {
291
        $this->getConnection($connection)->beginTransaction();
292
    }
293
294
    public function rollBackTransaction(?string $connection): void
295
    {
296
        $this->getConnection($connection)->rollBack();
297
    }
298
299
    public function commitTransaction(?string $connection): void
300
    {
301
        $this->getConnection($connection)->commit();
302
    }
303
}
304