Passed
Push — master ( 9548ef...30b30b )
by Mr
02:05
created

SQL::delete()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
c 0
b 0
f 0
rs 9.0856
cc 3
eloc 9
nc 4
nop 1
1
<?php
2
3
namespace DrMVC\Database\Drivers;
4
5
use DrMVC\Database\SQLException;
6
7
abstract class SQL extends Driver implements SQLInterface
8
{
9
    /**
10
     * Check if input value is integer
11
     *
12
     * @param   mixed $value
13
     * @return  int
14
     */
15
    private function isPdoInt($value): int
16
    {
17
        return \is_int($value) ? \PDO::PARAM_INT : \PDO::PARAM_STR;
18
    }
19
20
    /**
21
     * Initiate connection to database
22
     *
23
     * @return  DriverInterface
24
     */
25
    public function connect(): DriverInterface
26
    {
27
        try {
28
            $connection = new \PDO(
29
                $this->getDsn(),
30
                $this->getParam('username'),
31
                $this->getParam('password')
32
            );
33
            $this->setConnection($connection);
34
35
        } catch (SQLException $e) {
36
            // __construct
37
        }
38
39
        return $this;
40
    }
41
42
    /**
43
     * Generate basic select query
44
     *
45
     * @param   array $where
46
     * @return  string
47
     */
48
    private function getSelect(array $where): string
49
    {
50
        // Current table
51
        $table = $this->getCollection();
52
53
        // Generate where line
54
        $whereDetails = !empty($where)
55
            ? ' WHERE ' . $this->genWhere($where)
56
            : '';
57
58
        return "SELECT * FROM $table $whereDetails";
59
    }
60
61
    /**
62
     * Run a select statement against the database
63
     *
64
     * @param   array $where array with data for filtering
65
     * @return  mixed
66
     */
67
    public function select(array $where = [])
68
    {
69
        // Set statement
70
        $query = $this->getSelect($where);
71
        $statement = $this->getConnection()->prepare($query);
0 ignored issues
show
Bug introduced by
The method prepare() does not exist on MongoDB\Driver\Manager. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
        $statement = $this->getConnection()->/** @scrutinizer ignore-call */ prepare($query);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
72
73
        // Bind where values
74
        foreach ($where as $key => $value) {
75
            $statement->bindValue(":where_$key", $value, $this->isPdoInt($value));
76
        }
77
78
        // Execute operation
79
        $statement->execute();
80
81
        // Return object
82
        return $statement->fetchAll(\PDO::FETCH_OBJ);
83
    }
84
85
    /**
86
     * Execute raw query, without generation, useful for some advanced operations
87
     *
88
     * @param   array $arguments array of arguments
89
     * @return  mixed
90
     */
91
    public function rawSQL(array $arguments)
92
    {
93
        /*
94
         * @param string $query  pure sql query
95
         * @param  array $bind   array with values in [':key' => 'value'] format
96
         * @param   bool $fetch  make fetch and return data?
97
         */
98
        @list($query, $bind, $fetch) = $arguments;  // Notices disabled
99
100
        // Set statement
101
        $statement = $this->getConnection()->prepare($query);
102
103
        // Execute operation
104
        $statement->execute($bind);
105
106
        return (true === $fetch)
107
            // Return object
108
            ? $statement->fetchAll(\PDO::FETCH_OBJ)
109
            // Return count of affected rows
110
            : $statement->rowCount();
111
    }
112
113
    /**
114
     * Generate INSERT query by array
115
     *
116
     * @param   array $data
117
     * @return  string
118
     */
119
    private function genInsert(array $data): string
120
    {
121
        // Current table
122
        $table = $this->getCollection();
123
124
        // Generate array of fields for insert
125
        $fieldNames = implode(',', array_keys($data));
126
127
        // Generate line with data for update
128
        $fieldDetails = ':' . implode(', :', array_keys($data));
129
130
        return "INSERT INTO $table ($fieldNames) VALUES ($fieldDetails)";
131
    }
132
133
    /**
134
     * Insert in database and return of inserted element
135
     *
136
     * @param   array $data array of columns and values
137
     * @param   string $id field name of ID which must be returned
138
     * @return  mixed
139
     */
140
    public function insert(array $data, string $id = null)
141
    {
142
        // Prepare query
143
        $query = $this->genInsert($data);
144
        $statement = $this->getConnection()->prepare($query);
145
146
        // Bind values
147
        foreach ($data as $key => $value) {
148
            $statement->bindValue(":$key", $value, $this->isPdoInt($value));
149
        }
150
151
        // Execute operation
152
        $statement->execute();
153
154
        return (null !== $id)
155
            // Return ID of inserted element
156
            ? $this->getConnection()->lastInsertId($id)
0 ignored issues
show
Bug introduced by
The method lastInsertId() does not exist on MongoDB\Driver\Manager. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
            ? $this->getConnection()->/** @scrutinizer ignore-call */ lastInsertId($id)

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
157
            // Return count of affected rows
158
            : $statement->rowCount();
159
    }
160
161
    /**
162
     * Generate the line by provided keys
163
     *
164
     * @param   array $array array with data
165
     * @param   string $glue by this glue need merge items
166
     * @param   string $name name of field for PDO->bindValue
167
     * @return  string
168
     */
169
    private function genLine(array $array, string $glue, string $name): string
170
    {
171
        $line = '';
172
        $i = 0;
173
        foreach ($array as $key => $value) {
174
            $line .= (($i !== 0) ? null : $glue) . "$key = :${name}_$key";
175
            $i = 1;
176
        }
177
        return $line;
178
    }
179
180
    /**
181
     * Generate set of fields
182
     *
183
     * @param   array $array
184
     * @return  string
185
     */
186
    private function genFields(array $array): string
187
    {
188
        return $this->genLine($array, ', ', 'field');
189
    }
190
191
    /**
192
     * Generate WHERE line
193
     *
194
     * @param   array $array
195
     * @return  string
196
     */
197
    private function genWhere(array $array): string
198
    {
199
        return $this->genLine($array, ' AND ', 'where');
200
    }
201
202
    /**
203
     * Generate update query
204
     *
205
     * @param   array $data
206
     * @param   array $where
207
     * @return  string
208
     */
209
    private function genUpdate(array $data, array $where): string
210
    {
211
        // Current table
212
        $table = $this->getCollection();
213
214
        // Generate line with data for update
215
        $fieldDetails = !empty($data)
216
            ? $this->genFields($data)
217
            : '';
218
219
        // Generate where line
220
        $whereDetails = !empty($where)
221
            ? ' WHERE ' . $this->genWhere($where)
222
            : '';
223
224
        return "UPDATE $table SET $fieldDetails $whereDetails";
225
    }
226
227
    /**
228
     * Update method
229
     *
230
     * @param   array $data array of columns and values
231
     * @param   array $where array with data for filtering
232
     * @return  mixed
233
     */
234
    public function update(array $data, array $where = [])
235
    {
236
        // Prepare query
237
        $query = $this->genUpdate($data, $where);
238
        $statement = $this->getConnection()->prepare($query);
239
240
        // Bind field values
241
        foreach ($data as $key => $value) {
242
            $statement->bindValue(":field_$key", $value, $this->isPdoInt($value));
243
        }
244
245
        // Bind where values
246
        foreach ($where as $key => $value) {
247
            $statement->bindValue(":where_$key", $value, $this->isPdoInt($value));
248
        }
249
250
        // Execute operation
251
        $statement->execute();
252
253
        // Return count of affected rows
254
        return $statement->rowCount();
255
    }
256
257
    /**
258
     * Delete rows from database
259
     *
260
     * @param   array $where array with data for filtering
261
     * @return  mixed
262
     */
263
    public function delete(array $where)
264
    {
265
        // Current table
266
        $table = $this->getCollection();
267
268
        // Generate where line
269
        $whereDetails = !empty($where)
270
            ? ' WHERE ' . $this->genWhere($where)
271
            : '';
272
273
        // Prepare query
274
        $statement = $this->getConnection()->prepare("DELETE FROM $table $whereDetails");
275
276
        // Bind where values
277
        foreach ($where as $key => $value) {
278
            $statement->bindValue(":where_$key", $value, $this->isPdoInt($value));
279
        }
280
281
        // Execute operation
282
        $statement->execute();
283
284
        // Return count of affected rows
285
        return $statement->rowCount();
286
    }
287
288
    /**
289
     * Clean table function
290
     *
291
     * @return mixed
292
     */
293
    public function truncate()
294
    {
295
        // Current table
296
        $table = $this->getConnection();
297
298
        // Exec the truncate command
299
        return $this->rawSQL(["TRUNCATE TABLE $table"]);
300
    }
301
}
302