diff --git a/lib/Cake/Model/Datasource/Database/Driver/Postgres.php b/lib/Cake/Model/Datasource/Database/Driver/Postgres.php new file mode 100644 index 00000000000..c33bca327dc --- /dev/null +++ b/lib/Cake/Model/Datasource/Database/Driver/Postgres.php @@ -0,0 +1,97 @@ + true, + 'host' => 'localhost', + 'login' => 'root', + 'password' => '', + 'database' => 'cake', + 'schema' => 'public', + 'port' => 5432, + 'encoding' => 'utf8', + 'flags' => array(), + 'dsn' => null + ]; + +/** + * Establishes a connection to the databse server + * + * @param array $config configuration to be used for creating connection + * @return boolean true on success + **/ + public function connect(array $config) { + $config += $this->_baseConfig; + $config['flags'] += [ + PDO::ATTR_PERSISTENT => $config['persistent'], + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + ]; + + if (empty($config['dsn'])) { + $config['dsn'] = "pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']}"; + } + + $this->_connect($config); + if (!empty($config['encoding'])) { + $this->setEncoding($config['encoding']); + } + if (!empty($config['schema'])) { + $this->setSchema($config['schema']); + } + return true; + } + +/** + * Returns whether php is able to use this driver for connecting to database + * + * @return boolean true if it is valid to use this driver + **/ + + public function enabled() { + return in_array('sqlite', PDO::getAvailableDrivers()); + } + +/** + * Prepares a sql statement to be executed + * + * @param string $sql + * @return Cake\Model\Datasource\Database\Statement + **/ + public function prepare($sql) { + $statement = $this->connection()->prepare($sql); + return new Statement($statement, $this); + } + +/** + * Sets connection encoding + * + * @return void + **/ + public function setEncoding($encoding) { + $this->_connection->exec('SET NAMES ' . $this->_connection->quote($encoding)); + } + +/** + * Sets connection default schema, if any relation defined in a query is not fully qualified + * postgres will fallback to looking the relation into defined default schema + * + * @return void + **/ + public function setSchema($schema) { + $this->_connection->exec('SET search_path TO ' . $this->_connection->quote($schema)); + } + +} diff --git a/lib/Cake/Model/Datasource/Database/Driver/Sqlite.php b/lib/Cake/Model/Datasource/Database/Driver/Sqlite.php index 660480db7a5..8f690221c13 100644 --- a/lib/Cake/Model/Datasource/Database/Driver/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Driver/Sqlite.php @@ -29,7 +29,7 @@ class Sqlite extends \Cake\Model\Datasource\Database\Driver { * @return boolean true on success **/ public function connect(array $config) { - $config = $this->_baseConfig + array('login' => null, 'password' => null); + $config += $this->_baseConfig + array('login' => null, 'password' => null); $config['flags'] += [ PDO::ATTR_PERSISTENT => $config['persistent'], PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION diff --git a/lib/Cake/Model/Datasource/Database/Type.php b/lib/Cake/Model/Datasource/Database/Type.php index ea3329cb71b..2554aba2c12 100644 --- a/lib/Cake/Model/Datasource/Database/Type.php +++ b/lib/Cake/Model/Datasource/Database/Type.php @@ -34,10 +34,10 @@ class Type { * @var array **/ protected static $_basicTypes = [ - 'float' => ['php' => 'floatval'], - 'integer' => ['php' => 'intval', 'pdo' => PDO::PARAM_INT], - 'string' => ['php' => 'strval'], - 'text' => ['php' => 'strval'], + 'float' => ['callback' => 'floatval'], + 'integer' => ['callback' => 'intval', 'pdo' => PDO::PARAM_INT], + 'string' => ['callback' => 'strval'], + 'text' => ['callback' => 'strval'], ]; /** @@ -134,7 +134,7 @@ public function getName() { * @return mixed **/ public function toDatabase($value, Driver $driver) { - return $value; + return $this->_basicTypeCast($value, $driver); } /** @@ -145,11 +145,22 @@ public function toDatabase($value, Driver $driver) { * @return mixed **/ public function toPHP($value, Driver $driver) { + return $this->_basicTypeCast($value, $driver); + } + +/** + * Checks whether this type is a basic one and can be converted using a callback + * If it is, returns converted value + * + * @param mixed $value value to be converted to PHP equivalent + * @param Driver $driver object from which database preferences and configuration will be extracted + * @return mixed + **/ + protected function _basicTypeCast($value, Driver $driver) { if (!empty(self::$_basicTypes[$this->_name])) { $typeInfo = self::$_basicTypes[$this->_name]; - $value = ($value === null) ? null : $value; - if (isset($typeInfo['php'])) { - return $typeInfo['php']($value); + if (isset($typeInfo['callback'])) { + return $typeInfo['callback']($value); } } return $value; diff --git a/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php b/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php index a078326736f..dba687b70b4 100644 --- a/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php +++ b/lib/Cake/Test/TestCase/Model/Datasource/Database/ConnectionTest.php @@ -135,16 +135,16 @@ public function testExecuteWithArguments() { * @return void **/ public function testExecuteWithArgumentsAndTypes() { - $sql = 'SELECT ?'; + $sql = "SELECT ? = '2012-01-01'"; $statement = $this->connection->execute($sql, [new \DateTime('2012-01-01')], ['date']); $result = $statement->fetch(); - $this->assertEquals('2012-01-01', $result[0]); + $this->assertTrue((bool)$result[0]); - $sql = 'SELECT ?, ?, ?'; + $sql = "SELECT ? = '2012-01-01', ? = '2000-01-01 10:10:10', ? = 1.1"; $params = [new \DateTime('2012-01-01 10:10:10'), '2000-01-01 10:10:10', 1.1]; $statement = $this->connection->execute($sql, $params, ['date', 'string', 'float']); $result = $statement->fetch(); - $this->assertEquals(['2012-01-01', '2000-01-01 10:10:10', 1.1], $result); + $this->assertEquals($result, array_filter($result)); } /**