* @package Mammut\DB\Adapter\MSSQL */ class Result extends \Mammut\DB\Result { private $result; private $linkid; private $row = 0; private $skipped; private $apiver; private $cols; private $colids; // column name => id map private $ccount; public function __construct($linkid, $result, $skipped = 0, $api = 1) { $this->linkid = $linkid; $this->result = $result; $this->skipped = $skipped; $this->apiver = $api; $this->ccount = $this->getColumnCount(); if($this->apiver == 1) { for($i = 0; $i < $this->ccount; $i++) { $this->cols[$i]['name'] = strtolower(mssql_field_name($this->result, $i)); $this->cols[$i]['type'] = $this->mstype2mftype(strtolower(mssql_field_type($this->result, $i))); $this->colids[$this->cols[$i]['name']] = $i; } } else { $meta = sqlsrv_field_metadata($this->result); foreach($meta as $i=>$info) { $this->cols[$i]['name'] = strtolower($info['Name']); $this->cols[$i]['type'] = $this->mstype2mftype(strtolower($info['Type'])); $this->colids[$info['Name']] = $i; } } } protected function mstype2mftype($type) { switch($type) { case 'bit': return ColumnInfo::TYPE_BOOLEAN; case 'blob': return ColumnInfo::TYPE_BINARY; case 'image': return ColumnInfo::TYPE_BLOB; } return $type; } /** * * @see lib/Mammut/DB/MFDBResult#getRowNumber() */ public function getRowNumber() { return $this->row; } /** * * @return ColumnInfo a info object for $column, which could be a string or * integer */ public function getColumnInfo($column) { if(is_int($column)) $info = new ColumnInfo($this->cols[$column]['name'], $this->cols[$column]['type']); else { $id = (int) $this->colids[$column]; $info = new ColumnInfo($this->cols[$id]['name'], $this->cols[$id]['type']); } return $info; } /** * * @return int the size of the result set */ public function getRowCount() { return $this->apiver == 1 ? mssql_num_rows($this->result) - $this->skipped : sqlsrv_num_rows($this->result) - $this->skipped; } /** * * @return array a list of column names */ public function getColumns() { return array_keys($this->colids); } public function getColumnCount() { return $this->apiver == 1 ? mssql_num_fields($this->result) : sqlsrv_num_fields($this->result); } /** * fetches the next dataset as an numbered array * * @return array the next dataset */ public function fetchRow() { $this->row++; $result = $this->apiver == 1 ? mssql_fetch_row($this->result) : sqlsrv_fetch_array($this->result, SQLSRV_FETCH_NUMERIC); // fix datatypes if($result) { for($i = 0; $i < $this->ccount; $i++) { switch($this->cols[$i]['type']) { case ColumnInfo::TYPE_BOOLEAN: $result[$i] = ($result[$i] == 1); break; case ColumnInfo::TYPE_DATETIME: $result[$i] = new \DateTime($result[$i]); break; } } } return $result; } /** * fetches the next dataset as an associative array * * @return array the next dataset */ public function fetchArray() { $this->row++; $result = $this->apiver == 1 ? mssql_fetch_assoc($this->result) : sqlsrv_fetch_array($this->result, SQLSRV_FETCH_ASSOC); // fix datatypes if($result) { for($i = 0; $i < $this->ccount; $i++) { $name = $this->cols[$i]['name']; switch($this->cols[$i]['type']) { case ColumnInfo::TYPE_BOOLEAN: $result[$name] = ($result[$name] == 1); break; case ColumnInfo::TYPE_DATETIME: $result[$name] = new \DateTime($result[$name]); break; } } } return $result; } /** * fetches the next dataset as an object * * @param string $class * optional base class which should be used * @param array $param * for the constructor * @return object next dataset */ public function fetchObject($class = false, $param = array()) { $this->row++; if($class != false) { if($this->apiver == 2) $result = sqlsrv_fetch_object($this->result, $class, $param); else { if(class_exists($class)) $obj = new $class(); else throw new \InvalidArgumentException("Invalid class: $class"); $row = mssql_fetch_assoc($this->result); if($row === false) return false; foreach(array_keys($row) as $k) $obj->$k = $row[$k]; $result = $obj; } } else $result = $this->apiver == 1 ? mssql_fetch_object($this->result) : sqlsrv_fetch_object($this->result); // fix datatypes if($result) { for($i = 0; $i < $this->ccount; $i++) { $name = $this->cols[$i]['name']; switch($this->cols[$i]['type']) { case ColumnInfo::TYPE_BOOLEAN: $result->$name = ($result->$name == 1); break; case ColumnInfo::TYPE_DATETIME: $result->$name = new \DateTime($result->$name); break; } } } return $result; } /** * closes the result set and frees all resources * * @return void */ public function close() { $this->apiver == 1 && is_resource($this->result) ? mssql_free_result($this->result) : sqlsrv_free_stmt($this->result); } }