Schema::TYPE_SMALLINT, 'INT24' => Schema::TYPE_INTEGER, 'LONG' => Schema::TYPE_INTEGER, 'LONGLONG' => Schema::TYPE_BIGINT, 'NEWDECIMAL' => Schema::TYPE_DECIMAL, 'FLOAT' => Schema::TYPE_FLOAT, 'DOUBLE' => Schema::TYPE_FLOAT, 'STRING' => Schema::TYPE_STRING, 'VAR_STRING' => Schema::TYPE_STRING, 'BLOB' => Schema::TYPE_STRING, 'DATE' => Schema::TYPE_DATE, 'DATETIME' => Schema::TYPE_DATETIME, 'TIMESTAMP' => Schema::TYPE_TIMESTAMP, 'TIME' => Schema::TYPE_TIME, ]; public function queryAll($fetchMode = null) { $result = $this->queryInternal('fetchAll', $fetchMode); if ($this->castResult) { $result = $this->convertList($result); } return $result; } public function queryOne($fetchMode = null) { $result = $this->queryInternal('fetch', $fetchMode); if ($this->castResult) { $result = $this->convertRow($result); } return $result; } public function queryScalar() { $result = $this->queryInternal('fetchColumn', 0); if (is_resource($result) && get_resource_type($result) === 'stream') { $result = stream_get_contents($result); } if ($this->castResult) { $result = $this->convertOne($result); } return $result; } private function queryInternal($method, $fetchMode = null) { $rawSql = $this->getRawSql(); $token = $rawSql; try { yii::beginProfile($token, __METHOD__); $this->prepare(); $this->pdoStatement->execute(); if ($method === '') { $result = new DataReader($this); } else { if ($fetchMode === null) { $fetchMode = $this->fetchMode; } $result = call_user_func_array([$this->pdoStatement, $method], (array)$fetchMode); if ($this->castResult) { $this->typeList = $this->getResultTypeList($this); } $this->pdoStatement->closeCursor(); } yii::endProfile($token, __METHOD__); return $result; } catch (\Exception $e) { yii::endProfile($token, __METHOD__); if ($e instanceof Exception) { throw $e; } else { $message = $e->getMessage() . "\nThe SQL being executed was: $rawSql"; $errorInfo = $e instanceof \PDOException ? $e->errorInfo : null; throw new Exception($message, $errorInfo, (int)$e->getCode(), $e); } } } public function getResultTypeList() { if (0 == ($count = $this->pdoStatement->columnCount())) { return null; } $result = []; for ($i = 0; $i < $count; ++$i) { $meta = $this->pdoStatement->getColumnMeta($i); $name = $meta['name']; $type = (isset($meta['native_type']) && isset(static::$dataMap[$meta['native_type']])) ? static::$dataMap[$meta['native_type']] : null; $result[$name] = $type; } return $result; } public static function typecast($value, $type) { if (null === $value) { return null; } switch ($type) { case Schema::TYPE_SMALLINT: case Schema::TYPE_INTEGER: case Schema::TYPE_BIGINT: $value = (int)$value; break; case Schema::TYPE_DECIMAL: case Schema::TYPE_FLOAT: $value = (float)$value; break; case Schema::TYPE_DATE: case Schema::TYPE_DATETIME: case Schema::TYPE_TIMESTAMP: case Schema::TYPE_TIME: $value = (string)$value; break; case Schema::TYPE_BOOLEAN: $value = (boolean)$value; break; case Schema::TYPE_STRING: $value = (string)$value; break; default: // pass } return $value; } protected function convertOne($mixed) { if ($this->castResult && $this->typeList) { $mixed = static::typecast($mixed, reset($this->typeList)); } return $mixed; } protected function convertRow($row) { if ($this->castResult && $this->typeList) { foreach ($row as $idx => $value) { $row[$idx] = static::typecast($value, $this->typeList[$idx]); } } return $row; } protected function convertList($list) { if ($this->castResult && $this->typeList) { foreach ($list as $idx => $row) { $list[$idx] = static::convertRow($row); } } return $list; } }