1
0
mirror of https://github.com/dg/dibi.git synced 2025-07-30 19:00:13 +02:00

DibiConnection: types detection + normalization is always TRUE

This commit is contained in:
David Grudl
2012-01-11 23:01:10 +01:00
parent e60dc2d2d0
commit baf08d3c71
4 changed files with 93 additions and 118 deletions

View File

@@ -50,7 +50,6 @@ class DibiConnection extends DibiObject
* Connection options: (see driver-specific options too)
* - lazy (bool) => if TRUE, connection will be established only when required
* - result (array) => result set options
* - detectTypes (bool) => detect the types of result set fields?
* - formatDateTime => date-time format (if empty, DateTime objects will be returned)
* - profiler (array or bool)
* - run (bool) => enable profiler?
@@ -81,7 +80,6 @@ class DibiConnection extends DibiObject
self::alias($config, 'username', 'user');
self::alias($config, 'password', 'pass');
self::alias($config, 'host', 'hostname');
self::alias($config, 'result|detectTypes', 'resultDetectTypes'); // back compatibility
self::alias($config, 'result|formatDateTime', 'resultDateTime');
if (!isset($config['driver'])) {

View File

@@ -534,10 +534,7 @@ class DibiColumnInfo extends DibiObject
*/
public function getType()
{
if (self::$types === NULL) {
self::$types = new DibiHashMap(array(__CLASS__, 'detectType'));
}
return self::$types->{$this->info['nativetype']};
return self::getTypeCache()->{$this->info['nativetype']};
}
@@ -640,6 +637,19 @@ class DibiColumnInfo extends DibiObject
return dibi::TEXT;
}
/**
* @internal
*/
public static function getTypeCache()
{
if (self::$types === NULL) {
self::$types = new DibiHashMap(array(__CLASS__, 'detectType'));
}
return self::$types;
}
}

View File

