Completed
Push — master ( 7bb97e...01c45f )
by Oleg
03:57
created

DbConnection::listFields()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
c 0
b 0
f 0
rs 9.4285
nc 2
cc 2
eloc 12
nop 1
1
<?php /** MicroDataBaseConnection */
2
3
namespace Micro\Db;
4
5
use Micro\Base\Exception;
6
7
/**
8
 * Connection class file.
9
 *
10
 * @author Oleg Lunegov <[email protected]>
11
 * @link https://github.com/linpax/microphp-framework
12
 * @copyright Copyright (c) 2013 Oleg Lunegov
13
 * @license https://github.com/linpax/microphp-framework/blob/master/LICENSE
14
 * @package Micro
15
 * @subpackage Db
16
 * @version 1.0
17
 * @since 1.0
18
 */
19
class DbConnection extends Connection
20
{
21
    /** @var \PDO|null $conn Connection to DB */
22
    protected $conn;
23
    /** @var string $tableSchema */
24
    protected $tableSchema = 'public';
25
26
27
    /**
28
     * Construct for this class
29
     *
30
     * @access public
31
     *
32
     * @param array $config
33
     * @param array $options
34
     *
35
     * @result void
36
     * @throws Exception
37
     */
38
    public function __construct(array $config = [], array $options = [])
39
    {
40
        parent::__construct();
41
42
        if (!empty($config['schema'])) {
43
            $this->tableSchema = $config['schema'];
44
        }
45
46
        try {
47
            $this->conn = new \PDO($config['connectionString'], $config['username'], $config['password'],
48
                $options
49
            );
50
        } catch (\PDOException $e) {
51
            if (!array_key_exists('ignoreFail', $config) || !$config['ignoreFail']) {
52
                throw new Exception('Connect to DB failed: '.$e->getMessage());
53
            }
54
        }
55
    }
56
57
    /**
58
     * Destructor for this class
59
     *
60
     * @access public
61
     * @return void
62
     */
63
    public function __destruct()
64
    {
65
        $this->conn = null;
66
    }
67
68
    /**
69
     * @inheritdoc
70
     */
71
    public function rawQuery($query = '', array $params = [], $fetchType = \PDO::FETCH_ASSOC, $fetchClass = 'Model')
72
    {
73
        $sth = $this->conn->prepare($query);
74
75
        if ($fetchType === \PDO::FETCH_CLASS) {
76
            /** @noinspection PhpMethodParametersCountMismatchInspection */
77
            $sth->setFetchMode($fetchType, ucfirst($fetchClass), ['new' => false]);
78
        } else {
79
            $sth->setFetchMode($fetchType);
80
        }
81
82
        foreach ($params AS $name => $value) {
83
            $sth->bindValue($name, $value);
84
        }
85
86
        $sth->execute();
87
88
        return $sth->fetchAll();
89
    }
90
91
    /**
92
     * @inheritdoc
93
     */
94
    public function listDatabases()
95
    {
96
        $sth = $this->conn->query('SHOW DATABASES;');
97
98
        $result = [];
99
        foreach ($sth->fetchAll() AS $row) {
100
            $result[] = $row[0];
101
        }
102
103
        return $result;
104
    }
105
106
    /**
107
     * @inheritdoc
108
     */
109
    public function infoDatabase($dbName)
110
    {
111
        $sth = $this->conn->query("SHOW TABLE STATUS FROM {$dbName};");
112
113
        $result = [];
114
        foreach ($sth->fetchAll() AS $row) {
115
            $result[] = [
116
                'name' => $row['Name'],
117
                'engine' => $row['Engine'],
118
                'rows' => $row['Rows'],
119
                'length' => $row['Avg_row_length'],
120
                'increment' => $row['Auto_increment'],
121
                'collation' => $row['Collation']
122
            ];
123
        }
124
125
        return $result;
126
    }
127
128
    /**
129
     * @inheritdoc
130
     */
131
    public function tableExists($table)
132
    {
133
        return in_array($table, $this->listTables(), false);
134
    }
135
136
    /**
137
     * @inheritdoc
138
     */
139
    public function listTables()
140
    {
141
        $sql = 'SHOW TABLES;';
142
143
        if ($this->getDriverType() == 'pgsql') {
144
            $sql = 'SELECT table_name FROM information_schema.tables WHERE table_schema = \'' . $this->tableSchema . '\'';
145
        }
146
147
        return $this->conn->query($sql)->fetchAll(\PDO::FETCH_COLUMN, 0);
148
    }
149
150
    public function getDriverType()
151
    {
152
        return $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME);
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158
    public function createTable($name, array $elements = [], $params = '')
159
    {
160
        return $this->conn->exec(
161
            sprintf('SELECT TABLE IF NOT EXISTS `%s` (%s) %s;', $name, implode(',', $elements), $params)
162
        );
163
    }
164
165
    /**
166
     * @inheritdoc
167
     */
168
    public function clearTable($name)
169
    {
170
        return $this->conn->exec("TRUNCATE {$name};");
171
    }
172
173
    /**
174
     * @inheritdoc
175
     */
176
    public function removeTable($name)
177
    {
178
        return $this->conn->exec("DROP TABLE {$name};");
179
    }
180
181
    /**
182
     * @inheritdoc
183
     */
184
    public function fieldExists($field, $table)
185
    {
186
        foreach ($this->listFields($table) AS $tbl) {
187
            if ($tbl['field'] === $field) {
188
                return true;
189
            }
190
        }
191
192
        return false;
193
    }
194
195
    /**
196
     * @inheritdoc
197
     */
198
    public function listFields($table)
199
    {
200
        $sth = $this->conn->query("SHOW COLUMNS FROM {$table};");
201
202
        $result = [];
203
        foreach ($sth->fetchAll(\PDO::FETCH_ASSOC) as $row) {
204
            $result[] = [
205
                'field' => $row['Field'],
206
                'type' => $row['Type'],
207
                'null' => $row['Null'],
208
                'key' => $row['Key'],
209
                'default' => $row['Default'],
210
                'extra' => $row['Extra']
211
            ];
212
        }
213
214
        return $result;
215
    }
216
217
    /**
218
     * @inheritdoc
219
     */
220
    public function fieldInfo($field, $table)
221
    {
222
        return $this->conn->query("SELECT {$field} FROM {$table} LIMIT 1;")->getColumnMeta(0);
223
    }
224
225
    /**
226
     * @inheritdoc
227
     */
228
    public function switchDatabase($dbName)
229
    {
230
        if ($this->conn->exec("USE {$dbName};") !== false) {
231
            return true;
232
        } else {
233
            return false;
234
        }
235
    }
236
237
    /**
238
     * @inheritdoc
239
     */
240
    public function insert($table, array $line = [], $multi = false)
241
    {
242
        $fields = '`'.implode('`, `', array_keys($multi ? $line[0] : $line)).'`';
243
        $values = ':'.implode(', :', array_keys($multi ? $line[0] : $line));
244
        $rows = $multi ? $line : [$line];
245
        $id = null;
246
247
        if ($rows) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $rows of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
248
            $this->conn->beginTransaction();
249
250
            $dbh = null;
251
            foreach ($rows AS $row) {
252
                $dbh = $this->conn->prepare("INSERT INTO {$table} ({$fields}) VALUES ({$values});")->execute($row);
253
            }
254
255
            $id = $dbh ? $this->conn->lastInsertId() : false;
256
            $this->conn->commit();
257
        }
258
259
        return $id ?: false;
260
    }
