Completed
Push — master ( 539dc8...66ab79 )
by Mr
03:11
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
abstract class SQL extends Driver
6
{
7
    /**
8
     * Initiate connection to database
9
     *
10
     * @return  DriverInterface
11
     */
12
    public function connect(): DriverInterface
13
    {
14
        $connection = new \PDO($this->getDsn());
15
        $this->setConnection($connection);
16
        return $this;
17
    }
18
19
    /**
20
     * Close database connection
21
     *
22
     * @return  DriverInterface
23
     */
24
    public function disconnect(): DriverInterface
25
    {
26
        $this->setConnection(null);
27
        return $this;
28
    }
29
30
    /**
31
     * Run a select statement against the database
32
     *
33
     * @param   string $query
34
     * @param   array $data
35
     * @return  array|object
36
     */
37
    public function select(string $query, array $data = [])
38
    {
39
        // Set statement
40
        $statement = $this->_connection->prepare($query);
41
42
        // Parse parameters from array
43
        foreach ($data as $key => $value) {
44
            $value_type = \is_int($value) ? \PDO::PARAM_INT : \PDO::PARAM_STR;
45
            $statement->bindValue($key, $value, $value_type);
46
        }
47
48
        // Execute the statement
49
        $statement->execute();
50
51
        // Return result
52
        return $statement->fetchAll(\PDO::FETCH_OBJ);
53
    }
54
55
    /**
56
     * Exec query without return, create table for example
57
     *
58
     * @param   string $query
59
     * @return  mixed
60
     */
61
    public function exec(string $query)
62
    {
63
        return $this->_connection->exec($query);
64
    }
65
66
    /**
67
     * Insert in database and return of inserted element
68
     *
69
     * @param   array $data array of columns and values
70
     * @return  int
71
     */
72
    public function insert(array $data): int
73
    {
74
        // Current table
75
        $table = $this->getConnection();
76
77
        // Generate array of fields for insert
78
        $fieldNames = implode(',', array_keys($data));
79
80
        // Generate line with data for update
81
        $fieldDetails = !empty($data)
82
            ? $fieldDetails = $this->genFields($data)
0 ignored issues
show
Unused Code introduced by
The assignment to $fieldDetails is dead and can be removed.
Loading history...
83
            : '';
84
85
        // Prepare query
86
        $statement = $this->_connection->prepare("INSERT INTO $table ($fieldNames) VALUES ($fieldDetails)");
87
88
        // Bind field values
89
        foreach ($data as $key => $value) {
90
            $statement->bindValue(":field_$key", $value);
91
        }
92
93
        // Execute operation
94
        $statement->execute();
95
96
        // Return ID of inserted element
97
        return $this->_connection->lastInsertId();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_connection->lastInsertId() returns the type string which is incompatible with the type-hinted return integer.
Loading history...
98
        // TODO: Need to add ability to set the name of ID field (not only "id")
99
    }
100
101
    /**
102
     * Generate the line by provided keys
103
     *
104
     * @param   array $array array with data
105
     * @param   string $glue by this glue need merge items
106
     * @param   string $name name of field for PDO->bindValue
107
     * @return  string
108
     */
109
    private function genLine(array $array, string $glue, string $name): string
110
    {
111
        $line = '';
112
        $i = 0;
113
        foreach ($array as $key => $value) {
114
            $line .= (($i !== 0) ? null : $glue) . "$key = :${name}_$key";
115
            $i = 1;
116
        }
117
        return $line;
118
    }
119
120
    /**
121
     * Generate set of fields
122
     *
123
     * @param   array $array
124
     * @return  string
125
     */
126
    private function genFields(array $array): string
127
    {
128
        return $this->genLine($array, ', ', 'field');
129
    }
130
131
    /**
132
     * Generate WHERE line
133
     *
134
     * @param   array $array
135
     * @return  string
136
     */
137
    private function genWhere(array $array): string
138
    {
139
        return $this->genLine($array, ' AND ', 'where');
140
    }
141
142
    /**
143
     * Update method
144
     *
145
     * @param  array $data array of columns and values
146
     * @param  array $where array of columns and values
147
     * @return int
148
     */
149
    public function update(array $data, array $where): int
150
    {
151
        // Current table
152
        $table = $this->getConnection();
153
154
        // Generate line with data for update
155
        $fieldDetails = !empty($data)
156
            ? $fieldDetails = $this->genFields($data)
0 ignored issues
show
Unused Code introduced by
The assignment to $fieldDetails is dead and can be removed.
Loading history...
157
            : '';
158
159
        // Generate where line
160
        $whereDetails = !empty($where)
161
            ? ' WHERE ' . $this->genWhere($where)
162
            : '';
163
164
        // Prepare query
165
        $statement = $this->_connection->prepare("UPDATE $table SET $fieldDetails $whereDetails");
166
167
        // Bind field values
168
        foreach ($data as $key => $value) {
169
            $statement->bindValue(":field_$key", $value);
170
        }
171
172
        // Bind where values
173
        foreach ($where as $key => $value) {
174
            $statement->bindValue(":where_$key", $value);
175
        }
176
177
        // Execute operation
178
        $statement->execute();
179
180
        // Return count of affected rows
181
        return $statement->rowCount();
182
    }
183
184
    /**
185
     * Delete rows from database
186
     *
187
     * @param   array $where
188
     * @return  bool
189
     */
190
    public function delete(array $where): bool
191
    {
192
        // Current table
193
        $table = $this->getConnection();
194
195
        // Generate where line
196
        $whereDetails = !empty($where)
197
            ? ' WHERE ' . $this->genWhere($where)
198
            : '';
199
200
        // Prepare query
201
        $statement = $this->_connection->prepare("DELETE FROM $table $whereDetails");
202
203
        // Bind where values
204
        foreach ($where as $key => $value) {
205
            $statement->bindValue(":where_$key", $value);
206
        }
207
208
        // Execute operation
209
        $statement->execute();
210
211
        // Return count of affected rows
212
        return $statement->rowCount();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $statement->rowCount() returns the type integer which is incompatible with the type-hinted return boolean.
Loading history...
213
    }
214
215
    /**
216
     * Clean table function
217
     *
218
     * @return mixed
219
     */
220
    public function truncate()
221
    {
222
        // Current table
223
        $table = $this->getConnection();
224
225
        // Exec the truncate command
226
        return $this->exec("TRUNCATE TABLE $table");
227
    }
228
}
229