Skip to content

Commit 68e406d

Browse files
committed
Initial commit for #176
1 parent bd3130b commit 68e406d

File tree

6 files changed

+119
-79
lines changed

6 files changed

+119
-79
lines changed

api.php

Lines changed: 90 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ interface DatabaseInterface {
55
public function getSql($name);
66
public function connect($hostname,$username,$password,$database,$port,$socket,$charset);
77
public function query($sql,$params=array());
8-
public function fetchAssoc($result,$fields=false);
9-
public function fetchRow($result,$fields=false);
8+
public function fetchAssoc($result);
9+
public function fetchRow($result);
1010
public function insertId($result);
1111
public function affectedRows($result);
1212
public function close($result);
@@ -16,6 +16,7 @@ public function likeEscape($string);
1616
public function isNumericType($field);
1717
public function isBinaryType($field);
1818
public function isGeometryType($field);
19+
public function isJsonType($field);
1920
public function getDefaultCharset();
2021
public function beginTransaction();
2122
public function commitTransaction();
@@ -117,8 +118,8 @@ public function query($sql,$params=array()) {
117118
$param = array_shift($params);
118119
if ($matches[0]=='!') {
119120
$key = preg_replace('/[^a-zA-Z0-9\-_=<> ]/','',is_object($param)?$param->key:$param);
120-
if (is_object($param) && $param->type=='base64') {
121-
return "TO_BASE64(\"$key\") as \"$key\"";
121+
if (is_object($param) && $param->type=='hex') {
122+
return "HEX(\"$key\") as \"$key\"";
122123
}
123124
if (is_object($param) && $param->type=='wkt') {
124125
return "ST_AsText(\"$key\") as \"$key\"";
@@ -128,8 +129,8 @@ public function query($sql,$params=array()) {
128129
if (is_array($param)) return '('.implode(',',array_map(function($v) use (&$db) {
129130
return "'".mysqli_real_escape_string($db,$v)."'";
130131
},$param)).')';
131-
if (is_object($param) && $param->type=='base64') {
132-
return "x'".bin2hex(base64_decode($param->value))."'";
132+
if (is_object($param) && $param->type=='hex') {
133+
return "x'".$param->value."'";
133134
}
134135
if (is_object($param) && $param->type=='wkt') {
135136
return "ST_GeomFromText('".mysqli_real_escape_string($db,$param->value)."')";
@@ -143,29 +144,12 @@ public function query($sql,$params=array()) {
143144
return mysqli_query($db,$sql);
144145
}
145146

146-
protected function convertFloatAndInt($result,&$values,&$fields) {
147-
array_walk($values, function(&$v,$i) use ($result,$fields){
148-
if (is_string($v) && $this->isNumericType($fields[$i])) {
149-
$v+=0;
150-
}
151-
});
152-
}
153-
154-
public function fetchAssoc($result,$fields=false) {
155-
$values = mysqli_fetch_assoc($result);
156-
if ($values && $fields && !defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE')) {
157-
$this->convertFloatAndInt($result,$values,$fields);
158-
}
159-
return $values;
147+
public function fetchAssoc($result) {
148+
return mysqli_fetch_assoc($result);
160149
}
161150

162-
public function fetchRow($result,$fields=false) {
163-
$values = mysqli_fetch_row($result);
164-
if ($values && $fields && !defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE')) {
165-
$fields = array_values($fields);
166-
$this->convertFloatAndInt($result,$values,$fields);
167-
}
168-
return $values;
151+
public function fetchRow($result) {
152+
return mysqli_fetch_row($result);
169153
}
170154

171155
public function insertId($result) {
@@ -210,6 +194,10 @@ public function isGeometryType($field) {
210194
return ($field->type==255);
211195
}
212196

197+
public function isJsonType($field) {
198+
return ($field->type==245);
199+
}
200+
213201
public function getDefaultCharset() {
214202
return 'utf8';
215203
}
@@ -358,8 +346,8 @@ public function query($sql,$params=array()) {
358346
$param = array_shift($params);
359347
if ($matches[0]=='!') {
360348
$key = preg_replace('/[^a-zA-Z0-9\-_=<> ]/','',is_object($param)?$param->key:$param);
361-
if (is_object($param) && $param->type=='base64') {
362-
return "encode(\"$key\",'base64') as \"$key\"";
349+
if (is_object($param) && $param->type=='hex') {
350+
return "encode(\"$key\",'hex') as \"$key\"";
363351
}
364352
if (is_object($param) && $param->type=='wkt') {
365353
return "ST_AsText(\"$key\") as \"$key\"";
@@ -369,8 +357,8 @@ public function query($sql,$params=array()) {
369357
if (is_array($param)) return '('.implode(',',array_map(function($v) use (&$db) {
370358
return "'".pg_escape_string($db,$v)."'";
371359
},$param)).')';
372-
if (is_object($param) && $param->type=='base64') {
373-
return "'\x".bin2hex(base64_decode($param->value))."'";
360+
if (is_object($param) && $param->type=='hex') {
361+
return "'\x".$param->value."'";
374362
}
375363
if (is_object($param) && $param->type=='wkt') {
376364
return "ST_GeomFromText('".pg_escape_string($db,$param->value)."')";
@@ -386,29 +374,12 @@ public function query($sql,$params=array()) {
386374
return @pg_query($db,$sql);
387375
}
388376

389-
protected function convertFloatAndInt($result,&$values,&$fields) {
390-
array_walk($values, function(&$v,$i) use ($result,$fields){
391-
if (is_string($v) && $this->isNumericType($fields[$i])) {
392-
$v+=0;
393-
}
394-
});
395-
}
396-
397-
public function fetchAssoc($result,$fields=false) {
398-
$values = pg_fetch_assoc($result);
399-
if ($values && $fields) {
400-
$this->convertFloatAndInt($result,$values,$fields);
401-
}
402-
return $values;
377+
public function fetchAssoc($result) {
378+
return pg_fetch_assoc($result);
403379
}
404380

405-
public function fetchRow($result,$fields=false) {
406-
$values = pg_fetch_row($result);
407-
if ($values && $fields) {
408-
$fields = array_values($fields);
409-
$this->convertFloatAndInt($result,$values,$fields);
410-
}
411-
return $values;
381+
public function fetchRow($result) {
382+
return pg_fetch_row($result);
412383
}
413384

414385
public function insertId($result) {
@@ -460,6 +431,10 @@ public function isGeometryType($field) {
460431
return $field->type == 'geometry';
461432
}
462433

434+
public function isJsonType($field) {
435+
return $field->type == 'jsonb';
436+
}
437+
463438
public function getDefaultCharset() {
464439
return 'UTF8';
465440
}
@@ -595,8 +570,8 @@ public function query($sql,$params=array()) {
595570
$param = $params[$i];
596571
if ($matches[0]=='!') {
597572
$key = preg_replace('/[^a-zA-Z0-9\-_=<> ]/','',is_object($param)?$param->key:$param);
598-
if (is_object($param) && $param->type=='base64') {
599-
return "CAST(N'' AS XML).value('xs:base64Binary(xs:hexBinary(sql:column(\"$key\")))', 'VARCHAR(MAX)') as \"$key\"";
573+
if (is_object($param) && $param->type=='hex') {
574+
return "CONVERT(varchar(max), \"$key\", 2) as \"$key\"";
600575
}
601576
if (is_object($param) && $param->type=='wkt') {
602577
return "\"$key\".STAsText() as \"$key\"";
@@ -611,8 +586,8 @@ public function query($sql,$params=array()) {
611586
$args = array_merge($args,$param);
612587
return '('.implode(',',str_split(str_repeat('?',count($param)))).')';
613588
}
614-
if (is_object($param) && $param->type=='base64') {
615-
$args[] = bin2hex(base64_decode($param->value));
589+
if (is_object($param) && $param->type=='hex') {
590+
$args[] = $param->value;
616591
return 'CONVERT(VARBINARY(MAX),?,2)';
617592
}
618593
if (is_object($param) && $param->type=='wkt') {
@@ -633,11 +608,11 @@ public function query($sql,$params=array()) {
633608
return sqlsrv_query($db,$sql,$args)?:null;
634609
}
635610

636-
public function fetchAssoc($result,$fields=false) {
611+
public function fetchAssoc($result) {
637612
return sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
638613
}
639614

640-
public function fetchRow($result,$fields=false) {
615+
public function fetchRow($result) {
641616
return sqlsrv_fetch_array($result, SQLSRV_FETCH_NUMERIC);
642617
}
643618

@@ -721,6 +696,10 @@ public function isGeometryType($field) {
721696
return ($field->type==-151);
722697
}
723698

699+
public function isJsonType($field) {
700+
return ($field->type==-152);
701+
}
702+
724703
public function getDefaultCharset() {
725704
return 'UTF-8';
726705
}
@@ -862,7 +841,10 @@ public function query($sql,$params=array()) {
862841
if (is_array($param)) return '('.implode(',',array_map(function($v) use (&$db) {
863842
return "'".$db->escapeString($v)."'";
864843
},$param)).')';
865-
if (is_object($param) && $param->type=='base64') {
844+
if (is_object($param) && $param->type=='hex') {
845+
return "'".$db->escapeString($param->value)."'";
846+
}
847+
if (is_object($param) && $param->type=='wkt') {
866848
return "'".$db->escapeString($param->value)."'";
867849
}
868850
if ($param===null) return 'NULL';
@@ -874,11 +856,11 @@ public function query($sql,$params=array()) {
874856
return $result;
875857
}
876858

877-
public function fetchAssoc($result,$fields=false) {
859+
public function fetchAssoc($result) {
878860
return $result->fetchArray(SQLITE3_ASSOC);
879861
}
880862

881-
public function fetchRow($result,$fields=false) {
863+
public function fetchRow($result) {
882864
return $result->fetchArray(SQLITE3_NUM);
883865
}
884866

@@ -924,7 +906,11 @@ public function isBinaryType($field) {
924906
}
925907

926908
public function isGeometryType($field) {
927-
return false;
909+
return in_array($field->type,array('geometry'));;
910+
}
911+
912+
public function isJsonType($field) {
913+
return in_array($field->type,array('json','jsonb'));;
928914
}
929915

930916
public function getDefaultCharset() {
@@ -1292,7 +1278,7 @@ protected function retrieveObject($key,$fields,$filters,$tables) {
12921278
$this->addWhereFromFilters($filters[$table],$sql,$params);
12931279
$object = null;
12941280
if ($result = $this->db->query($sql,$params)) {
1295-
$object = $this->db->fetchAssoc($result,$fields[$table]);
1281+
$object = $this->fetchAssoc($result,$fields[$table]);
12961282
$this->db->close($result);
12971283
}
12981284
return $object;
@@ -1615,19 +1601,22 @@ protected function convertInputs(&$input,$fields) {
16151601
if (isset($input->$key) && $input->$key && $this->db->isBinaryType($field)) {
16161602
$value = $input->$key;
16171603
$value = str_pad(strtr($value, '-_', '+/'), ceil(strlen($value) / 4) * 4, '=', STR_PAD_RIGHT);
1618-
$input->$key = (object)array('type'=>'base64','value'=>$value);
1604+
$input->$key = (object)array('type'=>'hex','value'=>bin2hex(base64_decode($value)));
16191605
}
16201606
if (isset($input->$key) && $input->$key && $this->db->isGeometryType($field)) {
16211607
$input->$key = (object)array('type'=>'wkt','value'=>$input->$key);
16221608
}
1609+
if (isset($input->$key) && $input->$key && $this->db->isJsonType($field)) {
1610+
$input->$key = (object)array('type'=>'json','value'=>json_encode($input->$key));
1611+
}
16231612
}
16241613
}
16251614

16261615
protected function convertOutputs(&$sql, &$params, $fields) {
16271616
$sql .= implode(',',str_split(str_repeat('!',count($fields))));
16281617
foreach ($fields as $key=>$field) {
16291618
if ($this->db->isBinaryType($field)) {
1630-
$params[] = (object)array('type'=>'base64','key'=>$key);
1619+
$params[] = (object)array('type'=>'hex','key'=>$key);
16311620
}
16321621
else if ($this->db->isGeometryType($field)) {
16331622
$params[] = (object)array('type'=>'wkt','key'=>$key);
@@ -1638,6 +1627,39 @@ protected function convertOutputs(&$sql, &$params, $fields) {
16381627
}
16391628
}
16401629

1630+
protected function convertTypes($result,&$values,&$fields) {
1631+
array_walk($values, function(&$v,$i) use ($result,$fields){
1632+
if (is_string($v)) {
1633+
if ($this->db->isNumericType($fields[$i])) {
1634+
$v+=0;
1635+
}
1636+
else if ($this->db->isBinaryType($fields[$i])) {
1637+
$v=base64_encode(hex2bin($v));
1638+
}
1639+
else if ($this->db->isJsonType($fields[$i])) {
1640+
$v=json_decode($v);
1641+
}
1642+
}
1643+
});
1644+
}
1645+
1646+
protected function fetchAssoc($result,$fields=false) {
1647+
$values = $this->db->fetchAssoc($result);
1648+
if ($values && $fields) {
1649+
$this->convertTypes($result,$values,$fields);
1650+
}
1651+
return $values;
1652+
}
1653+
1654+
protected function fetchRow($result,$fields=false) {
1655+
$values = $this->db->fetchRow($result,$fields);
1656+
if ($values && $fields) {
1657+
$fields = array_values($fields);
1658+
$this->convertTypes($result,$values,$fields);
1659+
}
1660+
return $values;
1661+
}
1662+
16411663
protected function getParameters($settings) {
16421664
extract($settings);
16431665

@@ -1742,7 +1764,7 @@ protected function listCommandInternal($parameters) {
17421764
}
17431765
if ($result = $this->db->query($sql,$params)) {
17441766
while ($pages = $this->db->fetchRow($result)) {
1745-
$count = $pages[0];
1767+
$count = (int)$pages[0];
17461768
}
17471769
}
17481770
}
@@ -1767,7 +1789,7 @@ protected function listCommandInternal($parameters) {
17671789
$keys = array_flip($keys);
17681790
echo ',"records":[';
17691791
$first_row = true;
1770-
while ($row = $this->db->fetchRow($result,$fields[$table])) {
1792+
while ($row = $this->fetchRow($result,$fields[$table])) {
17711793
if ($first_row) $first_row = false;
17721794
else echo ',';
17731795
if (isset($collect[$table])) {
@@ -1817,7 +1839,7 @@ protected function listCommandInternal($parameters) {
18171839
$keys = array_flip($keys);
18181840
echo ',"records":[';
18191841
$first_row = true;
1820-
while ($row = $this->db->fetchRow($result,$fields[$table])) {
1842+
while ($row = $this->fetchRow($result,$fields[$table])) {
18211843
if ($first_row) $first_row = false;
18221844
else echo ',';
18231845
if (isset($collect[$table])) {

tests/blog_mysql.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,11 @@ CREATE TABLE `products` (
124124
`id` int(11) NOT NULL AUTO_INCREMENT,
125125
`name` varchar(255) NOT NULL,
126126
`price` decimal(10,2) NOT NULL,
127+
`properties` JSON NOT NULL,
127128
PRIMARY KEY (`id`)
128129
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
129130

130-
INSERT INTO `products` (`id`, `name`, `price`) VALUES
131-
(1, 'Calculator', '23.01');
131+
INSERT INTO `products` (`id`, `name`, `price`, `properties`) VALUES
132+
(1, 'Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}');
132133

133134
-- 2016-11-05 13:11:47

tests/blog_postgresql.sql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ CREATE VIEW "tag_usage" AS select "name", count("name") AS "count" from "tags",
129129
CREATE TABLE products (
130130
id serial NOT NULL,
131131
name character varying(255) NOT NULL,
132-
price decimal(10,2) NOT NULL
132+
price decimal(10,2) NOT NULL,
133+
properties jsonb NOT NULL
133134
);
134135

135136
--
@@ -203,8 +204,8 @@ INSERT INTO "events" ("name", "datetime", "visitors") VALUES
203204
-- Data for Name: events; Type: TABLE DATA; Schema: public; Owner: postgres
204205
--
205206

206-
INSERT INTO "products" ("name", "price") VALUES
207-
('Calculator', '23.01');
207+
INSERT INTO "products" ("name", "price", "properties") VALUES
208+
('Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}');
208209

209210
--
210211
-- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:

0 commit comments

Comments
 (0)