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