@@ -43,7 +43,7 @@ class DibiResult extends DibiObject implements IDataSource
private $driver;
/** @var array Translate table */
private $types;
private $types = array();
/** @var DibiResultInfo */
private $meta;
@@ -66,10 +66,7 @@ class DibiResult extends DibiObject implements IDataSource
public function __construct($driver, $config)
{
$this->driver = $driver;
if (!empty($config['detectTypes'])) {
$this->detectTypes();
}
$this->detectTypes();
if (!empty($config['formatDateTime'])) {
$this->dateFormat = is_string($config['formatDateTime']) ? $config['formatDateTime'] : '';
@@ -220,19 +217,11 @@ class DibiResult extends DibiObject implements IDataSource
final public function fetch()
{
$row = $this->getDriver()->fetch(TRUE);
if (!is_array($row)) return FALSE;
$this->fetched = TRUE;
// types-converting?
if ($this->types !== NULL) {
foreach ($this->types as $col => $type) {
if (isset($row[$col])) {
$row[$col] = $this->convert($row[$col], $type);
}
}
if (!is_array($row)) {
return FALSE;
}
$this->fetched = TRUE;
$this->normalize($row);
return new $this->rowClass($row);
}
@@ -245,17 +234,12 @@ class DibiResult extends DibiObject implements IDataSource
final public function fetchSingle()
{
$row = $this->getDriver()->fetch(TRUE);
if (!is_array($row)) return FALSE;
$this->fetched = TRUE;
$value = reset($row);
// types-converting?
$key = key($row);
if (isset($this->types[$key])) {
return $this->convert($value, $this->types[$key]);
if (!is_array($row)) {
return FALSE;
}
return $value;
$this->fetched = TRUE;
$this->normalize($row);
return reset($row);
}
@@ -495,7 +479,71 @@ class DibiResult extends DibiObject implements IDataSource
/********************* meta info ****************d*g**/
/********************* column types ****************d*g**/
/**
* Autodetect column types.
* @return void
*/
private function detectTypes()
{
$cache = DibiColumnInfo::getTypeCache();
try {
foreach ($this->getDriver()->getResultColumns() as $col) {
$this->types[$col['name']] = $cache->{$col['nativetype']};
}
} catch (DibiNotSupportedException $e) {}
}
/**
* Converts values to specified type and format.
* @param array
* @return void
*/
private function normalize(array & $row)
{
foreach ($this->types as $key => $type) {
if (!isset($row[$key])) { // NULL
continue;
}
$value = $row[$key];
if ($value === FALSE || $type === dibi::TEXT) {
} elseif ($type === dibi::INTEGER) {
$row[$key] = is_float($tmp = $value * 1) ? $value : $tmp;
} elseif ($type === dibi::FLOAT) {
$row[$key] = (string) ($tmp = (float) $value) === $value ? $tmp : $value;
} elseif ($type === dibi::BOOL) {
$row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F';
} elseif ($type === dibi::DATE || $type === dibi::DATETIME) {
if ((int) $value === 0) { // '', NULL, FALSE, '0000-00-00', ...
} elseif ($this->dateFormat === '') { // return DateTime object (default)
$row[$key] = new DibiDateTime(is_numeric($value) ? date('Y-m-d H:i:s', $value) : $value);
} elseif ($this->dateFormat === 'U') { // return timestamp
$row[$key] = is_numeric($value) ? (int) $value : strtotime($value);
} elseif (is_numeric($value)) { // formatted date
$row[$key] = date($this->dateFormat, $value);
} else {
$value = new DibiDateTime($value);
$row[$key] = $value->format($this->dateFormat);
}
} elseif ($type === dibi::BINARY) {
$row[$key] = $this->getDriver()->unescape($value, $type);
}
}
}
@@ -513,33 +561,6 @@ class DibiResult extends DibiObject implements IDataSource
/**
* Autodetect column types.
* @return void
*/
final public function detectTypes()
{
foreach ($this->getInfo()->getColumns() as $col) {
$this->types[$col->getName()] = $col->getType();
}
}
/**
* Define multiple columns types.
* @param array
* @return DibiResult provides a fluent interface
* @internal
*/
final public function setTypes(array $types)
{
$this->types = $types;
return $this;
}
/**
* Returns column type.
* @return string
@@ -551,57 +572,7 @@ class DibiResult extends DibiObject implements IDataSource
/**
* Converts value to specified type and format.
* @param mixed value
* @param int type
* @return mixed
*/
protected function convert($value, $type)
{
if ($value === NULL || $value === FALSE) {
return NULL;
}
switch ($type) {
case dibi::TEXT:
return (string) $value;
case dibi::BINARY:
return $this->getDriver()->unescape($value, $type);
case dibi::INTEGER:
return is_float($tmp = $value * 1) ? $value : $tmp;
case dibi::FLOAT:
return (float) $value;
case dibi::DATE:
case dibi::DATETIME:
if ((int) $value === 0) { // '', NULL, FALSE, '0000-00-00', ...
return NULL;
} elseif ($this->dateFormat === '') { // return DateTime object (default)
return new DibiDateTime(is_numeric($value) ? date('Y-m-d H:i:s', $value) : $value);
} elseif ($this->dateFormat === 'U') { // return timestamp
return is_numeric($value) ? (int) $value : strtotime($value);
} elseif (is_numeric($value)) { // formatted date
return date($this->dateFormat, $value);
} else {
$value = new DibiDateTime($value);
return $value->format($this->dateFormat);
}
case dibi::BOOL:
return ((bool) $value) && $value !== 'f' && $value !== 'F';
default:
return $value;
}
}
/********************* meta info ****************d*g**/
@@ -629,9 +600,7 @@ class DibiResult extends DibiObject implements IDataSource
/**
* @deprecated
*/
/** @deprecated */
public function getColumnNames($fullNames = FALSE)
{
trigger_error(__METHOD__ . '() is deprecated; use $res->getInfo()->getColumnNames() instead.', E_USER_WARNING);

View File

@@ -20,7 +20,7 @@ dibi::connect(array(
$res = dibi::query('SELECT * FROM [customers]');
$res->setType('customer_id', Dibi::INTEGER)
->setType('added', Dibi::DATETIME, 'H:i j.n.Y');
->setType('added', Dibi::DATETIME);
Debugger::dump( $res->fetch() );
// outputs:
@@ -35,8 +35,6 @@ Debugger::dump( $res->fetch() );
// using auto-detection (works well with MySQL or other strictly typed databases)
$res = dibi::query('SELECT * FROM [customers]');
$res->detectTypes();
Debugger::dump( $res->fetch() );
// outputs:
// object(DibiRow)#3 (3) {