Test Failed
Push — master ( e9c576...010f10 )
by Joe
03:45
created

Db::createDatabase()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 15
nc 2
nop 2
dl 0
loc 19
ccs 0
cts 16
cp 0
crap 6
rs 9.7666
c 0
b 0
f 0
1
<?php
2
/**
3
 * PDO SQL Related Functionality
4
 * @author Joe Huss <[email protected]>
5
 * @copyright 2018
6
 * @package MyAdmin
7
 * @category SQL
8
 */
9
10
namespace MyDb\Pdo;
11
12
use \MyDb\Generic;
13
use \MyDb\Db_Interface;
14
15
/**
16
 * Db
17
 *
18
 * @access public
19
 */
20
class Db extends Generic implements Db_Interface {
21
	/* public: connection parameters */
22
	public $driver = 'mysql';
23
	public $Rows = [];
24
	/* public: this is an api revision, not a CVS revision. */
25
	public $type = 'pdo';
26
27
	/**
28
	 * alias function of select_db, changes the database we are working with.
29
	 *
30
	 * @param string $database the name of the database to use
31
	 * @return void
32
	 */
33
	public function useDb($database) {
34
		$this->selectDb($database);
35
	}
36
37
	/**
38
	 * changes the database we are working with.
39
	 *
40
	 * @param string $database the name of the database to use
41
	 * @return void
42
	 */
43
	public function selectDb($database) {
44
		$dSN = "{$this->driver}:dbname={$database};host={$this->host}";
45
		if ($this->characterSet != '')
46
			$dSN .= ';charset='.$this->characterSet;
47
		$this->linkId = new \PDO($dSN, $this->user, $this->password);
48
	}
49
50
	/* public: connection management */
51
52
	/**
53
	 * Db::connect()
54
	 * @param string $database
55
	 * @param string $host
56
	 * @param string $user
57
	 * @param string $password
58
	 * @param string $driver
59
	 * @return bool|int|\PDO
60
	 */
61
	public function connect($database = '', $host = '', $user = '', $password = '', $driver = 'mysql') {
62
		/* Handle defaults */
63
		if ('' == $database)
64
			$database = $this->database;
65
		if ('' == $host)
66
			$host = $this->host;
67
		if ('' == $user)
68
			$user = $this->user;
69
		if ('' == $password)
70
			$password = $this->password;
71
		if ('' == $driver)
72
			$driver = $this->driver;
73
		/* establish connection, select database */
74
		$dSN = "$driver:dbname=$database;host=$host";
75
		if ($this->characterSet != '')
76
			$dSN .= ';charset='.$this->characterSet;
77
		if ($this->linkId === false) {
0 ignored issues
show
introduced by
The condition $this->linkId === false is always false.
Loading history...
78
			try {
79
				$this->linkId = new \PDO($dSN, $user, $password);
80
			} catch (\PDOException $e) {
81
				$this->halt('Connection Failed '.$e->getMessage());
82
				return 0;
83
			}
84
		}
85
		return $this->linkId;
86
	}
87
88
	/* This only affects systems not using persistent connections */
89
90
	/**
91
	 * Db::disconnect()
92
	 * @return void
93
	 */
94
	public function disconnect() {
95
	}
96
97
	/**
98
	 * @param $string
99
	 * @return string
100
	 */
101
	public function real_escape($string) {
102
		return escapeshellarg($string);
103
	}
104
105
	/**
106
	 * @param $string
107
	 * @return string
108
	 */
109
	public function escape($string) {
110
		return escapeshellarg($string);
111
	}
112
113
	/* public: discard the query result */
114
115
	/**
116
	 * Db::free()
117
	 * @return void
118
	 */
119
	public function free() {
120
		//			@mysql_free_result($this->queryId);
121
		//			$this->queryId = 0;
122
	}
123
124
	/**
125
	 * Db::queryReturn()
126
	 *
127
	 * Sends an SQL query to the server like the normal query() command but iterates through
128
	 * any rows and returns the row or rows immediately or FALSE on error
129
	 *
130
	 * @param mixed $query SQL Query to be used
131
	 * @param string $line optionally pass __LINE__ calling the query for logging
132
	 * @param string $file optionally pass __FILE__ calling the query for logging
133
	 * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
134
	 */
135
	public function queryReturn($query, $line = '', $file = '') {
136
		$this->query($query, $line, $file);
137
		if ($this->num_rows() == 0) {
138
			return false;
139
		} elseif ($this->num_rows() == 1) {
140
			$this->next_record(MYSQL_ASSOC);
0 ignored issues
show
introduced by
The constant MYSQL_ASSOC has been deprecated: 5.5 ( Ignorable by Annotation )

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

140
			$this->next_record(/** @scrutinizer ignore-deprecated */ MYSQL_ASSOC);
Loading history...
141
			return $this->Record;
142
		} else {
143
			$out = [];
144
			while ($this->next_record(MYSQL_ASSOC))
0 ignored issues
show
introduced by
The constant MYSQL_ASSOC has been deprecated: 5.5 ( Ignorable by Annotation )

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

144
			while ($this->next_record(/** @scrutinizer ignore-deprecated */ MYSQL_ASSOC))
Loading history...
145
				$out[] = $this->Record;
146
			return $out;
147
		}
148
	}
149
150
	/**
151
	 * db:qr()
152
	 *
153
	 *  alias of queryReturn()
154
	 *
155
	 * @param mixed $query SQL Query to be used
156
	 * @param string $line optionally pass __LINE__ calling the query for logging
157
	 * @param string $file optionally pass __FILE__ calling the query for logging
158
	 * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
159
	 */
160
	public function qr($query, $line = '', $file = '') {
161
		return $this->queryReturn($query, $line, $file);
162
	}
163
164
	/**
165
	 * Db::query()
166
	 *
167
	 *  Sends an SQL query to the database
168
	 *
169
	 * @param mixed $queryString
170
	 * @param string $line
171
	 * @param string $file
172
	 * @return mixed 0 if no query or query id handler, safe to ignore this return
173
	 */
174
	public function query($queryString, $line = '', $file = '') {
175
		/* No empty queries, please, since PHP4 chokes on them. */
176
		/* The empty query string is passed on from the constructor,
177
		* when calling the class without a query, e.g. in situations
178
		* like these: '$db = new db_Subclass;'
179
		*/
180
		if ($queryString == '')
181
			return 0;
182
		if (!$this->connect()) {
183
			return 0;
184
			/* we already complained in connect() about that. */
185
		}
186
		// New query, discard previous result.
187
		if ($this->queryId !== false)
0 ignored issues
show
introduced by
The condition $this->queryId !== false is always true.
Loading history...
188
			$this->free();
189
190
		if ($this->Debug)
191
			printf("Debug: query = %s<br>\n", $queryString);
192
		if (isset($GLOBALS['log_queries']) && $GLOBALS['log_queries'] !== false)
193
			$this->log($queryString, $line, $file);
194
195
		$this->queryId = $this->linkId->prepare($queryString);
0 ignored issues
show
Bug introduced by
The method prepare() does not exist on integer. ( Ignorable by Annotation )

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

195
		/** @scrutinizer ignore-call */ 
196
  $this->queryId = $this->linkId->prepare($queryString);

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...
196
		$success = $this->queryId->execute();
197
		$this->Rows = $this->queryId->fetchAll();
198
		$this->log("PDO Query $queryString (S:$success) - ".count($this->Rows).' Rows', __LINE__, __FILE__);
199
		$this->Row = 0;
200
		if ($success === false) {
201
			$this->emailError($queryString, json_encode($this->queryId->errorInfo(), JSON_PRETTY_PRINT), $line, $file);
202
		}
203
204
		// Will return nada if it fails. That's fine.
205
		return $this->queryId;
206
	}
207
208
	/* public: walk result set */
209
210
	/**
211
	 * Db::next_record()
212
	 * @param mixed $resultType
213
	 * @return bool
214
	 */
215
	public function next_record($resultType = MYSQL_ASSOC) {
0 ignored issues
show
introduced by
The constant MYSQL_ASSOC has been deprecated: 5.5 ( Ignorable by Annotation )

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

215
	public function next_record($resultType = /** @scrutinizer ignore-deprecated */ MYSQL_ASSOC) {
Loading history...
216
		// PDO result types so far seem to be +1
217
		++$resultType;
218
		if (!$this->queryId) {
219
			$this->halt('next_record called with no query pending.');
220
			return 0;
221
		}
222
223
		++$this->Row;
224
		$this->Record = $this->Rows[$this->Row];
225
226
		$stat = is_array($this->Record);
227
		if (!$stat && $this->autoFree)
228
			$this->free();
229
		return $stat;
230
	}
231
232
	/* public: position in result set */
233
234
	/**
235
	 * Db::seek()
236
	 * @param integer $pos
237
	 * @return int
238
	 */
239
	public function seek($pos = 0) {
240
		if (isset($this->Rows[$pos])) {
241
			$this->Row = $pos;
242
		} else {
243
			$this->halt("seek($pos) failed: result has ".count($this->Rows).' rows');
244
			/* half assed attempt to save the day,
245
			* but do not consider this documented or even
246
			* desirable behaviour.
247
			*/
248
			return 0;
249
		}
250
		return 1;
251
	}
252
253
	/**
254
	 * Initiates a transaction
255
	 * @return bool
256
	 */
257
	public function transactionBegin() {
258
		return $this->linkId->beginTransaction();
259
	}
260
261
	/**
262
	 * Commits a transaction
263
	 * @return bool
264
	 */
265
	public function transactionCommit() {
266
		return $this->linkId->commit();
267
	}
268
269
	/**
270
	 * Rolls back a transaction
271
	 * @return bool
272
	 */
273
	public function transactionAbort() {
274
		return $this->linkId->rollBack();
275
	}
276
277
	/**
278
	 * Db::getLastInsertId()
279
	 * @param mixed $table
280
	 * @param mixed $field
281
	 * @return int
282
	 */
283
	public function getLastInsertId($table, $field) {
284
		if (!isset($table) || $table == '' || !isset($field) || $field == '')
285
			return -1;
286
		return $this->linkId->lastInsertId();
287
	}
288
289
	/* public: table locking */
290
291
	/**
292
	 * Db::lock()
293
	 * @param mixed  $table
294
	 * @param string $mode
295
	 * @return void
296
	 */
297
	public function lock($table, $mode = 'write') {
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed. ( Ignorable by Annotation )

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

297
	public function lock(/** @scrutinizer ignore-unused */ $table, $mode = 'write') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $mode is not used and could be removed. ( Ignorable by Annotation )

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

297
	public function lock($table, /** @scrutinizer ignore-unused */ $mode = 'write') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
298
		/*			$this->connect();
299
300
		* $query = "lock tables ";
301
		* if (is_array($table))
302
		* {
303
		* while (list($key,$value)=each($table))
304
		* {
305
		* if ($key == "read" && $key!=0)
306
		* {
307
		* $query .= "$value read, ";
308
		* }
309
		* else
310
		* {
311
		* $query .= "$value $mode, ";
312
		* }
313
		* }
314
		* $query = mb_substr($query,0,-2);
315
		* }
316
		* else
317
		* {
318
		* $query .= "$table $mode";
319
		* }
320
		* $res = @mysql_query($query, $this->linkId);
321
		* if (!$res)
322
		* {
323
		* $this->halt("lock($table, $mode) failed.");
324
		* return 0;
325
		* }
326
		* return $res;
327
		*/
328
	}
329
330
	/**
331
	 * Db::unlock()
332
	 * @return void
333
	 */
334
	public function unlock() {
335
		/*			$this->connect();
336
337
		* $res = @mysql_query("unlock tables");
338
		* if (!$res)
339
		* {
340
		* $this->halt("unlock() failed.");
341
		* return 0;
342
		* }
343
		* return $res;
344
		*/
345
	}
346
347
	/* public: evaluate the result (size, width) */
348
349
	/**
350
	 * Db::affectedRows()
351
	 *
352
	 * @return mixed
353
	 */
354
	public function affectedRows() {
355
		return @$this->queryId->rowCount();
0 ignored issues
show
Bug introduced by
The method rowCount() does not exist on integer. ( Ignorable by Annotation )

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

355
		return @$this->queryId->/** @scrutinizer ignore-call */ rowCount();

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...
356
	}
357
358
	/**
359
	 * Db::num_rows()
360
	 * @return int
361
	 */
362
	public function num_rows() {
363
		return count($this->Rows);
364
	}
365
366
	/**
367
	 * Db::num_fields()
368
	 * @return int
369
	 */
370
	public function num_fields() {
371
		$keys = array_keys($this->Rows);
372
		return count($this->Rows[$keys[0]]);
373
	}
374
375
	/**
376
	 * @param mixed $msg
377
	 * @param string $line
378
	 * @param string $file
379
	 * @return mixed|void
380
	 */
381
	public function haltmsg($msg, $line = '', $file = '') {
382
		$this->log("Database error: $msg", $line, $file, 'error');
383
		if ($this->Errno != '0' || $this->Error != '()')
384
			$this->log('PDO MySQL Error: '.json_encode($this->linkId->errorInfo()), $line, $file, 'error');
385
		$this->logBackTrace($msg, $line, $file);
386
	}
387
388
	/**
389
	 * Db::tableNames()
390
	 *
391
	 * @return array
392
	 */
393
	public function tableNames() {
394
		$return = [];
395
		$this->query('SHOW TABLES');
396
		foreach ($this->Rows as $i => $info) {
397
			$return[$i]['table_name'] = $info[0];
398
			$return[$i]['tablespace_name'] = $this->database;
399
			$return[$i]['database'] = $this->database;
400
		}
401
		return $return;
402
	}
403
}
404