Completed
Push — master ( 80942e...842882 )
by Mr
02:00
created

SQL::update()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 2
1
<?php
2
3
namespace DrMVC\Database\Drivers;
4
5
use DrMVC\Database\SQLException;
6
7
abstract class SQL extends Driver
8
{
9
    /**
10
     * Initiate connection to database
11
     *
12
     * @return  DriverInterface
13
     */
14
    public function connect(): DriverInterface
15
    {
16
        try {
17
            $connection = new \PDO(
18
                $this->getDsn(),
19
                $this->getParam('username'),
20
                $this->getParam('password')
21
            );
22
        } catch (SQLException $e) {
23
            // __construct
24
        }
25
        $this->setConnection($connection);
26
27
        return $this;
28
    }
29
30
    /**
31
     * Close database connection
32
     *
33
     * @return  DriverInterface
34
     */
35
    public function disconnect(): DriverInterface
36
    {
37
        $this->setConnection(null);
38
        return $this;
39
    }
40
41
    /**
42
     * Run a select statement against the database
43
     *
44
     * @param   string $query
45
     * @param   array $data
46
     * @return  array|object
47
     */
48
    public function select(string $query, array $data = [])
49
    {
50
        // Set statement
51
        $statement = $this->getConnection()->prepare($query);
52
53
        // Parse parameters from array
54
        foreach ($data as $key => $value) {
55
            $value_type = \is_int($value) ? \PDO::PARAM_INT : \PDO::PARAM_STR;
56
            $statement->bindValue($key, $value, $value_type);
57
        }
58
59
        // Execute the statement
60
        $statement->execute();
61
62
        // Return result
63
        return $statement->fetchAll(\PDO::FETCH_OBJ);
64
    }
65
66
    /**
67
     * Exec query without return, create table for example
68
     *
69
     * @param   string $query
70
     * @return  mixed
71
     */
72
    public function exec(string $query)
73
    {
74
        return $this->getConnection()->exec($query);
75
    }
76
77
    /**
78
     * Generate INSERT query by array
79
     *
80
     * @param   array $data
81
     * @return  string
82
     */
83
    private function genInsert(array $data): string
84
    {
85
        // Current table
86
        $table = $this->getCollection();
87
88
        // Generate array of fields for insert
89
        $fieldNames = implode(',', array_keys($data));
90
91
        // Generate line with data for update
92
        $fieldDetails = ':' . implode(', :', array_keys($data));
93
94
        return "INSERT INTO $table ($fieldNames) VALUES ($fieldDetails)";
95
    }
96
97
    /**
98
     * Insert in database and return of inserted element
99
     *
100
     * @param   array $data array of columns and values
101
     * @param   string $id field name of ID which must be returned
102
     * @return  mixed
103
     */
104
    public function insert(array $data, string $id = null)
105
    {
106
        // Prepare query
107
        $query = $this->genInsert($data);
108
        $statement = $this->_connection->prepare($query);
109
110
        // Bind values
111
        foreach ($data as $key => $value) {
112
            $statement->bindValue(":$key", $value);
113
        }
114
115
        // Execute operation
116
        $statement->execute();
117
118
        return (null !== $id)
119
            // Return ID of inserted element
120
            ? $this->getConnection()->lastInsertId($id)
121
            // Return count of affected rows
122
            : $statement->rowCount();
123
    }
124
125
    /**
126
     * Generate the line by provided keys
127
     *
128
     * @param   array $array array with data
129
     * @param   string $glue by this glue need merge items
130
     * @param   string $name name of field for PDO->bindValue
131
     * @return  string
132
     */
133
    private function genLine(array $array, string $glue, string $name): string
134
    {
135
        $line = '';
136
        $i = 0;
137
        foreach ($array as $key => $value) {
138
            $line .= (($i !== 0) ? null : $glue) . "$key = :${name}_$key";
139
            $i = 1;
140
        }
141
        return $line;
142
    }
143
144
    /**
145
     * Generate set of fields
146
     *
147
     * @param   array $array
148
     * @return  string
149
     */
150
    private function genFields(array $array): string
151
    {
152
        return $this->genLine($array, ', ', 'field');
153
    }
154
155
    /**
156
     * Generate WHERE line
157
     *
158
     * @param   array $array
159
     * @return  string
160
     */
161
    private function genWhere(array $array): string
162
    {
163
        return $this->genLine($array, ' AND ', 'where');
164
    }
165
166
    /**
167
     * Generate update query
168
     *
169
     * @param   array $data
170
     * @param   array $where
171
     * @return  string
172
     */
173
    private function genUpdate(array $data, array $where): string
174
    {
175
        // Current table
176
        $table = $this->getConnection();
177
178
        // Generate line with data for update
179
        $fieldDetails = !empty($data)
180
            ? $this->genFields($data)
181
            : '';
182
183
        // Generate where line
184
        $whereDetails = !empty($where)
185
            ? ' WHERE ' . $this->genWhere($where)
186
            : '';
187
188
        return "UPDATE $table SET $fieldDetails $whereDetails";
189
    }
190
191
    /**
192
     * Update method
193
     *
194
     * @param  array $data array of columns and values
195
     * @param  array $where array of columns and values
196
     * @return mixed
197
     */
198
    public function update(array $data, array $where)
199
    {
200
        // Prepare query
201
        $query = $this->genUpdate($data, $where);
202
        $statement = $this->getConnection()->prepare($query);
203
204
        // Bind field values
205
        foreach ($data as $key => $value) {
206
            $statement->bindValue(":field_$key", $value);
207
        }
208
209
        // Bind where values
210
        foreach ($where as $key => $value) {
211
            $statement->bindValue(":where_$key", $value);
212
        }
213
214
        // Execute operation
215
        $statement->execute();
216
217
        // Return count of affected rows
218
        return $statement->rowCount();
219
    }
220
221
    /**
222
     * Delete rows from database
223
     *
224
     * @param   array $where
225
     * @return  mixed
226
     */
227
    public function delete(array $where)
228
    {
229
        // Current table
230
        $table = $this->getConnection();
231
232
        // Generate where line
233
        $whereDetails = !empty($where)
234
            ? ' WHERE ' . $this->genWhere($where)
235
            : '';
236
237
        // Prepare query
238
        $statement = $this->getConnection()->prepare("DELETE FROM $table $whereDetails");
239
240
        // Bind where values
241
        foreach ($where as $key => $value) {
242
            $statement->bindValue(":where_$key", $value);
243
        }
244
245
        // Execute operation
246
        $statement->execute();
247
248
        // Return count of affected rows
249
        return $statement->rowCount();
250
    }
251
252
    /**
253
     * Clean table function
254
     *
255
     * @return mixed
256
     */
257
    public function truncate()
258
    {
259
        // Current table
260
        $table = $this->getConnection();
261
262
        // Exec the truncate command
263
        return $this->exec("TRUNCATE TABLE $table");
264
    }
265
}
266