PdoCrud::insertMultyple()   A
last analyzed

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
     *
64
     * @param string $fieldName
65
     * @return int
66
     */
67
    public function getRecordsCount(string $fieldName = 'records_count'): int
68
    {
69
        $records = $this->executeSelect();
70
71
        if (empty($records)) {
72
            return 0;
73
        } else {
74
            return $records[0]->$fieldName;
75
        }
76
    }
77
78
    /**
79
     * Getting records
80
     *
81
     * @param string $fields
82
     *            List of fields
83
     * @param string $tableNames
84
     *            List of tables
85
     * @param string $where
86
     *            Condition
87
     * @param int $from
88
     *            First record in query
89
     * @param int $limit
90
     *            Count of records
91
     * @return array List of records
92
     * @deprecated since 2020-06-16
93
     */
94
    public function select(
95
        string $fields,
96
        string $tableNames,
97
        string $where = '1 = 1',
98
        int $from = 0,
99
        int $limit = 1000000): array
100
    {
101
        $query = "SELECT $fields FROM $tableNames WHERE $where LIMIT " . intval($from) . ' , ' . intval($limit);
102
103
        $result = $this->query($query);
104
105
        $this->processQueryError($result, $query);
106
107
        return $result->fetchAll(\PDO::FETCH_ASSOC);
108
    }
109
110
    /**
111
     * Method compiles set-query
112
     *
113
     * @param array $record
114
     *            Inserting record
115
     * @return string Compiled query string
116
     */
117
    protected function compileGetQuery(array $record): string
118
    {
119
        $setFieldsStatement = [];
120
121
        foreach ($record as $field => $value) {
122
            if (is_string($value) && strtoupper($value) === 'INC') {
123
                $setFieldsStatement[] = $field . ' = ' . $field . ' + 1';
124
            } elseif (is_string($value) && strtoupper($value) !== 'NOW()') {
125
                $setFieldsStatement[] = $field . ' = "' . $value . '"';
126
            } elseif ($value === null) {
127
                $setFieldsStatement[] = $field . ' = NULL';
128
            } else {
129
                $setFieldsStatement[] = $field . ' = ' . $value;
130
            }
131
        }
132
133
        return implode(' , ', $setFieldsStatement);
134
    }
135
136
    /**
137
     * Method compiles set-multyple-query
138
     *
139
     * @param array $records
140
     *            Inserting records
141
     * @return string Compiled query string
142
     */
143
    protected function setMultypleQuery(array $records): string
144
    {
145
        $query = '( ' . implode(' , ', array_keys($records[0])) . ' ) VALUES ';
146
147
        $values = [];
148
149
        foreach ($records as $record) {
150
            $values[] = "( '" . implode("' , '", array_values($record)) . "' )";
151
        }
152
153
        return $query . implode(' , ', $values);
154
    }
155
156
    /**
157
     * Updating records
158
     *
159
     * @param string $tableName
160
     *            Table name
161
     * @param array $record
162
     *            Updating records
163
     * @param string $where
164
     *            Condition
165
     * @param int $limit
166
     *            Limit for afffecting records
167
     * @return int Count of updated records
168
     * @deprecated Deprecated since 2020-11-21, use execute
169
     */
170
    public function update(string $tableName, array $record, string $where, int $limit = 10000000): int
171
    {
172
        $query = 'UPDATE ' . $tableName . ' SET ' . $this->compileGetQuery($record) . ' WHERE ' . $where . ' LIMIT ' .
173
            $limit;
174
175
        $result = $this->query($query);
176
177
        $this->processQueryError($result, $query);
178
179
        return $result->rowCount();
180
    }
181
182
    /**
183
     * Deleting records
184
     *
185
     * @param string $tableName
186
     *            Table name
187
     * @param string $where
188
     *            Condition
189
     * @param int $limit
190
     *            Liti for afffecting records
191
     * @return int Count of deleted records
192
     * @deprecated Deprecated since 2020-11-21, use execute
193
     */
194
    public function delete($tableName, $where, $limit = 10000000): int
195
    {
196
        // TODO remove this method, do not forget to up version
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