261
262
    /**
263
     * @inheritdoc
264
     */
265
    public function update($table, array $elements = [], $conditions = '')
266
    {
267
        $keys = array_keys($elements);
268
        if (0 === count($keys)) {
269
            return false;
270
        }
271
272
        $valStr = [];
273
        foreach ($keys as $key) {
274
            $valStr[] = '`'.$key.'` = :'.$key;
275
        }
276
        $valStr = implode(',', $valStr);
277
278
        if ($conditions) {
279
            $conditions = 'WHERE '.$conditions;
280
        }
281
282
        return $this->conn->prepare("UPDATE {$table} SET {$valStr} {$conditions};")->execute($elements);
283
    }
284
285
    /**
286
     * @inheritdoc
287
     */
288
    public function delete($table, $conditions, array $ph = [])
289
    {
290
        return $this->conn->prepare("DELETE FROM {$table} WHERE {$conditions};")->execute($ph);
291
    }
292
293
    /**
294
     * @inheritdoc
295
     */
296
    public function exists($table, array $params = [])
297
    {
298
        $keys = [];
299
        foreach ($params AS $key => $val) {
300
            $keys[] = $table . '.' . $key . '=\'' . $val . '\'';
301
        }
302
303
        $sth = $this->conn->prepare('SELECT * FROM ' . $table . ' WHERE ' . implode(' AND ', $keys) . ' LIMIT 1;');
304
        /** @noinspection PdoApiUsageInspection */
305
        $sth->execute();
306
307
        return (bool)$sth->rowCount();
308
    }
309
310
    /**
311
     * @inheritdoc
312
     */
313
    public function count($subQuery = '', $table = '')
314
    {
315
        if ($subQuery) {
316
            $sth = $this->conn->prepare("SELECT COUNT(*) FROM ({$subQuery}) AS m;");
317
        } elseif ($table) {
318
            $sth = $this->conn->prepare("SELECT COUNT(*) FROM {$table} AS m;");
319
        } else {
320
            return false;
321
        }
322
        if ($sth->execute()) {
323
            return $sth->fetchColumn();
324
        }
325
326
        return false;
327
    }
328
}
329