|
@@ -1,4 +1,4 @@
|
1
|
|
-<?
|
|
1
|
+<?php
|
2
|
2
|
//-----------------------------------------------------------------------------------
|
3
|
3
|
/////////////////////////////////////////////////////////////////////////////////////
|
4
|
4
|
/*//-- MySQL wrapper class ----------------------------------------------------------
|
|
@@ -116,333 +116,358 @@ set_query_id($ResultSet)
|
116
|
116
|
*///---------------------------------------------------------------------------------
|
117
|
117
|
|
118
|
118
|
if (!extension_loaded('mysqli')) {
|
119
|
|
- die('Mysqli Extension not loaded.');
|
|
119
|
+ die('Mysqli Extension not loaded.');
|
120
|
120
|
}
|
121
|
121
|
|
122
|
122
|
//Handles escaping
|
123
|
|
-function db_string($String, $DisableWildcards = false) {
|
124
|
|
- global $DB;
|
125
|
|
- //Escape
|
126
|
|
- $String = $DB->escape_str($String);
|
127
|
|
- //Remove user input wildcards
|
128
|
|
- if ($DisableWildcards) {
|
129
|
|
- $String = str_replace(array('%','_'), array('\%','\_'), $String);
|
130
|
|
- }
|
131
|
|
- return $String;
|
|
123
|
+function db_string($String, $DisableWildcards = false)
|
|
124
|
+{
|
|
125
|
+ global $DB;
|
|
126
|
+ //Escape
|
|
127
|
+ $String = $DB->escape_str($String);
|
|
128
|
+ //Remove user input wildcards
|
|
129
|
+ if ($DisableWildcards) {
|
|
130
|
+ $String = str_replace(array('%','_'), array('\%','\_'), $String);
|
|
131
|
+ }
|
|
132
|
+ return $String;
|
132
|
133
|
}
|
133
|
134
|
|
134
|
|
-function db_array($Array, $DontEscape = [], $Quote = false) {
|
135
|
|
- foreach ($Array as $Key => $Val) {
|
136
|
|
- if (!in_array($Key, $DontEscape)) {
|
137
|
|
- if ($Quote) {
|
138
|
|
- $Array[$Key] = '\''.db_string(trim($Val)).'\'';
|
139
|
|
- } else {
|
140
|
|
- $Array[$Key] = db_string(trim($Val));
|
141
|
|
- }
|
|
135
|
+function db_array($Array, $DontEscape = [], $Quote = false)
|
|
136
|
+{
|
|
137
|
+ foreach ($Array as $Key => $Val) {
|
|
138
|
+ if (!in_array($Key, $DontEscape)) {
|
|
139
|
+ if ($Quote) {
|
|
140
|
+ $Array[$Key] = '\''.db_string(trim($Val)).'\'';
|
|
141
|
+ } else {
|
|
142
|
+ $Array[$Key] = db_string(trim($Val));
|
|
143
|
+ }
|
|
144
|
+ }
|
142
|
145
|
}
|
143
|
|
- }
|
144
|
|
- return $Array;
|
|
146
|
+ return $Array;
|
145
|
147
|
}
|
146
|
148
|
|
147
|
149
|
//TODO: revisit access levels once Drone is replaced by ZeRobot
|
148
|
|
-class DB_MYSQL {
|
149
|
|
- public $LinkID = false;
|
150
|
|
- protected $QueryID = false;
|
151
|
|
- protected $StatementID = false;
|
152
|
|
- protected $PreparedQuery = false;
|
153
|
|
- protected $Record = [];
|
154
|
|
- protected $Row;
|
155
|
|
- protected $Errno = 0;
|
156
|
|
- protected $Error = '';
|
157
|
|
-
|
158
|
|
- public $Queries = [];
|
159
|
|
- public $Time = 0.0;
|
160
|
|
-
|
161
|
|
- protected $Database = '';
|
162
|
|
- protected $Server = '';
|
163
|
|
- protected $User = '';
|
164
|
|
- protected $Pass = '';
|
165
|
|
- protected $Port = 0;
|
166
|
|
- protected $Socket = '';
|
167
|
|
-
|
168
|
|
- function __construct($Database = SQLDB, $User = SQLLOGIN, $Pass = SQLPASS, $Server = SQLHOST, $Port = SQLPORT, $Socket = SQLSOCK) {
|
169
|
|
- $this->Database = $Database;
|
170
|
|
- $this->Server = $Server;
|
171
|
|
- $this->User = $User;
|
172
|
|
- $this->Pass = $Pass;
|
173
|
|
- $this->Port = $Port;
|
174
|
|
- $this->Socket = $Socket;
|
175
|
|
- }
|
176
|
|
-
|
177
|
|
- function halt($Msg) {
|
178
|
|
- global $Debug, $argv;
|
179
|
|
- $DBError = 'MySQL: '.strval($Msg).' SQL error: '.strval($this->Errno).' ('.strval($this->Error).')';
|
180
|
|
- if ($this->Errno == 1194) {
|
181
|
|
- send_irc('PRIVMSG '.ADMIN_CHAN.' :'.$this->Error);
|
|
150
|
+class DB_MYSQL
|
|
151
|
+{
|
|
152
|
+ public $LinkID = false;
|
|
153
|
+ protected $QueryID = false;
|
|
154
|
+ protected $StatementID = false;
|
|
155
|
+ protected $PreparedQuery = false;
|
|
156
|
+ protected $Record = [];
|
|
157
|
+ protected $Row;
|
|
158
|
+ protected $Errno = 0;
|
|
159
|
+ protected $Error = '';
|
|
160
|
+
|
|
161
|
+ public $Queries = [];
|
|
162
|
+ public $Time = 0.0;
|
|
163
|
+
|
|
164
|
+ protected $Database = '';
|
|
165
|
+ protected $Server = '';
|
|
166
|
+ protected $User = '';
|
|
167
|
+ protected $Pass = '';
|
|
168
|
+ protected $Port = 0;
|
|
169
|
+ protected $Socket = '';
|
|
170
|
+
|
|
171
|
+ public function __construct($Database = SQLDB, $User = SQLLOGIN, $Pass = SQLPASS, $Server = SQLHOST, $Port = SQLPORT, $Socket = SQLSOCK)
|
|
172
|
+ {
|
|
173
|
+ $this->Database = $Database;
|
|
174
|
+ $this->Server = $Server;
|
|
175
|
+ $this->User = $User;
|
|
176
|
+ $this->Pass = $Pass;
|
|
177
|
+ $this->Port = $Port;
|
|
178
|
+ $this->Socket = $Socket;
|
182
|
179
|
}
|
183
|
|
- $Debug->analysis('!dev DB Error', $DBError, 3600 * 24);
|
184
|
|
- if (DEBUG_MODE || check_perms('site_debug') || isset($argv[1])) {
|
185
|
|
- echo '<pre>'.display_str($DBError).'</pre>';
|
186
|
|
- if (DEBUG_MODE || check_perms('site_debug')) {
|
187
|
|
- print_r($this->Queries);
|
188
|
|
- }
|
189
|
|
- die();
|
190
|
|
- } else {
|
191
|
|
- error('-1');
|
|
180
|
+
|
|
181
|
+ public function halt($Msg)
|
|
182
|
+ {
|
|
183
|
+ global $Debug, $argv;
|
|
184
|
+ $DBError = 'MySQL: '.strval($Msg).' SQL error: '.strval($this->Errno).' ('.strval($this->Error).')';
|
|
185
|
+ if ($this->Errno == 1194) {
|
|
186
|
+ send_irc('PRIVMSG '.ADMIN_CHAN.' :'.$this->Error);
|
|
187
|
+ }
|
|
188
|
+ $Debug->analysis('!dev DB Error', $DBError, 3600 * 24);
|
|
189
|
+ if (DEBUG_MODE || check_perms('site_debug') || isset($argv[1])) {
|
|
190
|
+ echo '<pre>'.display_str($DBError).'</pre>';
|
|
191
|
+ if (DEBUG_MODE || check_perms('site_debug')) {
|
|
192
|
+ print_r($this->Queries);
|
|
193
|
+ }
|
|
194
|
+ die();
|
|
195
|
+ } else {
|
|
196
|
+ error('-1');
|
|
197
|
+ }
|
192
|
198
|
}
|
193
|
|
- }
|
194
|
|
-
|
195
|
|
- function connect() {
|
196
|
|
- if (!$this->LinkID) {
|
197
|
|
- $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); // defined in config.php
|
198
|
|
- if (!$this->LinkID) {
|
199
|
|
- $this->Errno = mysqli_connect_errno();
|
200
|
|
- $this->Error = mysqli_connect_error();
|
201
|
|
- $this->halt('Connection failed (host:'.$this->Server.':'.$this->Port.')');
|
202
|
|
- }
|
|
199
|
+
|
|
200
|
+ public function connect()
|
|
201
|
+ {
|
|
202
|
+ if (!$this->LinkID) {
|
|
203
|
+ $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); // defined in config.php
|
|
204
|
+ if (!$this->LinkID) {
|
|
205
|
+ $this->Errno = mysqli_connect_errno();
|
|
206
|
+ $this->Error = mysqli_connect_error();
|
|
207
|
+ $this->halt('Connection failed (host:'.$this->Server.':'.$this->Port.')');
|
|
208
|
+ }
|
|
209
|
+ }
|
|
210
|
+ mysqli_set_charset($this->LinkID, "utf8mb4");
|
203
|
211
|
}
|
204
|
|
- mysqli_set_charset($this->LinkID, "utf8mb4");
|
205
|
|
- }
|
206
|
|
-
|
207
|
|
- function prepare_query($Query, &...$BindVars) {
|
208
|
|
- $this->connect();
|
209
|
|
-
|
210
|
|
- $this->StatementID = mysqli_prepare($this->LinkID, $Query);
|
211
|
|
- if (!empty($BindVars)) {
|
212
|
|
- $Types = '';
|
213
|
|
- $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
|
214
|
|
- foreach ($BindVars as $BindVar) {
|
215
|
|
- $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
|
216
|
|
- }
|
217
|
|
- mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
|
|
212
|
+
|
|
213
|
+ public function prepare_query($Query, &...$BindVars)
|
|
214
|
+ {
|
|
215
|
+ $this->connect();
|
|
216
|
+
|
|
217
|
+ $this->StatementID = mysqli_prepare($this->LinkID, $Query);
|
|
218
|
+ if (!empty($BindVars)) {
|
|
219
|
+ $Types = '';
|
|
220
|
+ $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
|
|
221
|
+ foreach ($BindVars as $BindVar) {
|
|
222
|
+ $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
|
|
223
|
+ }
|
|
224
|
+ mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
|
|
225
|
+ }
|
|
226
|
+ $this->PreparedQuery = $Query;
|
|
227
|
+ return $this->StatementID;
|
218
|
228
|
}
|
219
|
|
- $this->PreparedQuery = $Query;
|
220
|
|
- return $this->StatementID;
|
221
|
|
- }
|
222
|
|
-
|
223
|
|
- function exec_prepared_query() {
|
224
|
|
- $QueryStartTime = microtime(true);
|
225
|
|
- mysqli_stmt_execute($this->StatementID);
|
226
|
|
- $this->QueryID = mysqli_stmt_get_result($this->StatementID);
|
227
|
|
- $QueryRunTime = (microtime(true) - $QueryStartTime) * 1000;
|
228
|
|
- $this->Queries[] = [$this->PreppedQuery, $QueryRunTime, null];
|
229
|
|
- $this->Time += $QueryRunTime;
|
230
|
|
- }
|
231
|
|
-
|
232
|
|
- function query($Query, &...$BindVars) {
|
233
|
|
- global $Debug;
|
234
|
|
- /*
|
235
|
|
- * If there was a previous query, we store the warnings. We cannot do
|
236
|
|
- * this immediately after mysqli_query because mysqli_insert_id will
|
237
|
|
- * break otherwise due to mysqli_get_warnings sending a SHOW WARNINGS;
|
238
|
|
- * query. When sending a query, however, we're sure that we won't call
|
239
|
|
- * mysqli_insert_id (or any similar function, for that matter) later on,
|
240
|
|
- * so we can safely get the warnings without breaking things.
|
241
|
|
- * Note that this means that we have to call $this->warnings manually
|
242
|
|
- * for the last query!
|
243
|
|
- */
|
244
|
|
- if ($this->QueryID) {
|
245
|
|
- $this->warnings();
|
|
229
|
+
|
|
230
|
+ public function exec_prepared_query()
|
|
231
|
+ {
|
|
232
|
+ $QueryStartTime = microtime(true);
|
|
233
|
+ mysqli_stmt_execute($this->StatementID);
|
|
234
|
+ $this->QueryID = mysqli_stmt_get_result($this->StatementID);
|
|
235
|
+ $QueryRunTime = (microtime(true) - $QueryStartTime) * 1000;
|
|
236
|
+ $this->Queries[] = [$this->PreppedQuery, $QueryRunTime, null];
|
|
237
|
+ $this->Time += $QueryRunTime;
|
246
|
238
|
}
|
247
|
|
- $QueryStartTime = microtime(true);
|
248
|
|
- $this->connect();
|
249
|
|
-
|
250
|
|
- // In the event of a MySQL deadlock, we sleep allowing MySQL time to unlock, then attempt again for a maximum of 5 tries
|
251
|
|
- for ($i = 1; $i < 6; $i++) {
|
252
|
|
- $this->StatementID = mysqli_prepare($this->LinkID, $Query);
|
253
|
|
- if (!empty($BindVars)) {
|
254
|
|
- $Types = '';
|
255
|
|
- $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
|
256
|
|
- foreach ($BindVars as $BindVar) {
|
257
|
|
- $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
|
|
239
|
+
|
|
240
|
+ public function query($Query, &...$BindVars)
|
|
241
|
+ {
|
|
242
|
+ global $Debug;
|
|
243
|
+ /*
|
|
244
|
+ * If there was a previous query, we store the warnings. We cannot do
|
|
245
|
+ * this immediately after mysqli_query because mysqli_insert_id will
|
|
246
|
+ * break otherwise due to mysqli_get_warnings sending a SHOW WARNINGS;
|
|
247
|
+ * query. When sending a query, however, we're sure that we won't call
|
|
248
|
+ * mysqli_insert_id (or any similar function, for that matter) later on,
|
|
249
|
+ * so we can safely get the warnings without breaking things.
|
|
250
|
+ * Note that this means that we have to call $this->warnings manually
|
|
251
|
+ * for the last query!
|
|
252
|
+ */
|
|
253
|
+ if ($this->QueryID) {
|
|
254
|
+ $this->warnings();
|
258
|
255
|
}
|
259
|
|
- mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
|
260
|
|
- }
|
261
|
|
- mysqli_stmt_execute($this->StatementID);
|
262
|
|
- $this->QueryID = mysqli_stmt_get_result($this->StatementID);
|
263
|
|
-
|
264
|
|
- if (DEBUG_MODE) {
|
265
|
|
- // in DEBUG_MODE, return the full trace on a SQL error (super useful
|
266
|
|
- // for debugging). do not attempt to retry to query
|
267
|
|
- if (!$this->QueryID) {
|
268
|
|
- echo '<pre>' . mysqli_error($this->LinkID) . '<br><br>';
|
269
|
|
- debug_print_backtrace();
|
270
|
|
- echo '</pre>';
|
271
|
|
- die();
|
|
256
|
+ $QueryStartTime = microtime(true);
|
|
257
|
+ $this->connect();
|
|
258
|
+
|
|
259
|
+ // In the event of a MySQL deadlock, we sleep allowing MySQL time to unlock, then attempt again for a maximum of 5 tries
|
|
260
|
+ for ($i = 1; $i < 6; $i++) {
|
|
261
|
+ $this->StatementID = mysqli_prepare($this->LinkID, $Query);
|
|
262
|
+ if (!empty($BindVars)) {
|
|
263
|
+ $Types = '';
|
|
264
|
+ $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
|
|
265
|
+ foreach ($BindVars as $BindVar) {
|
|
266
|
+ $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
|
|
267
|
+ }
|
|
268
|
+ mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
|
|
269
|
+ }
|
|
270
|
+ mysqli_stmt_execute($this->StatementID);
|
|
271
|
+ $this->QueryID = mysqli_stmt_get_result($this->StatementID);
|
|
272
|
+
|
|
273
|
+ if (DEBUG_MODE) {
|
|
274
|
+ // in DEBUG_MODE, return the full trace on a SQL error (super useful
|
|
275
|
+ // for debugging). do not attempt to retry to query
|
|
276
|
+ if (!$this->QueryID) {
|
|
277
|
+ echo '<pre>' . mysqli_error($this->LinkID) . '<br><br>';
|
|
278
|
+ debug_print_backtrace();
|
|
279
|
+ echo '</pre>';
|
|
280
|
+ die();
|
|
281
|
+ }
|
|
282
|
+ }
|
|
283
|
+
|
|
284
|
+ if (!in_array(mysqli_errno($this->LinkID), array(1213, 1205))) {
|
|
285
|
+ break;
|
|
286
|
+ }
|
|
287
|
+ $Debug->analysis('Non-Fatal Deadlock:', $Query, 3600 * 24);
|
|
288
|
+ trigger_error("Database deadlock, attempt $i");
|
|
289
|
+
|
|
290
|
+ sleep($i * rand(2, 5)); // Wait longer as attempts increase
|
272
|
291
|
}
|
273
|
|
- }
|
274
|
292
|
|
275
|
|
- if (!in_array(mysqli_errno($this->LinkID), array(1213, 1205))) {
|
276
|
|
- break;
|
277
|
|
- }
|
278
|
|
- $Debug->analysis('Non-Fatal Deadlock:', $Query, 3600 * 24);
|
279
|
|
- trigger_error("Database deadlock, attempt $i");
|
|
293
|
+ $QueryEndTime = microtime(true);
|
|
294
|
+ $this->Queries[] = array($Query, ($QueryEndTime - $QueryStartTime) * 1000, null);
|
|
295
|
+ $this->Time += ($QueryEndTime - $QueryStartTime) * 1000;
|
|
296
|
+
|
|
297
|
+ if (!$this->QueryID && !$this->StatementID) {
|
|
298
|
+ $this->Errno = mysqli_errno($this->LinkID);
|
|
299
|
+ $this->Error = mysqli_error($this->LinkID);
|
|
300
|
+ $this->halt("Invalid Query: $Query");
|
|
301
|
+ }
|
280
|
302
|
|
281
|
|
- sleep($i * rand(2, 5)); // Wait longer as attempts increase
|
|
303
|
+ $this->Row = 0;
|
|
304
|
+ return $this->QueryID;
|
282
|
305
|
}
|
283
|
306
|
|
284
|
|
- $QueryEndTime = microtime(true);
|
285
|
|
- $this->Queries[] = array($Query, ($QueryEndTime - $QueryStartTime) * 1000, null);
|
286
|
|
- $this->Time += ($QueryEndTime - $QueryStartTime) * 1000;
|
|
307
|
+ public function query_unb($Query)
|
|
308
|
+ {
|
|
309
|
+ $this->connect();
|
|
310
|
+ mysqli_real_query($this->LinkID, $Query);
|
|
311
|
+ }
|
287
|
312
|
|
288
|
|
- if (!$this->QueryID && !$this->StatementID) {
|
289
|
|
- $this->Errno = mysqli_errno($this->LinkID);
|
290
|
|
- $this->Error = mysqli_error($this->LinkID);
|
291
|
|
- $this->halt("Invalid Query: $Query");
|
|
313
|
+ public function inserted_id()
|
|
314
|
+ {
|
|
315
|
+ if ($this->LinkID) {
|
|
316
|
+ return mysqli_insert_id($this->LinkID);
|
|
317
|
+ }
|
292
|
318
|
}
|
293
|
319
|
|
294
|
|
- $this->Row = 0;
|
295
|
|
- return $this->QueryID;
|
296
|
|
- }
|
|
320
|
+ public function next_record($Type = MYSQLI_BOTH, $Escape = true)
|
|
321
|
+ {
|
|
322
|
+ // $Escape can be true, false, or an array of keys to not escape
|
|
323
|
+ if ($this->LinkID) {
|
|
324
|
+ $this->Record = mysqli_fetch_array($this->QueryID, $Type);
|
|
325
|
+ $this->Row++;
|
|
326
|
+ if (!is_array($this->Record)) {
|
|
327
|
+ $this->QueryID = false;
|
|
328
|
+ } elseif ($Escape !== false) {
|
|
329
|
+ $this->Record = Misc::display_array($this->Record, $Escape);
|
|
330
|
+ }
|
|
331
|
+ return $this->Record;
|
|
332
|
+ }
|
|
333
|
+ }
|
297
|
334
|
|
298
|
|
- function query_unb($Query) {
|
299
|
|
- $this->connect();
|
300
|
|
- mysqli_real_query($this->LinkID, $Query);
|
301
|
|
- }
|
|
335
|
+ public function close()
|
|
336
|
+ {
|
|
337
|
+ if ($this->LinkID) {
|
|
338
|
+ if (!mysqli_close($this->LinkID)) {
|
|
339
|
+ $this->halt('Cannot close connection or connection did not open.');
|
|
340
|
+ }
|
|
341
|
+ $this->LinkID = false;
|
|
342
|
+ }
|
|
343
|
+ }
|
302
|
344
|
|
303
|
|
- function inserted_id() {
|
304
|
|
- if ($this->LinkID) {
|
305
|
|
- return mysqli_insert_id($this->LinkID);
|
|
345
|
+ /*
|
|
346
|
+ * returns an integer with the number of rows found
|
|
347
|
+ * returns a string if the number of rows found exceeds MAXINT
|
|
348
|
+ */
|
|
349
|
+ public function record_count()
|
|
350
|
+ {
|
|
351
|
+ if ($this->QueryID) {
|
|
352
|
+ return mysqli_num_rows($this->QueryID);
|
|
353
|
+ }
|
306
|
354
|
}
|
307
|
|
- }
|
308
|
|
-
|
309
|
|
- function next_record($Type = MYSQLI_BOTH, $Escape = true) { // $Escape can be true, false, or an array of keys to not escape
|
310
|
|
- if ($this->LinkID) {
|
311
|
|
- $this->Record = mysqli_fetch_array($this->QueryID, $Type);
|
312
|
|
- $this->Row++;
|
313
|
|
- if (!is_array($this->Record)) {
|
314
|
|
- $this->QueryID = false;
|
315
|
|
- } elseif ($Escape !== false) {
|
316
|
|
- $this->Record = Misc::display_array($this->Record, $Escape);
|
317
|
|
- }
|
318
|
|
- return $this->Record;
|
|
355
|
+
|
|
356
|
+ /*
|
|
357
|
+ * returns true if the query exists and there were records found
|
|
358
|
+ * returns false if the query does not exist or if there were 0 records returned
|
|
359
|
+ */
|
|
360
|
+ public function has_results()
|
|
361
|
+ {
|
|
362
|
+ return ($this->QueryID && $this->record_count() !== 0);
|
319
|
363
|
}
|
320
|
|
- }
|
321
|
|
-
|
322
|
|
- function close() {
|
323
|
|
- if ($this->LinkID) {
|
324
|
|
- if (!mysqli_close($this->LinkID)) {
|
325
|
|
- $this->halt('Cannot close connection or connection did not open.');
|
326
|
|
- }
|
327
|
|
- $this->LinkID = false;
|
|
364
|
+
|
|
365
|
+ public function affected_rows()
|
|
366
|
+ {
|
|
367
|
+ if ($this->LinkID) {
|
|
368
|
+ return mysqli_affected_rows($this->LinkID);
|
|
369
|
+ }
|
|
370
|
+ }
|
|
371
|
+
|
|
372
|
+ public function info()
|
|
373
|
+ {
|
|
374
|
+ return mysqli_get_host_info($this->LinkID);
|
|
375
|
+ }
|
|
376
|
+
|
|
377
|
+ // You should use db_string() instead.
|
|
378
|
+ public function escape_str($Str)
|
|
379
|
+ {
|
|
380
|
+ $this->connect(0);
|
|
381
|
+ if (is_array($Str)) {
|
|
382
|
+ trigger_error('Attempted to escape array.');
|
|
383
|
+ return '';
|
|
384
|
+ }
|
|
385
|
+ return mysqli_real_escape_string($this->LinkID, $Str);
|
328
|
386
|
}
|
329
|
|
- }
|
330
|
|
-
|
331
|
|
- /*
|
332
|
|
- * returns an integer with the number of rows found
|
333
|
|
- * returns a string if the number of rows found exceeds MAXINT
|
334
|
|
- */
|
335
|
|
- function record_count() {
|
336
|
|
- if ($this->QueryID) {
|
337
|
|
- return mysqli_num_rows($this->QueryID);
|
|
387
|
+
|
|
388
|
+ // Creates an array from a result set
|
|
389
|
+ // If $Key is set, use the $Key column in the result set as the array key
|
|
390
|
+ // Otherwise, use an integer
|
|
391
|
+ public function to_array($Key = false, $Type = MYSQLI_BOTH, $Escape = true)
|
|
392
|
+ {
|
|
393
|
+ $Return = [];
|
|
394
|
+ while ($Row = mysqli_fetch_array($this->QueryID, $Type)) {
|
|
395
|
+ if ($Escape !== false) {
|
|
396
|
+ $Row = Misc::display_array($Row, $Escape);
|
|
397
|
+ }
|
|
398
|
+ if ($Key !== false) {
|
|
399
|
+ $Return[$Row[$Key]] = $Row;
|
|
400
|
+ } else {
|
|
401
|
+ $Return[] = $Row;
|
|
402
|
+ }
|
|
403
|
+ }
|
|
404
|
+ mysqli_data_seek($this->QueryID, 0);
|
|
405
|
+ return $Return;
|
338
|
406
|
}
|
339
|
|
- }
|
340
|
|
-
|
341
|
|
- /*
|
342
|
|
- * returns true if the query exists and there were records found
|
343
|
|
- * returns false if the query does not exist or if there were 0 records returned
|
344
|
|
- */
|
345
|
|
- function has_results() {
|
346
|
|
- return ($this->QueryID && $this->record_count() !== 0);
|
347
|
|
- }
|
348
|
|
-
|
349
|
|
- function affected_rows() {
|
350
|
|
- if ($this->LinkID) {
|
351
|
|
- return mysqli_affected_rows($this->LinkID);
|
|
407
|
+
|
|
408
|
+ // Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
|
|
409
|
+ public function to_pair($KeyField, $ValField, $Escape = true)
|
|
410
|
+ {
|
|
411
|
+ $Return = [];
|
|
412
|
+ while ($Row = mysqli_fetch_array($this->QueryID)) {
|
|
413
|
+ if ($Escape) {
|
|
414
|
+ $Key = display_str($Row[$KeyField]);
|
|
415
|
+ $Val = display_str($Row[$ValField]);
|
|
416
|
+ } else {
|
|
417
|
+ $Key = $Row[$KeyField];
|
|
418
|
+ $Val = $Row[$ValField];
|
|
419
|
+ }
|
|
420
|
+ $Return[$Key] = $Val;
|
|
421
|
+ }
|
|
422
|
+ mysqli_data_seek($this->QueryID, 0);
|
|
423
|
+ return $Return;
|
352
|
424
|
}
|
353
|
|
- }
|
354
|
|
-
|
355
|
|
- function info() {
|
356
|
|
- return mysqli_get_host_info($this->LinkID);
|
357
|
|
- }
|
358
|
|
-
|
359
|
|
- // You should use db_string() instead.
|
360
|
|
- function escape_str($Str) {
|
361
|
|
- $this->connect(0);
|
362
|
|
- if (is_array($Str)) {
|
363
|
|
- trigger_error('Attempted to escape array.');
|
364
|
|
- return '';
|
|
425
|
+
|
|
426
|
+ // Loops through the result set, collecting the $Key column into an array
|
|
427
|
+ public function collect($Key, $Escape = true)
|
|
428
|
+ {
|
|
429
|
+ $Return = [];
|
|
430
|
+ while ($Row = mysqli_fetch_array($this->QueryID)) {
|
|
431
|
+ $Return[] = $Escape ? display_str($Row[$Key]) : $Row[$Key];
|
|
432
|
+ }
|
|
433
|
+ mysqli_data_seek($this->QueryID, 0);
|
|
434
|
+ return $Return;
|
365
|
435
|
}
|
366
|
|
- return mysqli_real_escape_string($this->LinkID, $Str);
|
367
|
|
- }
|
368
|
|
-
|
369
|
|
- // Creates an array from a result set
|
370
|
|
- // If $Key is set, use the $Key column in the result set as the array key
|
371
|
|
- // Otherwise, use an integer
|
372
|
|
- function to_array($Key = false, $Type = MYSQLI_BOTH, $Escape = true) {
|
373
|
|
- $Return = [];
|
374
|
|
- while ($Row = mysqli_fetch_array($this->QueryID, $Type)) {
|
375
|
|
- if ($Escape !== false) {
|
376
|
|
- $Row = Misc::display_array($Row, $Escape);
|
377
|
|
- }
|
378
|
|
- if ($Key !== false) {
|
379
|
|
- $Return[$Row[$Key]] = $Row;
|
380
|
|
- } else {
|
381
|
|
- $Return[] = $Row;
|
382
|
|
- }
|
|
436
|
+
|
|
437
|
+ public function set_query_id(&$ResultSet)
|
|
438
|
+ {
|
|
439
|
+ $this->QueryID = $ResultSet;
|
|
440
|
+ $this->Row = 0;
|
383
|
441
|
}
|
384
|
|
- mysqli_data_seek($this->QueryID, 0);
|
385
|
|
- return $Return;
|
386
|
|
- }
|
387
|
|
-
|
388
|
|
- // Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
|
389
|
|
- function to_pair($KeyField, $ValField, $Escape = true) {
|
390
|
|
- $Return = [];
|
391
|
|
- while ($Row = mysqli_fetch_array($this->QueryID)) {
|
392
|
|
- if ($Escape) {
|
393
|
|
- $Key = display_str($Row[$KeyField]);
|
394
|
|
- $Val = display_str($Row[$ValField]);
|
395
|
|
- } else {
|
396
|
|
- $Key = $Row[$KeyField];
|
397
|
|
- $Val = $Row[$ValField];
|
398
|
|
- }
|
399
|
|
- $Return[$Key] = $Val;
|
|
442
|
+
|
|
443
|
+ public function get_query_id()
|
|
444
|
+ {
|
|
445
|
+ return $this->QueryID;
|
400
|
446
|
}
|
401
|
|
- mysqli_data_seek($this->QueryID, 0);
|
402
|
|
- return $Return;
|
403
|
|
- }
|
404
|
|
-
|
405
|
|
- // Loops through the result set, collecting the $Key column into an array
|
406
|
|
- function collect($Key, $Escape = true) {
|
407
|
|
- $Return = [];
|
408
|
|
- while ($Row = mysqli_fetch_array($this->QueryID)) {
|
409
|
|
- $Return[] = $Escape ? display_str($Row[$Key]) : $Row[$Key];
|
|
447
|
+
|
|
448
|
+ public function beginning()
|
|
449
|
+ {
|
|
450
|
+ mysqli_data_seek($this->QueryID, 0);
|
|
451
|
+ $this->Row = 0;
|
410
|
452
|
}
|
411
|
|
- mysqli_data_seek($this->QueryID, 0);
|
412
|
|
- return $Return;
|
413
|
|
- }
|
414
|
|
-
|
415
|
|
- function set_query_id(&$ResultSet) {
|
416
|
|
- $this->QueryID = $ResultSet;
|
417
|
|
- $this->Row = 0;
|
418
|
|
- }
|
419
|
|
-
|
420
|
|
- function get_query_id() {
|
421
|
|
- return $this->QueryID;
|
422
|
|
- }
|
423
|
|
-
|
424
|
|
- function beginning() {
|
425
|
|
- mysqli_data_seek($this->QueryID, 0);
|
426
|
|
- $this->Row = 0;
|
427
|
|
- }
|
428
|
|
-
|
429
|
|
- /**
|
430
|
|
- * This function determines whether the last query caused warning messages
|
431
|
|
- * and stores them in $this->Queries.
|
432
|
|
- */
|
433
|
|
- function warnings() {
|
434
|
|
- $Warnings = [];
|
435
|
|
- if (!is_bool($this->LinkID) && mysqli_warning_count($this->LinkID)) {
|
436
|
|
- $e = mysqli_get_warnings($this->LinkID);
|
437
|
|
- do {
|
438
|
|
- if ($e->errno == 1592) {
|
439
|
|
- // 1592: Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.
|
440
|
|
- continue;
|
|
453
|
+
|
|
454
|
+ /**
|
|
455
|
+ * This function determines whether the last query caused warning messages
|
|
456
|
+ * and stores them in $this->Queries.
|
|
457
|
+ */
|
|
458
|
+ public function warnings()
|
|
459
|
+ {
|
|
460
|
+ $Warnings = [];
|
|
461
|
+ if (!is_bool($this->LinkID) && mysqli_warning_count($this->LinkID)) {
|
|
462
|
+ $e = mysqli_get_warnings($this->LinkID);
|
|
463
|
+ do {
|
|
464
|
+ if ($e->errno == 1592) {
|
|
465
|
+ // 1592: Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.
|
|
466
|
+ continue;
|
|
467
|
+ }
|
|
468
|
+ $Warnings[] = 'Code ' . $e->errno . ': ' . display_str($e->message);
|
|
469
|
+ } while ($e->next());
|
441
|
470
|
}
|
442
|
|
- $Warnings[] = 'Code ' . $e->errno . ': ' . display_str($e->message);
|
443
|
|
- } while ($e->next());
|
|
471
|
+ $this->Queries[count($this->Queries) - 1][2] = $Warnings;
|
444
|
472
|
}
|
445
|
|
- $this->Queries[count($this->Queries) - 1][2] = $Warnings;
|
446
|
|
- }
|
447
|
473
|
}
|
448
|
|
-?>
|