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