5
5
use PDO ;
6
6
use PDOStatement ;
7
7
8
+ /**
9
+ */
8
10
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
+
9
57
/**
10
58
* @param Closure $callback
11
59
* @return array[]
12
60
*/
13
61
public function fetchRows (Closure $ callback = null ) {
14
62
$ statement = $ this ->createStatement ();
63
+ $ statement ->execute ($ this ->values );
15
64
$ data = $ statement ->fetchAll (PDO ::FETCH_ASSOC );
16
65
if ($ callback !== null ) {
17
66
$ data = array_map ($ callback , $ data );
18
67
}
19
68
$ 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
+
20
77
return $ data ;
21
78
}
22
79
@@ -25,10 +82,18 @@ public function fetchRows(Closure $callback = null) {
25
82
*/
26
83
public function fetchRow () {
27
84
$ statement = $ this ->createStatement ();
85
+ $ statement ->execute ($ this ->values );
28
86
$ row = $ statement ->fetch (PDO ::FETCH_ASSOC );
29
87
if (!is_array ($ row )) {
30
88
return array ();
31
89
}
90
+ if ($ this ->preserveTypes ) {
91
+ $ columnDefinitions = $ this ->getFieldTypes ($ statement );
92
+ $ row = $ this ->convertValues ($ row , $ columnDefinitions );
93
+ }
94
+
95
+ $ statement ->closeCursor ();
96
+
32
97
return $ row ;
33
98
}
34
99
@@ -48,6 +113,7 @@ public function fetchArray() {
48
113
*/
49
114
public function fetchValue ($ default = null ) {
50
115
$ statement = $ this ->createStatement ();
116
+ $ statement ->execute ($ this ->values );
51
117
$ row = $ statement ->fetch (PDO ::FETCH_ASSOC );
52
118
if (!is_array ($ row )) {
53
119
return $ default ;
@@ -62,6 +128,68 @@ public function fetchValue($default = null) {
62
128
* @return PDOStatement
63
129
*/
64
130
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 ;
66
194
}
67
195
}
0 commit comments