-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.php
243 lines (220 loc) · 7.13 KB
/
db.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
<?php
/**
* DB - A PDO Wrapper
* Intended to be called once, set up the PDO connection, and handle common
* @uses
* $db = new db();
* @author Nick Wright
*
*/
class db {
public
$pdo;
/**
* DB expects several constants to be set:
* DB_HOST
* DB_PORT
* DB_SCHEMA
* DB_USERNAME
* DB_PASSWORD
*/
public function __construct() {
try {
$this->pdo = new PDO('mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_SCHEMA, DB_USERNAME, DB_PASSWORD);
@$this->pdo->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
echo $e->getMessage();
}
}
/**
* Update
* Take data, parse it, then build and execute an UPDATE command
* @param string $table >> The name of the table
* @param array $set >> An assoc array of field=>values.
* Fields will be tick'd (`field`), and values will be "prepared".
* @param array $where >> An assoc array to build the where statement.
* They will be joined with "AND".
* @param array $rawFields >> To overwrite the "prepared values" functionality of $set, defined the "raw" fields.
* @param string $rawWhere >> If the where statement is more complicated than "AND", use this
*
* @uses: One - simple name change
* $db->update('users', array('name' => 'Nick'), array('id' => 7));
*
* SQL:
* UPDATE users SET `name` = :name WHERE id = :whereid;
* passing: array('name' => 'Nick', 'whereid' => 7).
* The where prepared items get prepended with text to prevent overlap.
* This prevents cases of UPDATE users SET `name` = :name WHERE `name` = :name;
* That would cause confusion and be unclear.
*
* This will update the users table: the field `name` changes 'Nick where the id is equal to 7.
* @uses: Two - complicated
* $db->update('users', array(
* 'name' => $name,
* 'counter' => 'counter + 1'
* ), array(
* 'id' => 7
* ), array(
* 'counter'
* ), 'OR id = 6');
*
* SQL:
* UPDATE users SET `name` = :name, `counter` = counter + 1 WHERE id = :whereid OR id = 6;
*
* This will update the users table, the field `name` will change. The counter will be incremented by one.
* We use PDO's prepared statement functionality, so to avoid being prepared, we place "counter" in the rawFields.
*
* @return nothing
*/
public function update($table, $set, $where, $rawFields = array(), $rawWhere = null) {
$setString = $whereString = '';
$values = $set;
foreach ($set as $k => $v) {
$setString .= '`' . $k . '` = ';
if (strtolower($v) == 'now()') $setString .= 'NOW()';
elseif (strtolower($v) == 'null') $setString .= 'NULL';
elseif (in_array($k, $rawFields)) $setString .= $v;
else $setString .= ':' . $k;
$setString .= ', ';
}
$setString = substr($setString, 0, -2);
foreach ($where as $k => $v) {
$whereString .= '`' . $k . '` = :where' . $k . ' AND ';
$values['where' . $k] = $v;
}
$whereString = substr($whereString, 0, -5);
if ($rawWhere)
$whereString .= ' ' . $rawWhere;
$sth = $this->pdo->prepare(
'UPDATE `' . $table . '` ' .
'SET ' . $setString . ' ' .
'WHERE ' . $whereString
);
$sth->execute($values);
}
/**
* Insert
* Take data, parse it, then build and execute an INSERT command
* @param string $table
* @param array $values >> An assoc array of field=>values
* @param array $rawFields >> @see UPDATE
* @param boolean $ignore >> A flag, if true, indicates "INSERT IGNORE"
*
* @see Update >> Please read the comments concerning the Update command.
* Many of it's core ideas about prepared statements hold true with Insert as well.
*
* @uses:
* $newId = $db->insert('users', array('name' => 'Nicholas', 'createdAt' => 'now()'));
* // assert($newId == 8)
*
* SQL:
* INSERT INTO users (name, createdAt) VALUES(:name, NOW());
* passing: array('name' => 'Nicholas')
*
* @return the last inserted id
*/
public function insert($table, $values, $rawFields = array(), $ignore = false) {
$fieldsString = $valuesString = '';
foreach ($values as $k => $v) {
$fieldsString .= '`' . $k . '`, ';
if (strtolower($v) == 'now()') $valuesString .= 'NOW()';
elseif (strtolower($v) == 'null') $valuesString .= 'NULL';
elseif (in_array($k, $rawFields)) $valuesString .= $v;
else $valuesString .= ':' . $k;
$valuesString .= ', ';
}
$fieldsString = substr($fieldsString, 0, -2);
$valuesString = substr($valuesString, 0, -2);
$sth = $this->pdo->prepare(
'INSERT ' . ($ignore ? 'IGNORE ' : '') . 'INTO `' . $table . '` ' .
'(' . $fieldsString . ') VALUES (' . $valuesString . ')'
);
$sth->execute($values);
return $this->pdo->lastInsertId();
}
/**
* Delete
*
* @param string $table
* @param array $where >> An assoc array detailing the matches
*
* @see Update >> Please read the comments concerning the Update command.
* How it handles $where is true for Delete as well.
*
* @uses
* $db->delete('users', array('id' => 7));
*
* SQL:
* DELETE FROM users WHERE id = 7;
*
* @return nothing
*/
public function delete($table, $where) {
$whereString = '';
foreach ($where as $k => $v)
$whereString .= '`' . $k . '` = :' . $k . ' AND ';
$whereString = substr($whereString, 0, -5);
$sth = $this->pdo->prepare(
'DELETE FROM `'. $table . '` ' .
'WHERE ' . $whereString
);
$sth->execute($where);
}
/**
* Query
* When you need to execute complicated SQL without expecting a result,
* and the ->update, ->insert and ->delete functions are not up to the task,
* use this function.
* @example `INSERT ... SELECT`, `INSERT ... (), (), ()`, `DELETE ... WHERE 1 OR (2 AND 3)`
*
* @param string $query >> the SQL you want executed. Build it as a prepared statement (with :variables)
* @param array $values >> Assoc array to use for the prepared statement
*
* @return nothing
*/
public function query($query, $values) {
$sth = $this->pdo->prepare($query);
$sth->execute($values);
}
/**
* Select
* Run a query and gather the results.
* @param string $query >> Use a prepared statement
* @param array $values
* @see Update or Insert for description on how this handles prepared values
* @return array >> Multi-tiered assoc array
*/
public function select($query, $values = array()) {
$sth = $this->pdo->prepare($query);
$sth->execute($values);
$sth->setFetchMode(PDO::FETCH_ASSOC);
return $sth->fetchAll();
}
/**
* Select First
* Runs the query, but only returns the first result.
* Also attempts to append query with "LIMIT 1" for simplicity.
* @see Select
* @param string $query
* @param array $values
* @return array >> Single-tiered assoc array
*/
public function select_first($query, $values = array()) {
if (!strstr($query, 'LIMIT'))
$query .= ' LIMIT 1';
$result = $this->select($query, $values);
return $result[0];
}
/**
* Fields
* Gather the column names that belong to the table.
* @param string $table
*/
public function fields($table) {
$sth = $this->pdo->prepare('DESCRIBE `' . $table . '`');
$sth->execute();
$sth->setFetchMode(PDO::FETCH_ASSOC);
return $sth->fetchAll(PDO::FETCH_COLUMN, 0);
}
}