Passed
Push — master ( ff0d7b...2a62f8 )
by Alex
08:11
created

PdoCrud::insert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 9
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 2
1
<?php
2
namespace Mezon\PdoCrud;
3
4
/**
5
 * Class PdoCrud
6
 *
7
 * @package Mezon
8
 * @subpackage PdoCrud
9
 * @author Dodonov A.A.
10
 * @version v.1.0 (2019/08/16)
11
 * @copyright Copyright (c) 2019, aeon.org
12
 */
13
14
/**
15
 * Class provides simple CRUD operations
16
 */
17
class PdoCrud
18
{
19
20
    /**
21
     * PDO object
22
     *
23
     * @var \PDO
24
     */
25
    private $pdo = null;
26
27
    use PdoCrudStatement;
28
29
    /**
30
     * Method connects to the database
31
     *
32
     * @param array $connnectionData
33
     *            Connection settings
34
     * @codeCoverageIgnore
35
     */
36
    public function connect(array $connnectionData): void
37
    {
38
        // no need to test this single string. assume that PDO developers did it
39
        $this->pdo = new \PDO($connnectionData['dsn'], $connnectionData['user'], $connnectionData['password']);
40
41
        $this->query('SET NAMES utf8');
42
    }
43
44
    /**
45
     * Method handles request errors
46
     *
47
     * @param mixed $result
48
     *            Query result
49
     * @param string $query
50
     *            SQL Query
51
     * @codeCoverageIgnore
52
     */
53
    protected function processQueryError($result, string $query): void
54
    {
55
        if ($result === false) {
56
            $errorInfo = $this->pdo->errorInfo();
57
58
            throw (new \Exception($errorInfo[2] . ' in statement ' . $query));
59
        }
60
    }
61
62
    /**
63
     * Method executes SQL query
64
     *
65
     * @param ?array $data
66
     *            query data
67
     * @codeCoverageIgnore
68
     */
69
    public function execute(?array $data = null):void{
70
        if ($this->pdoStatement->execute($data) === false) {
71
            $info = $this->pdoStatement->errorInfo();
72
            
73
            throw (new \Exception($info[2], - 1));
74
        }
75
    }
76
    
77
    /**
78
     * Method executes select query and fetches results
79
     *
80
     * @param ?array $data
81
     *            query data
82
     * @return array query result as an array of objects
83
     * @codeCoverageIgnore
84
     */
85
    public function executeSelect(?array $data = null): array
86
    {
87
        $this->execute($data);
88
89
        return $this->pdoStatement->fetchAll(\PDO::FETCH_OBJ);
90
    }
91
92
    /**
93
     * 
94
     * @param string $fieldName
95
     * @return int
96
     */
97
    public function getRecordsCount(string $fieldName = 'records_count'):int{
98
        $records = $this->executeSelect();
99
        
100
        if(empty($records)){
101
            return 0;
102
        }
103
        else{
104
            return $records[0]->$fieldName;
105
        }
106
    }
107
108
    /**
109
     * Method executes select query and fetches results
110
     *
111
     * @param ?array $data
112
     *            query data
113
     * @return array query result as an array of objects
114
     * @codeCoverageIgnore
115
     * @deprecated Deprecated since 2020-11-21, use executeSelect
116
     */
117
    public function execSelect(?array $data = null): array
118
    {
119
        return $this->executeSelect($data);
120
    }
121
122
    /**
123
     * Getting records
124
     *
125
     * @param string $fields
126
     *            List of fields
127
     * @param string $tableNames
128
     *            List of tables
129
     * @param string $where
130
     *            Condition
131
     * @param int $from
132
     *            First record in query
133
     * @param int $limit
134
     *            Count of records
135
     * @return array List of records
136
     * @deprecated since 2020-06-16
137
     */
138
    public function select(
139
        string $fields,
140
        string $tableNames,
141
        string $where = '1 = 1',
142
        int $from = 0,
143
        int $limit = 1000000): array
144
    {
145
        $query = "SELECT $fields FROM $tableNames WHERE $where LIMIT " . intval($from) . ' , ' . intval($limit);
146
147
        $result = $this->query($query);
148
149
        $this->processQueryError($result, $query);
150
151
        return $result->fetchAll(\PDO::FETCH_ASSOC);
152
    }
153
154
    /**
155
     * Method compiles set-query
156
     *
157
     * @param array $record
158
     *            Inserting record
159
     * @return string Compiled query string
160
     */
161
    protected function compileGetQuery(array $record): string
162
    {
163
        $setFieldsStatement = [];
164
165
        foreach ($record as $field => $value) {
166
            if (is_string($value) && strtoupper($value) === 'INC') {
167
                $setFieldsStatement[] = $field . ' = ' . $field . ' + 1';
168
            } elseif (is_string($value) && strtoupper($value) !== 'NOW()') {
169
                $setFieldsStatement[] = $field . ' = "' . $value . '"';
170
            } elseif ($value === null) {
171
                $setFieldsStatement[] = $field . ' = NULL';
172
            } else {
173
                $setFieldsStatement[] = $field . ' = ' . $value;
174
            }
175
        }
176
177
        return implode(' , ', $setFieldsStatement);
178
    }
179
180
    /**
181
     * Method compiles set-multyple-query
182
     *
183
     * @param array $records
184
     *            Inserting records
185
     * @return string Compiled query string
186
     */
187
    protected function setMultypleQuery(array $records): string
188
    {
189
        $query = '( ' . implode(' , ', array_keys($records[0])) . ' ) VALUES ';
190
191
        $values = [];
192
193
        foreach ($records as $record) {
194
            $values[] = "( '" . implode("' , '", array_values($record)) . "' )";
195
        }
196
197
        return $query . implode(' , ', $values);
198
    }
199
200
    /**
201
     * Updating records
202
     *
203
     * @param string $tableName
204
     *            Table name
205
     * @param array $record
206
     *            Updating records
207
     * @param string $where
208
     *            Condition
209
     * @param int $limit
210
     *            Limit for afffecting records
211
     * @return int Count of updated records
212
     * @deprecated Deprecated since 2020-11-21, use execute
213
     */
214
    public function update(string $tableName, array $record, string $where, int $limit = 10000000): int
215
    {
216
        $query = 'UPDATE ' . $tableName . ' SET ' . $this->compileGetQuery($record) . ' WHERE ' . $where . ' LIMIT ' .
217
            $limit;
218
219
        $result = $this->query($query);
220
221
        $this->processQueryError($result, $query);
222
223
        return $result->rowCount();
224
    }
225
226
    /**
227
     * Deleting records
228
     *
229
     * @param string $tableName
230
     *            Table name
231
     * @param string $where
232
     *            Condition
233
     * @param int $limit
234
     *            Liti for afffecting records
235
     * @return int Count of deleted records
236
     * @deprecated Deprecated since 2020-11-21, use execute
237
     */
238
    public function delete($tableName, $where, $limit = 10000000): int
239
    {
240
        $query = 'DELETE FROM ' . $tableName . ' WHERE ' . $where . ' LIMIT ' . intval($limit);
241
242
        $result = $this->query($query);
243
244
        $this->processQueryError($result, $query);
245
246
        return $result->rowCount();
247
    }
248
249
    /**
250
     * Method compiles lock queries
251
     *
252
     * @param array $tables
253
     *            List of tables
254
     * @param array $modes
255
     *            List of lock modes
256
     * @return string Query
257
     */
258
    protected function lockQuery(array $tables, array $modes): string
259
    {
260
        $query = [];
261
262
        foreach ($tables as $i => $table) {
263
            $query[] = $table . ' ' . $modes[$i];
264
        }
265
266
        return 'LOCK TABLES ' . implode(' , ', $query);
267
    }
268
269
    /**
270
     * Method locks tables
271
     *
272
     * @param array $tables
273
     *            List of tables
274
     * @param array $modes
275
     *            List of lock modes
276
     */
277
    public function lock(array $tables, array $modes): void
278
    {
279
        $query = $this->lockQuery($tables, $modes);
280
281
        $result = $this->query($query);
282
283
        $this->processQueryError($result, $query);
284
    }
285
286
    /**
287
     * Method unlocks locked tables
288
     */
289
    public function unlock(): void
290
    {
291
        $result = $this->query('UNLOCK TABLES');
292
293
        $this->processQueryError($result, 'UNLOCK TABLES');
294
    }
295
296
    /**
297
     * Method starts transaction
298
     */
299
    public function startTransaction(): void
300
    {
301
        // setting autocommit off
302
        $result = $this->query('SET AUTOCOMMIT = 0');
303
304
        $this->processQueryError($result, 'SET AUTOCOMMIT = 0');
305
306
        // starting transaction
307
        $result = $this->query('START TRANSACTION');
308
309
        $this->processQueryError($result, 'START TRANSACTION');
310
    }
311
312
    /**
313
     * Commiting transaction
314
     */
315
    public function commit(): void
316
    {
317
        // commit transaction
318
        $result = $this->query('COMMIT');
319
320
        $this->processQueryError($result, 'COMMIT');
321
322
        // setting autocommit on
323
        $result = $this->query('SET AUTOCOMMIT = 1');
324
325
        $this->processQueryError($result, 'SET AUTOCOMMIT = 1');
326
    }
327
328
    /**
329
     * Rollback transaction
330
     */
331
    public function rollback(): void
332
    {
333
        // rollback transaction
334
        $result = $this->query('ROLLBACK');
335
336
        $this->processQueryError($result, 'ROLLBACK');
337
    }
338
339
    /**
340
     * Method executes query
341
     *
342
     * @param string $query
343
     *            Query
344
     * @return mixed Query execution result
345
     */
346
    public function query(string $query)
347
    {
348
        // @codeCoverageIgnoreStart
349
        return $this->pdo->query($query);
350
        // @codeCoverageIgnoreEnd
351
    }
352
353
    /**
354
     * Method returns id of the last inserted record
355
     *
356
     * @return int id of the last inserted record
357
     */
358
    public function lastInsertId(): int
359
    {
360
        // @codeCoverageIgnoreStart
361
        return (int) $this->pdo->lastInsertId();
362
        // @codeCoverageIgnoreEnd
363
    }
364
365
    /**
366
     * Method inserts record
367
     *
368
     * @param string $tableName
369
     *            Table name
370
     * @param array $record
371
     *            Inserting record
372
     * @return int New record's id
373
     * @deprecated Deprecated since 2020-11-21, use execute
374
     */
375
    public function insert(string $tableName, array $record): int
376
    {
377
        $query = 'INSERT ' . $tableName . ' SET ' . $this->compileGetQuery($record);
378
379
        $result = $this->query($query);
380
381
        $this->processQueryError($result, $query);
382
383
        return $this->lastInsertId();
384
    }
385
386
    /**
387
     * Method inserts record
388
     *
389
     * @param string $tableName
390
     *            Table name
391
     * @param array $records
392
     *            Inserting records
393
     * @return int New record's id
394
     * @deprecated Deprecated since 2020-11-21, use execute
395
     */
396
    public function insertMultyple(string $tableName, array $records): int
397
    {
398
        $query = 'INSERT INTO ' . $tableName . ' ' . $this->setMultypleQuery($records) . ';';
399
400
        $result = $this->query($query);
401
402
        $this->processQueryError($result, $query);
403
404
        return 0;
405
    }
406
407
    /**
408
     * Method destroys connection
409
     */
410
    public function __destruct()
411
    {
412
        $this->pdo = null;
413
414
        unset($this->pdo);
415
    }
416
}
417