From c79f4a1475399f065d885a3cec1bdb89541938c0 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 13 Oct 2015 20:39:54 +0200 Subject: [PATCH] MySQL drivers: type TIME is returned as DateInterval (BC break) [Closes #168] --- src/Dibi/Drivers/MySqlDriver.php | 1 + src/Dibi/Drivers/MySqliDriver.php | 1 + src/Dibi/Drivers/PdoDriver.php | 1 + src/Dibi/Result.php | 7 ++++++- src/Dibi/Type.php | 3 ++- tests/dibi/mysql-pdo.time.phpt | 17 +++++++++++++++++ tests/dibi/mysql.time.phpt | 17 +++++++++++++++++ tests/dibi/mysqli.time.phpt | 17 +++++++++++++++++ 8 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/dibi/mysql-pdo.time.phpt create mode 100644 tests/dibi/mysql.time.phpt create mode 100644 tests/dibi/mysqli.time.phpt diff --git a/src/Dibi/Drivers/MySqlDriver.php b/src/Dibi/Drivers/MySqlDriver.php index 6d2f215e..accefe2f 100644 --- a/src/Dibi/Drivers/MySqlDriver.php +++ b/src/Dibi/Drivers/MySqlDriver.php @@ -455,6 +455,7 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver 'table' => $row['table'], 'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'], 'nativetype' => strtoupper($row['type']), + 'type' => $row['type'] === 'time' ? Dibi\Type::TIME_INTERVAL : NULL, 'vendor' => $row, ]; } diff --git a/src/Dibi/Drivers/MySqliDriver.php b/src/Dibi/Drivers/MySqliDriver.php index cd10a8a8..b3e1f4b5 100644 --- a/src/Dibi/Drivers/MySqliDriver.php +++ b/src/Dibi/Drivers/MySqliDriver.php @@ -477,6 +477,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver 'table' => $row['orgtable'], 'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'], 'nativetype' => isset($types[$row['type']]) ? $types[$row['type']] : $row['type'], + 'type' => $row['type'] === MYSQLI_TYPE_TIME ? Dibi\Type::TIME_INTERVAL : NULL, 'vendor' => $row, ]; } diff --git a/src/Dibi/Drivers/PdoDriver.php b/src/Dibi/Drivers/PdoDriver.php index 147c5358..ab74c351 100644 --- a/src/Dibi/Drivers/PdoDriver.php +++ b/src/Dibi/Drivers/PdoDriver.php @@ -523,6 +523,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver 'name' => $row['name'], 'table' => $row['table'], 'nativetype' => $row['native_type'], + 'type' => $row['native_type'] === 'TIME' && $this->driverName === 'mysql' ? Dibi\Type::TIME_INTERVAL : NULL, 'fullname' => $row['table'] ? $row['table'] . '.' . $row['name'] : $row['name'], 'vendor' => $row, ]; diff --git a/src/Dibi/Result.php b/src/Dibi/Result.php index d49cb11d..69ea0110 100644 --- a/src/Dibi/Result.php +++ b/src/Dibi/Result.php @@ -471,7 +471,7 @@ class Result implements IDataSource $cache = Helpers::getTypeCache(); try { foreach ($this->getResultDriver()->getResultColumns() as $col) { - $this->types[$col['name']] = $cache->{$col['nativetype']}; + $this->types[$col['name']] = isset($col['type']) ? $col['type'] : $cache->{$col['nativetype']}; } } catch (NotSupportedException $e) { } @@ -522,6 +522,11 @@ class Result implements IDataSource $row[$key] = NULL; } + } elseif ($type === Type::TIME_INTERVAL) { + preg_match('#^(-?)(\d+)\D(\d+)\D(\d+)\z#', $value, $m); + $row[$key] = new \DateInterval("PT$m[2]H$m[3]M$m[4]S"); + $row[$key]->invert = (int) (bool) $m[1]; + } elseif ($type === Type::BINARY) { $row[$key] = $this->getResultDriver()->unescapeBinary($value); } diff --git a/src/Dibi/Type.php b/src/Dibi/Type.php index 5295d584..801e5ee4 100644 --- a/src/Dibi/Type.php +++ b/src/Dibi/Type.php @@ -21,7 +21,8 @@ class Type FLOAT = 'f', DATE = 'd', DATETIME = 't', - TIME = 't'; + TIME = 't', + TIME_INTERVAL = 'ti'; final public function __construct() { diff --git a/tests/dibi/mysql-pdo.time.phpt b/tests/dibi/mysql-pdo.time.phpt new file mode 100644 index 00000000..1b09290f --- /dev/null +++ b/tests/dibi/mysql-pdo.time.phpt @@ -0,0 +1,17 @@ +query('USE dibi_test'); +$conn->query('DROP TABLE IF EXISTS timetest'); +$conn->query('CREATE TABLE timetest (col TIME NOT NULL) ENGINE=InnoDB'); +$conn->query('INSERT INTO timetest VALUES ("12:30:40")'); +Assert::equal(new DateInterval('PT12H30M40S'), $conn->fetchSingle('SELECT * FROM timetest')); diff --git a/tests/dibi/mysql.time.phpt b/tests/dibi/mysql.time.phpt new file mode 100644 index 00000000..cb7b7656 --- /dev/null +++ b/tests/dibi/mysql.time.phpt @@ -0,0 +1,17 @@ +query('USE dibi_test'); +$conn->query('DROP TABLE IF EXISTS timetest'); +$conn->query('CREATE TABLE timetest (col TIME NOT NULL) ENGINE=InnoDB'); +$conn->query('INSERT INTO timetest VALUES ("12:30:40")'); +Assert::equal(new DateInterval('PT12H30M40S'), $conn->fetchSingle('SELECT * FROM timetest')); diff --git a/tests/dibi/mysqli.time.phpt b/tests/dibi/mysqli.time.phpt new file mode 100644 index 00000000..dcd50fe0 --- /dev/null +++ b/tests/dibi/mysqli.time.phpt @@ -0,0 +1,17 @@ +query('USE dibi_test'); +$conn->query('DROP TABLE IF EXISTS timetest'); +$conn->query('CREATE TABLE timetest (col TIME NOT NULL) ENGINE=InnoDB'); +$conn->query('INSERT INTO timetest VALUES ("12:30:40")'); +Assert::equal(new DateInterval('PT12H30M40S'), $conn->fetchSingle('SELECT * FROM timetest'));