Completed
Push — master ( 5d8d83...636137 )
by Alex
02:12
created

PdoCrud::unlock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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