1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: class Statement extends PDOStatement
22: {
23:
24: private $connection;
25:
26:
27: public $time;
28:
29:
30: private $types;
31:
32:
33:
34: protected function __construct(Connection $connection)
35: {
36: $this->connection = $connection;
37: $this->setFetchMode(PDO::FETCH_CLASS, 'Row', array($this));
38: }
39:
40:
41:
42: 43: 44:
45: public function getConnection()
46: {
47: return $this->connection;
48: }
49:
50:
51:
52: 53: 54: 55: 56:
57: public function execute($params = array())
58: {
59: static $types = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT,
60: 'resource' => PDO::PARAM_LOB, 'NULL' => PDO::PARAM_NULL);
61:
62: foreach ($params as $key => $value) {
63: $type = gettype($value);
64: $this->bindValue(is_int($key) ? $key + 1 : $key, $value, isset($types[$type]) ? $types[$type] : PDO::PARAM_STR);
65: }
66:
67: $time = microtime(TRUE);
68: try {
69: parent::execute();
70: } catch (PDOException $e) {
71: $e->queryString = $this->queryString;
72: throw $e;
73: }
74: $this->time = microtime(TRUE) - $time;
75: $this->connection->__call('onQuery', array($this, $params));
76:
77: return $this;
78: }
79:
80:
81:
82: 83: 84: 85:
86: public function fetchPairs()
87: {
88: return $this->fetchAll(PDO::FETCH_KEY_PAIR);
89: }
90:
91:
92:
93: 94: 95: 96: 97:
98: public function normalizeRow($row)
99: {
100: if ($this->types === NULL) {
101: $this->types = array();
102: if ($this->connection->getSupplementalDriver()->supports['meta']) {
103: $col = 0;
104: foreach ($row as $key => $foo) {
105: $type = $this->getColumnMeta($col++);
106: if (isset($type['native_type'])) {
107: $this->types[$key] = DatabaseReflection::detectType($type['native_type']);
108: }
109: }
110: }
111: }
112:
113: foreach ($this->types as $key => $type) {
114: $value = $row[$key];
115: if ($value === NULL || $value === FALSE || $type === DatabaseReflection::FIELD_TEXT) {
116:
117: } elseif ($type === DatabaseReflection::FIELD_INTEGER) {
118: $row[$key] = is_float($tmp = $value * 1) ? $value : $tmp;
119:
120: } elseif ($type === DatabaseReflection::FIELD_FLOAT) {
121: $row[$key] = (string) ($tmp = (float) $value) === $value ? $tmp : $value;
122:
123: } elseif ($type === DatabaseReflection::FIELD_BOOL) {
124: $row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F';
125: }
126: }
127:
128: return $this->connection->getSupplementalDriver()->normalizeRow($row, $this);
129: }
130:
131:
132:
133:
134:
135:
136:
137: 138: 139: 140:
141: public function dump()
142: {
143: echo "\n<table class=\"dump\">\n<caption>" . htmlSpecialChars($this->queryString) . "</caption>\n";
144: if (!$this->columnCount()) {
145: echo "\t<tr>\n\t\t<th>Affected rows:</th>\n\t\t<td>", $this->rowCount(), "</td>\n\t</tr>\n</table>\n";
146: return;
147: }
148: $i = 0;
149: foreach ($this as $row) {
150: if ($i === 0) {
151: echo "<thead>\n\t<tr>\n\t\t<th>#row</th>\n";
152: foreach ($row as $col => $foo) {
153: echo "\t\t<th>" . htmlSpecialChars($col) . "</th>\n";
154: }
155: echo "\t</tr>\n</thead>\n<tbody>\n";
156: }
157: echo "\t<tr>\n\t\t<th>", $i, "</th>\n";
158: foreach ($row as $col) {
159:
160: echo "\t\t<td>", htmlSpecialChars($col), "</td>\n";
161: }
162: echo "\t</tr>\n";
163: $i++;
164: }
165:
166: if ($i === 0) {
167: echo "\t<tr>\n\t\t<td><em>empty result set</em></td>\n\t</tr>\n</table>\n";
168: } else {
169: echo "</tbody>\n</table>\n";
170: }
171: }
172:
173:
174:
175:
176:
177:
178:
179: 180: 181:
182: public function getReflection()
183: {
184: return new ClassReflection($this);
185: }
186:
187:
188:
189: public function __call($name, $args)
190: {
191: return ObjectMixin::call($this, $name, $args);
192: }
193:
194:
195:
196: public function &__get($name)
197: {
198: return ObjectMixin::get($this, $name);
199: }
200:
201:
202:
203: public function __set($name, $value)
204: {
205: return ObjectMixin::set($this, $name, $value);
206: }
207:
208:
209:
210: public function __isset($name)
211: {
212: return ObjectMixin::has($this, $name);
213: }
214:
215:
216:
217: public function __unset($name)
218: {
219: ObjectMixin::remove($this, $name);
220: }
221:
222: }
223: