Skip to content

Commit be3dd21

Browse files
committed
- Support for Named-Parameters
- Option for preserving field-types in the result-set
1 parent b7d44e8 commit be3dd21

File tree

5 files changed

+159
-2
lines changed

5 files changed

+159
-2
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/.idea
22
/vendor
33
/composer.lock
4-
/atlassian-ide-plugin.xml
4+
/atlassian-ide-plugin.xml
5+
/test.php

src/Kir/MySQL/Builder/RunnableSelect.php

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,75 @@
55
use PDO;
66
use PDOStatement;
77

8+
/**
9+
*/
810
class RunnableSelect extends Select {
11+
/**
12+
* @var array
13+
*/
14+
private $values = array();
15+
16+
/**
17+
* @var bool
18+
*/
19+
private $preserveTypes;
20+
21+
/**
22+
* @param array $values
23+
* @return $this
24+
*/
25+
public function bindValues(array $values) {
26+
$this->values = array_merge($this->values, $values);
27+
return $this;
28+
}
29+
30+
/**
31+
* @param string $key
32+
* @param string|int|bool|float|null $value
33+
* @return $this
34+
*/
35+
public function bindValue($key, $value) {
36+
$this->values[$key] = $value;
37+
return $this;
38+
}
39+
40+
/**
41+
* @return $this
42+
*/
43+
public function clearValues() {
44+
$this->values = array();
45+
return $this;
46+
}
47+
48+
/**
49+
* @param bool $preserveTypes
50+
* @return $this
51+
*/
52+
public function setPreserveTypes($preserveTypes = true) {
53+
$this->preserveTypes = $preserveTypes;
54+
return $this;
55+
}
56+
957
/**
1058
* @param Closure $callback
1159
* @return array[]
1260
*/
1361
public function fetchRows(Closure $callback = null) {
1462
$statement = $this->createStatement();
63+
$statement->execute($this->values);
1564
$data = $statement->fetchAll(PDO::FETCH_ASSOC);
1665
if($callback !== null) {
1766
$data = array_map($callback, $data);
1867
}
1968
$statement->closeCursor();
69+
70+
if($this->preserveTypes) {
71+
$columnDefinitions = $this->getFieldTypes($statement);
72+
foreach($data as &$row) {
73+
$row = $this->convertValues($row, $columnDefinitions);
74+
}
75+
}
76+
2077
return $data;
2178
}
2279

@@ -25,10 +82,18 @@ public function fetchRows(Closure $callback = null) {
2582
*/
2683
public function fetchRow() {
2784
$statement = $this->createStatement();
85+
$statement->execute($this->values);
2886
$row = $statement->fetch(PDO::FETCH_ASSOC);
2987
if(!is_array($row)) {
3088
return array();
3189
}
90+
if($this->preserveTypes) {
91+
$columnDefinitions = $this->getFieldTypes($statement);
92+
$row = $this->convertValues($row, $columnDefinitions);
93+
}
94+
95+
$statement->closeCursor();
96+
3297
return $row;
3398
}
3499

@@ -48,6 +113,7 @@ public function fetchArray() {
48113
*/
49114
public function fetchValue($default = null) {
50115
$statement = $this->createStatement();
116+
$statement->execute($this->values);
51117
$row = $statement->fetch(PDO::FETCH_ASSOC);
52118
if(!is_array($row)) {
53119
return $default;
@@ -62,6 +128,68 @@ public function fetchValue($default = null) {
62128
* @return PDOStatement
63129
*/
64130
private function createStatement() {
65-
return $this->db()->query($this->__toString());
131+
return $this->db()->prepare($this->__toString());
132+
}
133+
134+
/**
135+
* @param PDOStatement $statement
136+
* @return array
137+
*/
138+
private function getFieldTypes($statement) {
139+
$c = $statement->columnCount();
140+
$fieldTypes = array();
141+
for($i=0; $i<$c+20; $i++) {
142+
$column = $statement->getColumnMeta($i);
143+
$fieldTypes[$column['name']] = $this->getTypeFromNativeType($column['native_type']);
144+
}
145+
return $fieldTypes;
146+
}
147+
148+
/**
149+
* @param string $type
150+
* @return string
151+
*/
152+
private function getTypeFromNativeType($type) {
153+
switch ($type) {
154+
case 'NEWDECIMAL':
155+
case 'DECIMAL':
156+
case 'FLOAT':
157+
case 'DOUBLE':
158+
return 'f';
159+
case 'TINY':
160+
case 'SHORT':
161+
case 'LONG':
162+
case 'LONGLONG':
163+
case 'INT24':
164+
return 'i';
165+
}
166+
return $type;
167+
}
168+
169+
/**
170+
* @param array $row
171+
* @param array $columnDefinitions
172+
* @return mixed
173+
*/
174+
private function convertValues(array $row, array $columnDefinitions) {
175+
foreach($row as $key => &$value) {
176+
$value = $this->convertValue($value, $columnDefinitions[$key]);
177+
}
178+
return $row;
179+
}
180+
181+
/**
182+
* @param mixed $value
183+
* @param string $type
184+
* @return mixed
185+
*/
186+
private function convertValue($value, $type) {
187+
switch ($type) {
188+
case 'i':
189+
return (int) $value;
190+
case 'f':
191+
return (float) $value;
192+
}
193+
return $value;
66194
}
67195
}

src/Kir/MySQL/Database.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ interface Database {
1010
*/
1111
public function query($query);
1212

13+
/**
14+
* @param string $query
15+
* @return PDOStatement
16+
*/
17+
public function prepare($query);
18+
1319
/**
1420
* @param string $query
1521
* @return int
@@ -66,4 +72,5 @@ public function update();
6672
* @return Builder\RunnableDelete
6773
*/
6874
public function delete();
75+
6976
}

src/Kir/MySQL/Databases/MySQL.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ public function query($query) {
4141
return $stmt;
4242
}
4343

44+
/**
45+
* @param string $query
46+
* @throws Exception
47+
* @return PDOStatement
48+
*/
49+
public function prepare($query) {
50+
$stmt = $this->pdo->prepare($query);
51+
if(!$stmt) {
52+
throw new Exception("Could not execute statement:\n{$query}");
53+
}
54+
return $stmt;
55+
}
56+
4457
/**
4558
* @param string $query
4659
* @return int

tests/Kir/MySQL/Databases/Mock.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public function query($query) {
2727
return null;
2828
}
2929

30+
/**
31+
* @param string $query
32+
* @return PDOStatement
33+
*/
34+
public function prepare($query) {
35+
return null;
36+
}
37+
3038
/**
3139
* @param string $query
3240
* @return int

0 commit comments

Comments
 (0)