FIX: Correct type coercion of MySQL

This commit is contained in:
Sam Minnee 2018-11-11 13:54:03 +13:00
parent adb6e9eb8d
commit 45e1fcaf30
2 changed files with 36 additions and 3 deletions

View File

@ -4,6 +4,7 @@ namespace SilverStripe\ORM\Connect;
/**
* A result-set from a MySQL database (using MySQLiConnector)
* Note that this class is only used for the results of non-prepared statements
*/
class MySQLQuery extends Query
{
@ -17,6 +18,11 @@ class MySQLQuery extends Query
*/
protected $handle;
/**
* Metadata about the columns of this query
*/
protected $columns;
/**
* Hook the result-set given into a Query class, suitable for use by SilverStripe.
*
@ -27,6 +33,9 @@ class MySQLQuery extends Query
public function __construct($database, $handle)
{
$this->handle = $handle;
if (is_object($this->handle)) {
$this->columns = $this->handle->fetch_fields();
}
}
public function __destruct()
@ -40,7 +49,7 @@ class MySQLQuery extends Query
{
if (is_object($this->handle)) {
$this->handle->data_seek($row);
return $this->handle->fetch_assoc();
return $this->nextRecord();
}
return null;
}
@ -55,7 +64,19 @@ class MySQLQuery extends Query
public function nextRecord()
{
if (is_object($this->handle) && ($data = $this->handle->fetch_assoc())) {
$floatTypes = [MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE, MYSQLI_TYPE_DECIMAL, MYSQLI_TYPE_NEWDECIMAL];
if (is_object($this->handle) && ($row = $this->handle->fetch_array(MYSQLI_NUM))) {
$data = [];
foreach ($row as $i => $value) {
if (!isset($this->columns[$i])) {
throw new DatabaseException("Can't get metadata for column $i");
}
if (in_array($this->columns[$i]->type, $floatTypes)) {
$value = (float)$value;
}
$data[$this->columns[$i]->name] = $value;
}
return $data;
} else {
return false;

View File

@ -6,7 +6,7 @@ use mysqli_result;
use mysqli_stmt;
/**
* Provides a record-view for mysqli statements
* Provides a record-view for mysqli prepared statements
*
* By default streams unbuffered data, but seek(), rewind(), or numRecords() will force the statement to
* buffer itself and sacrifice any potential performance benefit.
@ -42,6 +42,13 @@ class MySQLStatement extends Query
*/
protected $columns = array();
/**
* Map of column types, keyed by column name
*
* @var array
*/
protected $types = array();
/**
* List of bound variables in the current row
*
@ -59,6 +66,7 @@ class MySQLStatement extends Query
// Bind each field
while ($field = $this->metadata->fetch_field()) {
$this->columns[] = $field->name;
$this->types[$field->name] = $field->type;
// Note that while boundValues isn't initialised at this point,
// later calls to $this->statement->fetch() Will populate
// $this->boundValues later with the next result.
@ -116,6 +124,10 @@ class MySQLStatement extends Query
// Dereferenced row
$row = array();
foreach ($this->boundValues as $key => $value) {
$floatTypes = [MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE, MYSQLI_TYPE_DECIMAL, MYSQLI_TYPE_NEWDECIMAL];
if (in_array($this->types[$key], $floatTypes)) {
$value = (float)$value;
}
$row[$key] = $value;
}
return $row;