Completed
Push — master ( 7b363d...433e34 )
by Oleg
07:56
created

PgsqlDriver::update()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 11

Duplication

Lines 22
Ratio 100 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 22
loc 22
rs 8.9197
c 2
b 0
f 0
cc 4
eloc 11
nc 5
nop 3
1
<?php /** PgsqlDriverMicro */
2
3
namespace Micro\Db\Drivers;
4
5
use Micro\Base\Exception;
6
7
/**
8
 * PostgreSQL Driver 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\Drivers
16
 * @version 1.0
17
 * @since 1.0
18
 */
19
class PgsqlDriver extends Driver
20
{
21
    /** @var string $tableSchema Table schema for postgres */
22
    protected $tableSchema = 'public';
23
24
25
    /**
26
     * Driver constructor.
27
     *
28
     * @access public
29
     *
30
     * @param string $dsn DSN connection string
31
     * @param array $config Configuration of connection
32
     * @param array $options Other options
33
     *
34
     * @result void
35
     * @throws Exception
36
     */
37
    public function __construct($dsn, array $config = [], array $options = [])
38
    {
39
        parent::__construct($dsn, $config, $options);
40
41
        if (!empty($config['schema'])) {
42
            $this->tableSchema = $config['schema'];
43
        }
44
    }
45
46
    /**
47
     * Set current database
48
     *
49
     * @access public
50
     *
51
     * @param string $dbName Database name
52
     *
53
     * @return boolean
54
     * @throws \InvalidArgumentException
55
     */
56
    public function switchDatabase($dbName)
57
    {
58
        // TODO: Implement switchDatabase() method.
59
    }
60
61
    /**
62
     * Info of database
63
     *
64
     * @access public
65
     *
66
     * @param string $dbName Database name
67
     *
68
     * @return array
69
     */
70
    public function infoDatabase($dbName)
71
    {
72
        // TODO: Implement infoDatabase() method.
73
    }
74
75
    /**
76
     * List tables in db
77
     *
78
     * @access public
79
     * @return array
80
     */
81
    public function listTables()
82
    {
83
        return $this->conn->query(
84
            'SELECT table_name FROM information_schema.tables WHERE table_schema = \'' . $this->tableSchema . '\';'
85
        )->fetchAll(\PDO::FETCH_COLUMN, 0);
86
    }
87
88
    /**
89
     * List database names on this connection
90
     *
91
     * @access public
92
     * @return mixed
93
     */
94
    public function listDatabases()
95
    {
96
        return $this->conn->query(
97
            'SELECT datname FROM pg_database WHERE datistemplate = false and datname != \'postgres\';'
98
        )->fetchAll(\PDO::FETCH_COLUMN, 0);
99
    }
100
101
    /**
102
     * Create a new table
103
     *
104
     * @param string $name Table name
105
     * @param array $elements Table elements
106
     * @param string $params Table params
107
     *
108
     * @return int
109
     */
110
    public function createTable($name, array $elements = [], $params = '')
111
    {
112
        return $this->conn->exec(
113
            sprintf('SELECT TABLE IF NOT EXISTS `%s` (%s) %s;', $name, implode(', ', $elements), $params)
114
        );
115
    }
116
117
    /**
118
     * Get array fields into table
119
     *
120
     * @access public
121
     *
122
     * @param string $table Table name
123
     *
124
     * @return array
125
     */
126
    public function listFields($table)
127
    {
128
        $sth = $this->conn->query('SELECT * FROM information_schema.columns WHERE table_name =\'' . $table . '\'');
129
        $result = [];
130
131
        foreach ($sth->fetchAll(\PDO::FETCH_ASSOC) as $row) {
132
            $result[] = [
133
                'field' => $row['column_name'],
134
                'type' => $row['data_type'] . (($max = $row['character_maximum_length']) ? '(' . $max . ')' : ''),
135
                'null' => $row['is_nullable'],
136
                'default' => $row['column_default']
137
            ];
138
        }
139
140
        return $result;
141
    }
142
143
    /**
144
     * Insert row into table
145
     *
146
     * @access public
147
     *
148
     * @param string $table Table name
149
     * @param array $line Line or lines to added
150
     * @param bool $multi Is multi rows
151
     *
152
     * @return bool
153
     */
154
    public function insert($table, array $line = [], $multi = false)
155
    {
156
        $fields = '"' . implode('", "', array_keys($multi ? $line[0] : $line)) . '"';
157
        $values = ':' . implode(', :', array_keys($multi ? $line[0] : $line));
158
        $rows = $multi ? $line : [$line];
159
        $id = null;
160
161
        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...
162
            $this->conn->beginTransaction();
163
164
            $dbh = null;
165
            foreach ($rows AS $row) {
166
                $res = $this->conn->prepare('INSERT INTO ' . $table . ' (' . $fields . ') VALUES (' . $values . ');');
167
                $dbh = $res->execute($row);
0 ignored issues
show
Unused Code introduced by
$dbh is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
168
                die(var_dump($res->errorCode() . ': ' . print_r($res->errorInfo(), true)));
0 ignored issues
show
Security Debugging Code introduced by
var_dump($res->errorCode...s->errorInfo(), true)); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
Coding Style Compatibility introduced by
The method insert() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
169
            }
170
171
            $id = $dbh ? $this->conn->lastInsertId() : false;
172
            $this->conn->commit();
173
        }
174
175
        return $id ?: false;
176
    }
177
178
    /**
179
     * Update row in table
180
     *
181
     * @access public
182
     *
183
     * @param string $table Table name
184
     * @param array $elements Elements to update
185
     * @param string $conditions Conditions for search
186
     *
187
     * @return bool
188
     */
189 View Code Duplication
    public function update($table, array $elements = [], $conditions = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
    {
191
        $keys = array_keys($elements);
192
193
        if (0 === count($keys)) {
194
            return false;
195
        }
196
197
        $valStr = [];
198
199
        foreach ($keys as $key) {
200
            $valStr[] = '"' . $key . '" = :' . $key;
201
        }
202
203
        $valStr = implode(',', $valStr);
204
205
        if ($conditions) {
206
            $conditions = 'WHERE ' . $conditions;
207
        }
208
209
        return $this->conn->prepare("UPDATE {$table} SET {$valStr} {$conditions};")->execute($elements);
210
    }
211
212
    /**
213
     * Exists element in the table by params
214
     *
215
     * @access public
216
     *
217
     * @param string $table Table name
218
     * @param array $params Params array
219
     *
220
     * @return bool
221
     */
222 View Code Duplication
    public function exists($table, array $params = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
223
    {
224
        $keys = [];
225
226
        foreach ($params AS $key => $val) {
227
            $keys[] = '"' . $key . '"=\'' . $val . '\'';
228
        }
229
230
        $sth = $this->conn->prepare('SELECT * FROM ' . $table . ' WHERE ' . implode(' AND ', $keys) . ' LIMIT 1;');
231
        /** @noinspection PdoApiUsageInspection */
232
        $sth->execute();
233
234
        return (bool)$sth->rowCount();
235
    }
236
}