Browse Source

Refactor database drivers

Maurits van der Schee 8 years ago
parent
commit
518d01bac2
6 changed files with 164 additions and 128 deletions
  1. 157
    115
      api.php
  2. 0
    0
      tests/blog_mysql.sql
  3. 0
    0
      tests/blog_postgresql.sql
  4. 0
    0
      tests/blog_sqlserver.sql
  5. 1
    1
      tests/config.php.dist
  6. 6
    12
      tests/tests.php

+ 157
- 115
api.php View File

1
 <?php
1
 <?php
2
-class MySQL_CRUD_API extends REST_CRUD_API {
2
+interface DatabaseInterface {
3
+	public function get_sql($name);
4
+	public function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset);
5
+	public function query($sql,$params);
6
+	public function fetch_assoc($result);
7
+	public function fetch_row($result);
8
+	public function insert_id($result);
9
+	public function affected_rows($result);
10
+	public function close($result);
11
+	public function fetch_fields($result);
12
+	public function add_limit_to_sql($sql,$limit,$offset);
13
+	public function likeEscape($string);
14
+	public function is_binary_type($field);
15
+	public function base64_encode($string);
16
+	public function getDefaultCharset();
17
+}
3
 
18
 
4
-	public function __construct($config) {
5
-		parent::__construct($config);
19
+class MySQL implements DatabaseInterface {
20
+
21
+	protected $db;
22
+	protected $queries;
23
+
24
+	public function __construct() {
6
 		$this->queries = array(
25
 		$this->queries = array(
7
 			'reflect_table'=>'SELECT
26
 			'reflect_table'=>'SELECT
8
 					"TABLE_NAME"
27
 					"TABLE_NAME"
58
 		);
77
 		);
59
 	}
78
 	}
60
 
79
 
61
-	protected function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset) {
80
+	public function get_sql($name) {
81
+		return isset($this->queries[$name])?$this->queries[$name]:false;
82
+	}
83
+
84
+	public function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset) {
62
 		$db = mysqli_connect($hostname,$username,$password,$database,$port,$socket);
85
 		$db = mysqli_connect($hostname,$username,$password,$database,$port,$socket);
63
 		if (mysqli_connect_errno()) {
86
 		if (mysqli_connect_errno()) {
64
 			throw new \Exception('Connect failed. '.mysqli_connect_error());
87
 			throw new \Exception('Connect failed. '.mysqli_connect_error());
69
 		if (!mysqli_query($db,'SET SESSION sql_mode = \'ANSI_QUOTES\';')) {
92
 		if (!mysqli_query($db,'SET SESSION sql_mode = \'ANSI_QUOTES\';')) {
70
 			throw new \Exception('Error setting ANSI quotes. '.mysqli_error($db));
93
 			throw new \Exception('Error setting ANSI quotes. '.mysqli_error($db));
71
 		}
94
 		}
72
-		return $db;
95
+		$this->db = $db;
73
 	}
96
 	}
74
 
97
 
75
-	protected function query($db,$sql,$params) {
98
+	public function query($sql,$params) {
99
+		$db = $this->db;
76
 		$sql = preg_replace_callback('/\!|\?/', function ($matches) use (&$db,&$params) {
100
 		$sql = preg_replace_callback('/\!|\?/', function ($matches) use (&$db,&$params) {
77
 			$param = array_shift($params);
101
 			$param = array_shift($params);
78
 			if ($matches[0]=='!') return preg_replace('/[^a-zA-Z0-9\-_=<>]/','',$param);
102
 			if ($matches[0]=='!') return preg_replace('/[^a-zA-Z0-9\-_=<>]/','',$param);
89
 		return mysqli_query($db,$sql);
113
 		return mysqli_query($db,$sql);
90
 	}
114
 	}
91
 
115
 
92
-	protected function fetch_assoc($result) {
116
+	public function fetch_assoc($result) {
93
 		return mysqli_fetch_assoc($result);
117
 		return mysqli_fetch_assoc($result);
94
 	}
118
 	}
95
 
119
 
96
-	protected function fetch_row($result) {
120
+	public function fetch_row($result) {
97
 		return mysqli_fetch_row($result);
121
 		return mysqli_fetch_row($result);
98
 	}
122
 	}
99
 
123
 
100
-	protected function insert_id($db,$result) {
101
-		return mysqli_insert_id($db);
124
+	public function insert_id($result) {
125
+		return mysqli_insert_id($this->db);
102
 	}
126
 	}
103
 
127
 
104
-	protected function affected_rows($db,$result) {
105
-		return mysqli_affected_rows($db);
128
+	public function affected_rows($result) {
129
+		return mysqli_affected_rows($this->db);
106
 	}
130
 	}
107
 
131
 
108
-	protected function close($result) {
132
+	public function close($result) {
109
 		return mysqli_free_result($result);
133
 		return mysqli_free_result($result);
110
 	}
134
 	}
111
 
135
 
112
-	protected function fetch_fields($result) {
136
+	public function fetch_fields($result) {
113
 		return mysqli_fetch_fields($result);
137
 		return mysqli_fetch_fields($result);
114
 	}
138
 	}
115
 
139
 
116
-	protected function add_limit_to_sql($sql,$limit,$offset) {
140
+	public function add_limit_to_sql($sql,$limit,$offset) {
117
 		return "$sql LIMIT $limit OFFSET $offset";
141
 		return "$sql LIMIT $limit OFFSET $offset";
118
 	}
142
 	}
119
 
143
 
120
-	protected function likeEscape($string) {
144
+	public function likeEscape($string) {
121
 		return addcslashes($string,'%_');
145
 		return addcslashes($string,'%_');
122
 	}
146
 	}
123
 
147
 
124
-	protected function is_binary_type($field) {
148
+	public function is_binary_type($field) {
125
 		//echo "$field->name: $field->type ($field->flags)\n";
149
 		//echo "$field->name: $field->type ($field->flags)\n";
126
 		return (($field->flags & 128) && ($field->type>=249) && ($field->type<=252));
150
 		return (($field->flags & 128) && ($field->type>=249) && ($field->type<=252));
127
 	}
151
 	}
128
 
152
 
129
-	protected function base64_encode($string) {
153
+	public function base64_encode($string) {
130
 		return base64_encode($string);
154
 		return base64_encode($string);
131
 	}
155
 	}
132
 
156
 
133
-	protected function getDefaultCharset() {
157
+	public function getDefaultCharset() {
134
 		return 'utf8';
158
 		return 'utf8';
135
 	}
159
 	}
136
 
160
 
137
 }
161
 }
138
 
162
 
139
-class PgSQL_CRUD_API extends REST_CRUD_API {
163
+class PostgreSQL implements DatabaseInterface {
140
 
164
 
141
-	public function __construct($config) {
142
-		parent::__construct($config);
165
+	protected $db;
166
+	protected $queries;
167
+
168
+	public function __construct() {
143
 		$this->queries = array(
169
 		$this->queries = array(
144
 			'reflect_table'=>'select
170
 			'reflect_table'=>'select
145
 					"table_name"
171
 					"table_name"
213
 		);
239
 		);
214
 	}
240
 	}
215
 
241
 
216
-	protected function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset) {
242
+	public function get_sql($name) {
243
+		return isset($this->queries[$name])?$this->queries[$name]:false;
244
+	}
245
+
246
+	public function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset) {
217
 		$e = function ($v) { return str_replace(array('\'','\\'),array('\\\'','\\\\'),$v); };
247
 		$e = function ($v) { return str_replace(array('\'','\\'),array('\\\'','\\\\'),$v); };
218
 		$conn_string = '';
248
 		$conn_string = '';
219
 		if ($hostname || $socket) {
249
 		if ($hostname || $socket) {
242
 			$conn_string.= " options='--client_encoding=$charset'";
272
 			$conn_string.= " options='--client_encoding=$charset'";
243
 		}
273
 		}
244
 		$db = pg_connect($conn_string);
274
 		$db = pg_connect($conn_string);
245
-		return $db;
275
+		$this->db = $db;
246
 	}
276
 	}
247
 
277
 
248
-	protected function query($db,$sql,$params) {
278
+	public function query($sql,$params) {
279
+		$db = $this->db;
249
 		$sql = preg_replace_callback('/\!|\?/', function ($matches) use (&$db,&$params) {
280
 		$sql = preg_replace_callback('/\!|\?/', function ($matches) use (&$db,&$params) {
250
 			$param = array_shift($params);
281
 			$param = array_shift($params);
251
 			if ($matches[0]=='!') return preg_replace('/[^a-zA-Z0-9\-_=<>]/','',$param);
282
 			if ($matches[0]=='!') return preg_replace('/[^a-zA-Z0-9\-_=<>]/','',$param);
265
 		return @pg_query($db,$sql);
296
 		return @pg_query($db,$sql);
266
 	}
297
 	}
267
 
298
 
268
-	protected function fetch_assoc($result) {
299
+	public function fetch_assoc($result) {
269
 		return pg_fetch_assoc($result);
300
 		return pg_fetch_assoc($result);
270
 	}
301
 	}
271
 
302
 
272
-	protected function fetch_row($result) {
303
+	public function fetch_row($result) {
273
 		return pg_fetch_row($result);
304
 		return pg_fetch_row($result);
274
 	}
305
 	}
275
 
306
 
276
-	protected function insert_id($db,$result) {
307
+	public function insert_id($result) {
277
 		list($id) = pg_fetch_row($result);
308
 		list($id) = pg_fetch_row($result);
278
 		return (int)$id;
309
 		return (int)$id;
279
 	}
310
 	}
280
 
311
 
281
-	protected function affected_rows($db,$result) {
312
+	public function affected_rows($result) {
282
 		return pg_affected_rows($result);
313
 		return pg_affected_rows($result);
283
 	}
314
 	}
284
 
315
 
285
-	protected function close($result) {
316
+	public function close($result) {
286
 		return pg_free_result($result);
317
 		return pg_free_result($result);
287
 	}
318
 	}
288
 
319
 
289
-	protected function fetch_fields($result) {
320
+	public function fetch_fields($result) {
290
 		$keys = array();
321
 		$keys = array();
291
 		for($i=0;$i<pg_num_fields($result);$i++) {
322
 		for($i=0;$i<pg_num_fields($result);$i++) {
292
 			$field = array();
323
 			$field = array();
297
 		return $keys;
328
 		return $keys;
298
 	}
329
 	}
299
 
330
 
300
-	protected function add_limit_to_sql($sql,$limit,$offset) {
331
+	public function add_limit_to_sql($sql,$limit,$offset) {
301
 		return "$sql LIMIT $limit OFFSET $offset";
332
 		return "$sql LIMIT $limit OFFSET $offset";
302
 	}
333
 	}
303
 
334
 
304
-	protected function likeEscape($string) {
335
+	public function likeEscape($string) {
305
 		return addcslashes($string,'%_');
336
 		return addcslashes($string,'%_');
306
 	}
337
 	}
307
 
338
 
308
-	protected function is_binary_type($field) {
339
+	public function is_binary_type($field) {
309
 		return $field->type == 'bytea';
340
 		return $field->type == 'bytea';
310
 	}
341
 	}
311
 
342
 
312
-	protected function base64_encode($string) {
343
+	public function base64_encode($string) {
313
 		return base64_encode(hex2bin(substr($string,2)));
344
 		return base64_encode(hex2bin(substr($string,2)));
314
 	}
345
 	}
315
 
346
 
316
-	protected function getDefaultCharset() {
347
+	public function getDefaultCharset() {
317
 		return 'UTF8';
348
 		return 'UTF8';
318
 	}
349
 	}
319
 
350
 
320
 }
351
 }
321
 
352
 
322
-class MsSQL_CRUD_API extends REST_CRUD_API {
353
+class SQLServer implements DatabaseInterface {
323
 
354
 
324
-	public function __construct($config) {
325
-		parent::__construct($config);
355
+	protected $db;
356
+	protected $queries;
357
+
358
+	public function __construct() {
326
 		$this->queries = array(
359
 		$this->queries = array(
327
 			'reflect_table'=>'SELECT
360
 			'reflect_table'=>'SELECT
328
 					"TABLE_NAME"
361
 					"TABLE_NAME"
396
 		);
429
 		);
397
 	}
430
 	}
398
 
431
 
399
-	protected function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset) {
432
+	public function get_sql($name) {
433
+		return isset($this->queries[$name])?$this->queries[$name]:false;
434
+	}
435
+
436
+	public function connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset) {
400
 		$connectionInfo = array();
437
 		$connectionInfo = array();
401
 		if ($port) $hostname.=','.$port;
438
 		if ($port) $hostname.=','.$port;
402
 		if ($username) $connectionInfo['UID']=$username;
439
 		if ($username) $connectionInfo['UID']=$username;
413
 		if ($socket) {
450
 		if ($socket) {
414
 			throw new \Exception('Socket connection is not supported.');
451
 			throw new \Exception('Socket connection is not supported.');
415
 		}
452
 		}
416
-		return $db;
453
+		$this->db = $db;
417
 	}
454
 	}
418
 
455
 
419
-	protected function query($db,$sql,$params) {
456
+	public function query($sql,$params) {
420
 		$args = array();
457
 		$args = array();
458
+		$db = $this->db;
421
 		$sql = preg_replace_callback('/\!|\?/', function ($matches) use (&$db,&$params,&$args) {
459
 		$sql = preg_replace_callback('/\!|\?/', function ($matches) use (&$db,&$params,&$args) {
422
 			static $i=-1;
460
 			static $i=-1;
423
 			$i++;
461
 			$i++;
452
 		return sqlsrv_query($db,$sql,$args)?:null;
490
 		return sqlsrv_query($db,$sql,$args)?:null;
453
 	}
491
 	}
454
 
492
 
455
-	protected function fetch_assoc($result) {
493
+	public function fetch_assoc($result) {
456
 		$values = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
494
 		$values = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
457
 		if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
495
 		if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
458
 		return $values;
496
 		return $values;
459
 	}
497
 	}
460
 
498
 
461
-	protected function fetch_row($result) {
499
+	public function fetch_row($result) {
462
 		$values = sqlsrv_fetch_array($result, SQLSRV_FETCH_NUMERIC);
500
 		$values = sqlsrv_fetch_array($result, SQLSRV_FETCH_NUMERIC);
463
 		if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
501
 		if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
464
 		return $values;
502
 		return $values;
465
 	}
503
 	}
466
 
504
 
467
-	protected function insert_id($db,$result) {
505
+	public function insert_id($result) {
468
 		sqlsrv_next_result($result);
506
 		sqlsrv_next_result($result);
469
 		sqlsrv_fetch($result);
507
 		sqlsrv_fetch($result);
470
 		return (int)sqlsrv_get_field($result, 0);
508
 		return (int)sqlsrv_get_field($result, 0);
471
 	}
509
 	}
472
 
510
 
473
-	protected function affected_rows($db,$result) {
511
+	public function affected_rows($result) {
474
 		return sqlsrv_rows_affected($result);
512
 		return sqlsrv_rows_affected($result);
475
 	}
513
 	}
476
 
514
 
477
-	protected function close($result) {
515
+	public function close($result) {
478
 		return sqlsrv_free_stmt($result);
516
 		return sqlsrv_free_stmt($result);
479
 	}
517
 	}
480
 
518
 
481
-	protected function fetch_fields($result) {
519
+	public function fetch_fields($result) {
482
 		//var_dump(sqlsrv_field_metadata($result));
520
 		//var_dump(sqlsrv_field_metadata($result));
483
 		return array_map(function($a){
521
 		return array_map(function($a){
484
 			$p = array();
522
 			$p = array();
489
 		},sqlsrv_field_metadata($result));
527
 		},sqlsrv_field_metadata($result));
490
 	}
528
 	}
491
 
529
 
492
-	protected function add_limit_to_sql($sql,$limit,$offset) {
530
+	public function add_limit_to_sql($sql,$limit,$offset) {
493
 		return "$sql OFFSET $offset ROWS FETCH NEXT $limit ROWS ONLY";
531
 		return "$sql OFFSET $offset ROWS FETCH NEXT $limit ROWS ONLY";
494
 	}
532
 	}
495
 
533
 
496
-	protected function likeEscape($string) {
534
+	public function likeEscape($string) {
497
 		return str_replace(array('%','_'),array('[%]','[_]'),$string);
535
 		return str_replace(array('%','_'),array('[%]','[_]'),$string);
498
 	}
536
 	}
499
 
537
 
500
-	protected function is_binary_type($field) {
538
+	public function is_binary_type($field) {
501
 		return ($field->type>=-4 && $field->type<=-2);
539
 		return ($field->type>=-4 && $field->type<=-2);
502
 	}
540
 	}
503
 
541
 
504
-	protected function base64_encode($string) {
542
+	public function base64_encode($string) {
505
 		return base64_encode($string);
543
 		return base64_encode($string);
506
 	}
544
 	}
507
 
545
 
508
-	protected function getDefaultCharset() {
546
+	public function getDefaultCharset() {
509
 		return 'UTF-8';
547
 		return 'UTF-8';
510
 	}
548
 	}
511
 }
549
 }
512
 
550
 
513
-class REST_CRUD_API {
551
+class PHP_CRUD_API {
514
 
552
 
515
-	protected $queries;
516
 	protected $settings;
553
 	protected $settings;
517
 
554
 
518
 	protected function mapMethodToAction($method,$key) {
555
 	protected function mapMethodToAction($method,$key) {
561
 		}
598
 		}
562
 	}
599
 	}
563
 
600
 
564
-	protected function applyRecordFilter($callback,$action,$database,$tables,&$filters) {
601
+	protected function applyRecordFilter($callback,$action,$database,$tables,&$filters,$db) {
565
 		if (is_callable($callback,true)) foreach ($tables as $i=>$table) {
602
 		if (is_callable($callback,true)) foreach ($tables as $i=>$table) {
566
-			$f = $this->convertFilters($callback($action,$database,$table));
603
+			$f = $this->convertFilters($db,$callback($action,$database,$table));
567
 			if ($f) {
604
 			if ($f) {
568
 				if (!isset($filters[$table])) $filters[$table] = array();
605
 				if (!isset($filters[$table])) $filters[$table] = array();
569
 				if (!isset($filters[$table]['and'])) $filters[$table]['and'] = array();
606
 				if (!isset($filters[$table]['and'])) $filters[$table]['and'] = array();
638
 		$table_array = explode(',',$tables);
675
 		$table_array = explode(',',$tables);
639
 		$table_list = array();
676
 		$table_list = array();
640
 		foreach ($table_array as $table) {
677
 		foreach ($table_array as $table) {
641
-			if ($result = $this->query($db,$this->queries['reflect_table'],array($table,$database))) {
642
-				while ($row = $this->fetch_row($result)) $table_list[] = $row[0];
643
-				$this->close($result);
678
+			if ($result = $db->query($db->get_sql('reflect_table'),array($table,$database))) {
679
+				while ($row = $db->fetch_row($result)) $table_list[] = $row[0];
680
+				$db->close($result);
644
 				if ($action!='list') break;
681
 				if ($action!='list') break;
645
 			}
682
 			}
646
 		}
683
 		}
701
 		if (!$key) return false;
738
 		if (!$key) return false;
702
 		$count = 0;
739
 		$count = 0;
703
 		$field = false;
740
 		$field = false;
704
-		if ($result = $this->query($db,$this->queries['reflect_pk'],array($tables[0],$database))) {
705
-			while ($row = $this->fetch_row($result)) {
741
+		if ($result = $db->query($db->get_sql('reflect_pk'),array($tables[0],$database))) {
742
+			while ($row = $db->fetch_row($result)) {
706
 				$count++;
743
 				$count++;
707
 				$field = $row[0];
744
 				$field = $row[0];
708
 			}
745
 			}
709
-			$this->close($result);
746
+			$db->close($result);
710
 		}
747
 		}
711
 		if ($count!=1 || $field==false) $this->exitWith404('1pk');
748
 		if ($count!=1 || $field==false) $this->exitWith404('1pk');
712
 		return array($key,$field);
749
 		return array($key,$field);
721
 		return $order;
758
 		return $order;
722
 	}
759
 	}
723
 
760
 
724
-	protected function convertFilter($field, $comparator, $value) {
761
+	protected function convertFilter($db, $field, $comparator, $value) {
725
 		switch (strtolower($comparator)) {
762
 		switch (strtolower($comparator)) {
726
-			case 'cs': $comparator = 'LIKE'; $value = '%'.$this->likeEscape($value).'%'; break;
727
-			case 'sw': $comparator = 'LIKE'; $value = $this->likeEscape($value).'%'; break;
728
-			case 'ew': $comparator = 'LIKE'; $value = '%'.$this->likeEscape($value); break;
763
+			case 'cs': $comparator = 'LIKE'; $value = '%'.$db->likeEscape($value).'%'; break;
764
+			case 'sw': $comparator = 'LIKE'; $value = $db->likeEscape($value).'%'; break;
765
+			case 'ew': $comparator = 'LIKE'; $value = '%'.$db->likeEscape($value); break;
729
 			case 'eq': $comparator = '='; break;
766
 			case 'eq': $comparator = '='; break;
730
 			case 'ne': $comparator = '<>'; break;
767
 			case 'ne': $comparator = '<>'; break;
731
 			case 'lt': $comparator = '<'; break;
768
 			case 'lt': $comparator = '<'; break;
737
 		return array($field, $comparator, $value);
774
 		return array($field, $comparator, $value);
738
 	}
775
 	}
739
 
776
 
740
-	protected function convertFilters($filters) {
777
+	protected function convertFilters($db,$filters) {
741
 		$result = array();
778
 		$result = array();
742
 		if ($filters) {
779
 		if ($filters) {
743
 			for ($i=0;$i<count($filters);$i++) {
780
 			for ($i=0;$i<count($filters);$i++) {
744
 				$filter = explode(',',$filters[$i],3);
781
 				$filter = explode(',',$filters[$i],3);
745
 				if (count($filter)==3) {
782
 				if (count($filter)==3) {
746
-					$result[] = $this->convertFilter($filter[0],$filter[1],$filter[2]);
783
+					$result[] = $this->convertFilter($db,$filter[0],$filter[1],$filter[2]);
747
 				}
784
 				}
748
 			}
785
 			}
749
 		}
786
 		}
750
 		return $result;
787
 		return $result;
751
 	}
788
 	}
752
 
789
 
753
-	protected function processFiltersParameter($tables,$satisfy,$filters) {
754
-		$result = $this->convertFilters($filters);
790
+	protected function processFiltersParameter($tables,$satisfy,$filters,$db) {
791
+		$result = $this->convertFilters($db, $filters);
755
 		if (!$result) return array();
792
 		if (!$result) return array();
756
 		$and = ($satisfy && strtolower($satisfy)=='any')?'or':'and';
793
 		$and = ($satisfy && strtolower($satisfy)=='any')?'or':'and';
757
 		return array($tables[0]=>array($and=>$result));
794
 		return array($tables[0]=>array($and=>$result));
776
 		if (!isset($filters[$table]['or'])) $filters[$table]['or'] = array();
813
 		if (!isset($filters[$table]['or'])) $filters[$table]['or'] = array();
777
 		$filters[$table]['or'][] = array($key[1],'=',$key[0]);
814
 		$filters[$table]['or'][] = array($key[1],'=',$key[0]);
778
 		$this->addWhereFromFilters($filters[$table],$sql,$params);
815
 		$this->addWhereFromFilters($filters[$table],$sql,$params);
779
-		if ($result = $this->query($db,$sql,$params)) {
780
-			$object = $this->fetch_assoc($result);
816
+		if ($result = $db->query($sql,$params)) {
817
+			$object = $db->fetch_assoc($result);
781
 			foreach ($fields[$table] as $field) {
818
 			foreach ($fields[$table] as $field) {
782
-				if ($this->is_binary_type($field) && $object[$field->name]) {
783
-					$object[$field->name] = $this->base64_encode($object[$field->name]);
819
+				if ($db->is_binary_type($field) && $object[$field->name]) {
820
+					$object[$field->name] = $db->base64_encode($object[$field->name]);
784
 				}
821
 				}
785
 			}
822
 			}
786
-			$this->close($result);
823
+			$db->close($result);
787
 		}
824
 		}
788
 		return $object;
825
 		return $object;
789
 	}
826
 	}
795
 		$values = implode(',',str_split(str_repeat('?', count($input))));
832
 		$values = implode(',',str_split(str_repeat('?', count($input))));
796
 		$params = array_merge(array_keys($input),array_values($input));
833
 		$params = array_merge(array_keys($input),array_values($input));
797
 		array_unshift($params, $tables[0]);
834
 		array_unshift($params, $tables[0]);
798
-		$result = $this->query($db,'INSERT INTO "!" ("'.$keys.'") VALUES ('.$values.')',$params);
835
+		$result = $db->query('INSERT INTO "!" ("'.$keys.'") VALUES ('.$values.')',$params);
799
 		if (!$result) return null;
836
 		if (!$result) return null;
800
-		return $this->insert_id($db,$result);
837
+		return $db->insert_id($result);
801
 	}
838
 	}
802
 
839
 
803
 	protected function updateObject($key,$input,$filters,$tables,$db) {
840
 	protected function updateObject($key,$input,$filters,$tables,$db) {
817
 		if (!isset($filters[$table]['or'])) $filters[$table]['or'] = array();
854
 		if (!isset($filters[$table]['or'])) $filters[$table]['or'] = array();
818
 		$filters[$table]['or'][] = array($key[1],'=',$key[0]);
855
 		$filters[$table]['or'][] = array($key[1],'=',$key[0]);
819
 		$this->addWhereFromFilters($filters[$table],$sql,$params);
856
 		$this->addWhereFromFilters($filters[$table],$sql,$params);
820
-		$result = $this->query($db,$sql,$params);
821
-		return $this->affected_rows($db, $result);
857
+		$result = $db->query($sql,$params);
858
+		return $db->affected_rows($result);
822
 	}
859
 	}
823
 
860
 
824
 	protected function deleteObject($key,$filters,$tables,$db) {
861
 	protected function deleteObject($key,$filters,$tables,$db) {
829
 		if (!isset($filters[$table]['or'])) $filters[$table]['or'] = array();
866
 		if (!isset($filters[$table]['or'])) $filters[$table]['or'] = array();
830
 		$filters[$table]['or'][] = array($key[1],'=',$key[0]);
867
 		$filters[$table]['or'][] = array($key[1],'=',$key[0]);
831
 		$this->addWhereFromFilters($filters[$table],$sql,$params);
868
 		$this->addWhereFromFilters($filters[$table],$sql,$params);
832
-		$result = $this->query($db,$sql,$params);
833
-		return $this->affected_rows($db, $result);
869
+		$result = $db->query($sql,$params);
870
+		return $db->affected_rows($result);
834
 	}
871
 	}
835
 
872
 
836
 	protected function findRelations($tables,$database,$db) {
873
 	protected function findRelations($tables,$database,$db) {
842
 			$table0 = array_shift($tables);
879
 			$table0 = array_shift($tables);
843
 			$tableset[] = $table0;
880
 			$tableset[] = $table0;
844
 
881
 
845
-			$result = $this->query($db,$this->queries['reflect_belongs_to'],array($table0,$tables,$database,$database));
846
-			while ($row = $this->fetch_row($result)) {
882
+			$result = $db->query($db->get_sql('reflect_belongs_to'),array($table0,$tables,$database,$database));
883
+			while ($row = $db->fetch_row($result)) {
847
 				$collect[$row[0]][$row[1]]=array();
884
 				$collect[$row[0]][$row[1]]=array();
848
 				$select[$row[2]][$row[3]]=array($row[0],$row[1]);
885
 				$select[$row[2]][$row[3]]=array($row[0],$row[1]);
849
 				if (!in_array($row[0],$tableset)) $tableset[] = $row[0];
886
 				if (!in_array($row[0],$tableset)) $tableset[] = $row[0];
850
 			}
887
 			}
851
-			$result = $this->query($db,$this->queries['reflect_has_many'],array($tables,$table0,$database,$database));
852
-			while ($row = $this->fetch_row($result)) {
888
+			$result = $db->query($db->get_sql('reflect_has_many'),array($tables,$table0,$database,$database));
889
+			while ($row = $db->fetch_row($result)) {
853
 				$collect[$row[2]][$row[3]]=array();
890
 				$collect[$row[2]][$row[3]]=array();
854
 				$select[$row[0]][$row[1]]=array($row[2],$row[3]);
891
 				$select[$row[0]][$row[1]]=array($row[2],$row[3]);
855
 				if (!in_array($row[2],$tableset)) $tableset[] = $row[2];
892
 				if (!in_array($row[2],$tableset)) $tableset[] = $row[2];
856
 			}
893
 			}
857
-			$result = $this->query($db,$this->queries['reflect_habtm'],array($database,$database,$database,$database,$table0,$tables));
858
-			while ($row = $this->fetch_row($result)) {
894
+			$result = $db->query($db->get_sql('reflect_habtm'),array($database,$database,$database,$database,$table0,$tables));
895
+			while ($row = $db->fetch_row($result)) {
859
 				$collect[$row[2]][$row[3]]=array();
896
 				$collect[$row[2]][$row[3]]=array();
860
 				$select[$row[0]][$row[1]]=array($row[2],$row[3]);
897
 				$select[$row[0]][$row[1]]=array($row[2],$row[3]);
861
 				$collect[$row[4]][$row[5]]=array();
898
 				$collect[$row[4]][$row[5]]=array();
911
 
948
 
912
 	protected function findTableFields($table,$database,$db) {
949
 	protected function findTableFields($table,$database,$db) {
913
 		$fields = array();
950
 		$fields = array();
914
-		$result = $this->query($db,'SELECT * FROM "!" WHERE 1=2;',array($table));
915
-		foreach ($this->fetch_fields($result) as $field) {
951
+		$result = $db->query('SELECT * FROM "!" WHERE 1=2;',array($table));
952
+		foreach ($db->fetch_fields($result) as $field) {
916
 			$fields[$field->name] = $field;
953
 			$fields[$field->name] = $field;
917
 		}
954
 		}
918
 		return $fields;
955
 		return $fields;
927
 		return $input;
964
 		return $input;
928
 	}
965
 	}
929
 
966
 
930
-	protected function convertBinary(&$input,$keys) {
967
+	protected function convertBinary(&$input,$keys,$db) {
931
 		foreach ($keys as $key=>$field) {
968
 		foreach ($keys as $key=>$field) {
932
-			if (isset($input->$key) && $input->$key && $this->is_binary_type($field)) {
969
+			if (isset($input->$key) && $input->$key && $db->is_binary_type($field)) {
933
 				$data = $input->$key;
970
 				$data = $input->$key;
934
 				$data = str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT);
971
 				$data = str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT);
935
 				$input->$key = (object)array('type'=>'base64','data'=>$data);
972
 				$input->$key = (object)array('type'=>'base64','data'=>$data);
953
 
990
 
954
 		$tables    = $this->processTablesParameter($database,$tables,$action,$db);
991
 		$tables    = $this->processTablesParameter($database,$tables,$action,$db);
955
 		$key       = $this->processKeyParameter($key,$tables,$database,$db);
992
 		$key       = $this->processKeyParameter($key,$tables,$database,$db);
956
-		$filters   = $this->processFiltersParameter($tables,$satisfy,$filters);
993
+		$filters   = $this->processFiltersParameter($tables,$satisfy,$filters, $db);
957
 		$page      = $this->processPageParameter($page);
994
 		$page      = $this->processPageParameter($page);
958
 		$order     = $this->processOrderParameter($order);
995
 		$order     = $this->processOrderParameter($order);
959
 
996
 
963
 
1000
 
964
 		// permissions
1001
 		// permissions
965
 		if ($table_authorizer) $this->applyTableAuthorizer($table_authorizer,$action,$database,$tables);
1002
 		if ($table_authorizer) $this->applyTableAuthorizer($table_authorizer,$action,$database,$tables);
966
-		if ($record_filter) $this->applyRecordFilter($record_filter,$action,$database,$tables,$filters);
1003
+		if ($record_filter) $this->applyRecordFilter($record_filter,$action,$database,$tables,$filters,$db);
967
 		if ($column_authorizer) $this->applyColumnAuthorizer($column_authorizer,$action,$database,$fields);
1004
 		if ($column_authorizer) $this->applyColumnAuthorizer($column_authorizer,$action,$database,$fields);
968
 		if ($tenancy_function) $this->applyTenancyFunction($tenancy_function,$action,$database,$fields,$filters);
1005
 		if ($tenancy_function) $this->applyTenancyFunction($tenancy_function,$action,$database,$fields,$filters);
969
 
1006
 
976
 			if ($input_sanitizer) $this->applyInputSanitizer($input_sanitizer,$action,$database,$tables[0],$input,$fields[$tables[0]]);
1013
 			if ($input_sanitizer) $this->applyInputSanitizer($input_sanitizer,$action,$database,$tables[0],$input,$fields[$tables[0]]);
977
 			if ($input_validator) $this->applyInputValidator($input_validator,$action,$database,$tables[0],$input,$fields[$tables[0]],$context);
1014
 			if ($input_validator) $this->applyInputValidator($input_validator,$action,$database,$tables[0],$input,$fields[$tables[0]],$context);
978
 
1015
 
979
-			$this->convertBinary($input,$fields[$tables[0]]);
1016
+			$this->convertBinary($input,$fields[$tables[0]],$db);
980
 		}
1017
 		}
981
 
1018
 
982
 		return compact('action','database','tables','key','callback','page','filters','fields','order','transform','db','input','collect','select');
1019
 		return compact('action','database','tables','key','callback','page','filters','fields','order','transform','db','input','collect','select');
1022
 			if (isset($filters[$table])) {
1059
 			if (isset($filters[$table])) {
1023
 					$this->addWhereFromFilters($filters[$table],$sql,$params);
1060
 					$this->addWhereFromFilters($filters[$table],$sql,$params);
1024
 			}
1061
 			}
1025
-			if ($result = $this->query($db,$sql,$params)) {
1026
-				while ($pages = $this->fetch_row($result)) {
1062
+			if ($result = $db->query($sql,$params)) {
1063
+				while ($pages = $db->fetch_row($result)) {
1027
 					$count = $pages[0];
1064
 					$count = $pages[0];
1028
 				}
1065
 				}
1029
 			}
1066
 			}
1042
 			$params[] = $order[1];
1079
 			$params[] = $order[1];
1043
 		}
1080
 		}
1044
 		if (is_array($order) && is_array($page)) {
1081
 		if (is_array($order) && is_array($page)) {
1045
-			$sql = $this->add_limit_to_sql($sql,$page[1],$page[0]);
1082
+			$sql = $db->add_limit_to_sql($sql,$page[1],$page[0]);
1046
 		}
1083
 		}
1047
-		if ($result = $this->query($db,$sql,$params)) {
1084
+		if ($result = $db->query($sql,$params)) {
1048
 			echo '"columns":';
1085
 			echo '"columns":';
1049
 			$keys = array();
1086
 			$keys = array();
1050
 			$base64 = array();
1087
 			$base64 = array();
1051
 			foreach ($fields[$table] as $field) {
1088
 			foreach ($fields[$table] as $field) {
1052
-				$base64[] = $this->is_binary_type($field);
1089
+				$base64[] = $db->is_binary_type($field);
1053
 				$keys[] = $field->name;
1090
 				$keys[] = $field->name;
1054
 			}
1091
 			}
1055
 			echo json_encode($keys);
1092
 			echo json_encode($keys);
1056
 			$keys = array_flip($keys);
1093
 			$keys = array_flip($keys);
1057
 			echo ',"records":[';
1094
 			echo ',"records":[';
1058
 			$first_row = true;
1095
 			$first_row = true;
1059
-			while ($row = $this->fetch_row($result)) {
1096
+			while ($row = $db->fetch_row($result)) {
1060
 				if ($first_row) $first_row = false;
1097
 				if ($first_row) $first_row = false;
1061
 				else echo ',';
1098
 				else echo ',';
1062
 				if (isset($collect[$table])) {
1099
 				if (isset($collect[$table])) {
1066
 				}
1103
 				}
1067
 				foreach ($base64 as $k=>$v) {
1104
 				foreach ($base64 as $k=>$v) {
1068
 					if ($v && $row[$k]) {
1105
 					if ($v && $row[$k]) {
1069
-						$row[$k] = $this->base64_encode($row[$k]);
1106
+						$row[$k] = $db->base64_encode($row[$k]);
1070
 					}
1107
 					}
1071
 				}
1108
 				}
1072
 				echo json_encode($row);
1109
 				echo json_encode($row);
1073
 			}
1110
 			}
1074
-			$this->close($result);
1111
+			$db->close($result);
1075
 			echo ']';
1112
 			echo ']';
1076
 			if ($count) echo ',';
1113
 			if ($count) echo ',';
1077
 		}
1114
 		}
1101
 				echo '}';
1138
 				echo '}';
1102
 				$this->addWhereFromFilters($filters[$table],$sql,$params);
1139
 				$this->addWhereFromFilters($filters[$table],$sql,$params);
1103
 			}
1140
 			}
1104
-			if ($result = $this->query($db,$sql,$params)) {
1141
+			if ($result = $db->query($sql,$params)) {
1105
 				if (isset($select[$table])) echo ',';
1142
 				if (isset($select[$table])) echo ',';
1106
 				echo '"columns":';
1143
 				echo '"columns":';
1107
 				$keys = array();
1144
 				$keys = array();
1108
 				$base64 = array();
1145
 				$base64 = array();
1109
 				foreach ($fields[$table] as $field) {
1146
 				foreach ($fields[$table] as $field) {
1110
-					$base64[] = $this->is_binary_type($field);
1147
+					$base64[] = $db->is_binary_type($field);
1111
 					$keys[] = $field->name;
1148
 					$keys[] = $field->name;
1112
 				}
1149
 				}
1113
 				echo json_encode($keys);
1150
 				echo json_encode($keys);
1114
 				$keys = array_flip($keys);
1151
 				$keys = array_flip($keys);
1115
 				echo ',"records":[';
1152
 				echo ',"records":[';
1116
 				$first_row = true;
1153
 				$first_row = true;
1117
-				while ($row = $this->fetch_row($result)) {
1154
+				while ($row = $db->fetch_row($result)) {
1118
 					if ($first_row) $first_row = false;
1155
 					if ($first_row) $first_row = false;
1119
 					else echo ',';
1156
 					else echo ',';
1120
 					if (isset($collect[$table])) {
1157
 					if (isset($collect[$table])) {
1124
 					}
1161
 					}
1125
 					foreach ($base64 as $k=>$v) {
1162
 					foreach ($base64 as $k=>$v) {
1126
 						if ($v && $row[$k]) {
1163
 						if ($v && $row[$k]) {
1127
-							$row[$k] = $this->base64_encode($row[$k]);
1164
+							$row[$k] = $db->base64_encode($row[$k]);
1128
 						}
1165
 						}
1129
 					}
1166
 					}
1130
 					echo json_encode($row);
1167
 					echo json_encode($row);
1131
 				}
1168
 				}
1132
-				$this->close($result);
1169
+				$db->close($result);
1133
 				echo ']';
1170
 				echo ']';
1134
 			}
1171
 			}
1135
 			echo '}';
1172
 			echo '}';
1204
 		$input_sanitizer = isset($input_sanitizer)?$input_sanitizer:null;
1241
 		$input_sanitizer = isset($input_sanitizer)?$input_sanitizer:null;
1205
 		$input_validator = isset($input_validator)?$input_validator:null;
1242
 		$input_validator = isset($input_validator)?$input_validator:null;
1206
 
1243
 
1244
+		$dbengine = isset($dbengine)?$dbengine:null;
1207
 		$db = isset($db)?$db:null;
1245
 		$db = isset($db)?$db:null;
1208
 		$method = isset($method)?$method:null;
1246
 		$method = isset($method)?$method:null;
1209
 		$request = isset($request)?$request:null;
1247
 		$request = isset($request)?$request:null;
1211
 		$post = isset($post)?$post:null;
1249
 		$post = isset($post)?$post:null;
1212
 
1250
 
1213
 		// defaults
1251
 		// defaults
1252
+		if (!$dbengine) {
1253
+			$dbengine = 'MySQL';
1254
+		}
1214
 		if (!$method) {
1255
 		if (!$method) {
1215
 			$method = $_SERVER['REQUEST_METHOD'];
1256
 			$method = $_SERVER['REQUEST_METHOD'];
1216
 		}
1257
 		}
1223
 		if (!$post) {
1264
 		if (!$post) {
1224
 			$post = 'php://input';
1265
 			$post = 'php://input';
1225
 		}
1266
 		}
1226
-		if (!$charset) {
1227
-			$charset = $this->getDefaultCharset();
1228
-		}
1229
 
1267
 
1230
 		// connect
1268
 		// connect
1231
 		$request = trim($request,'/');
1269
 		$request = trim($request,'/');
1233
 			$database  = $this->parseRequestParameter($request, 'a-zA-Z0-9\-_');
1271
 			$database  = $this->parseRequestParameter($request, 'a-zA-Z0-9\-_');
1234
 		}
1272
 		}
1235
 		if (!$db) {
1273
 		if (!$db) {
1236
-			$db = $this->connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset);
1274
+			$db = new $dbengine();
1275
+			if (!$charset) {
1276
+				$charset = $db->getDefaultCharset();
1277
+			}
1278
+			$db->connectDatabase($hostname,$username,$password,$database,$port,$socket,$charset);
1237
 		}
1279
 		}
1238
 
1280
 
1239
 		$this->settings = compact('method', 'request', 'get', 'post', 'database', 'table_authorizer', 'record_filter', 'column_authorizer', 'tenancy_function', 'input_sanitizer', 'input_validator', 'db');
1281
 		$this->settings = compact('method', 'request', 'get', 'post', 'database', 'table_authorizer', 'record_filter', 'column_authorizer', 'tenancy_function', 'input_sanitizer', 'input_validator', 'db');
1295
 
1337
 
1296
 // uncomment the lines below when running in stand-alone mode:
1338
 // uncomment the lines below when running in stand-alone mode:
1297
 
1339
 
1298
-// $api = new MySQL_CRUD_API(array(
1340
+// $api = new PHP_CRUD_API(array(
1299
 // 	'hostname'=>'localhost',
1341
 // 	'hostname'=>'localhost',
1300
 //	'username'=>'xxx',
1342
 //	'username'=>'xxx',
1301
 //	'password'=>'xxx',
1343
 //	'password'=>'xxx',
1306
 
1348
 
1307
 // For Microsoft SQL Server use:
1349
 // For Microsoft SQL Server use:
1308
 
1350
 
1309
-// $api = new MsSQL_CRUD_API(array(
1351
+// $api = new PHP_CRUD_API(array(
1310
 // 	'hostname'=>'(local)',
1352
 // 	'hostname'=>'(local)',
1311
 // 	'username'=>'',
1353
 // 	'username'=>'',
1312
 // 	'password'=>'',
1354
 // 	'password'=>'',
1317
 
1359
 
1318
 // For PostgreSQL use:
1360
 // For PostgreSQL use:
1319
 
1361
 
1320
-// $api = new PgSQL_CRUD_API(array(
1362
+// $api = new PHP_CRUD_API(array(
1321
 // 	'hostname'=>'localhost',
1363
 // 	'hostname'=>'localhost',
1322
 // 	'username'=>'xxx',
1364
 // 	'username'=>'xxx',
1323
 // 	'password'=>'xxx',
1365
 // 	'password'=>'xxx',

tests/blog.mysql → tests/blog_mysql.sql View File


tests/blog.pgsql → tests/blog_postgresql.sql View File


tests/blog.mssql → tests/blog_sqlserver.sql View File


+ 1
- 1
tests/config.php.dist View File

2
 
2
 
3
 class MySQL_CRUD_API_Config
3
 class MySQL_CRUD_API_Config
4
 {
4
 {
5
-	public static $dbengine='mysql';             // 'mysql', 'mssql' or 'pgsql'
5
+	public static $dbengine='MySQL';             // 'MySQL', 'SQLServer' or 'PostgreSQL'
6
 	public static $hostname='{{test_hostname}}'; // 'localhost' for mysql or '(Local)' for mssql
6
 	public static $hostname='{{test_hostname}}'; // 'localhost' for mysql or '(Local)' for mssql
7
 	public static $username='{{test_username}}'; // May be empty on mssql
7
 	public static $username='{{test_username}}'; // May be empty on mssql
8
 	public static $password='{{test_password}}'; // May be empty on mssql
8
 	public static $password='{{test_password}}'; // May be empty on mssql

+ 6
- 12
tests/tests.php View File

23
 
23
 
24
 		$data = 'data://text/plain;base64,'.base64_encode($data);
24
 		$data = 'data://text/plain;base64,'.base64_encode($data);
25
 
25
 
26
-		switch(MySQL_CRUD_API_Config::$dbengine) {
27
-			case 'mssql':	$class = 'MsSQL_CRUD_API'; break;
28
-			case 'pgsql':	$class = 'PgSQL_CRUD_API'; break;
29
-			case 'mysql':	$class = 'MySQL_CRUD_API'; break;
30
-			default:	die("DB engine not supported: $dbengine\n");
31
-		}
32
-
33
-		$this->api = new $class(array(
26
+		$this->api = new PHP_CRUD_API(array(
27
+				'dbengine'=>MySQL_CRUD_API_Config::$dbengine,
34
 				'hostname'=>MySQL_CRUD_API_Config::$hostname,
28
 				'hostname'=>MySQL_CRUD_API_Config::$hostname,
35
 				'username'=>MySQL_CRUD_API_Config::$username,
29
 				'username'=>MySQL_CRUD_API_Config::$username,
36
 				'password'=>MySQL_CRUD_API_Config::$password,
30
 				'password'=>MySQL_CRUD_API_Config::$password,
107
 		$password = MySQL_CRUD_API_Config::$password;
101
 		$password = MySQL_CRUD_API_Config::$password;
108
 		$database = MySQL_CRUD_API_Config::$database;
102
 		$database = MySQL_CRUD_API_Config::$database;
109
 
103
 
110
-		$fixture = __DIR__.'/blog.'.$dbengine;
104
+		$fixture = __DIR__.'/blog_'.strtolower($dbengine).'.sql';
111
 
105
 
112
-		if ($dbengine == 'mysql') {
106
+		if ($dbengine == 'MySQL') {
113
 
107
 
114
 			$link = mysqli_connect($hostname, $username, $password, $database);
108
 			$link = mysqli_connect($hostname, $username, $password, $database);
115
 			if (mysqli_connect_errno()) {
109
 			if (mysqli_connect_errno()) {
127
 
121
 
128
 			mysqli_close($link);
122
 			mysqli_close($link);
129
 
123
 
130
-		} elseif ($dbengine == 'mssql') {
124
+		} elseif ($dbengine == 'SQLServer') {
131
 
125
 
132
 			$connectionInfo = array();
126
 			$connectionInfo = array();
133
 			$connectionInfo['UID']=$username;
127
 			$connectionInfo['UID']=$username;
148
 			}
142
 			}
149
 			sqlsrv_close($conn);
143
 			sqlsrv_close($conn);
150
 
144
 
151
-		} elseif ($dbengine == 'pgsql') {
145
+		} elseif ($dbengine == 'PostgreSQL') {
152
 
146
 
153
 			$e = function ($v) { return str_replace(array('\'','\\'),array('\\\'','\\\\'),$v); };
147
 			$e = function ($v) { return str_replace(array('\'','\\'),array('\\\'','\\\\'),$v); };
154
 			$hostname = $e($hostname);
148
 			$hostname = $e($hostname);

Loading…
Cancel
Save