From caaa4e99b4d4b53712165ff0bd3eea707c5c1535 Mon Sep 17 00:00:00 2001 From: Nevmera I Date: Thu, 19 Feb 2015 20:59:18 +0600 Subject: [PATCH 1/4] add RedshiftAdapter --- lib/Connection.php | 4 + lib/Table.php | 2 +- lib/adapters/RedshiftAdapter.php | 144 +++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 lib/adapters/RedshiftAdapter.php diff --git a/lib/Connection.php b/lib/Connection.php index c32311bcb..6341db5e2 100644 --- a/lib/Connection.php +++ b/lib/Connection.php @@ -245,6 +245,10 @@ protected function __construct($info) } else $host = "unix_socket=$info->host"; + // PDO driver redshift == pgsql + if ($info->protocol == 'redshift') { + $info->protocol = 'pgsql'; + } $this->connection = new PDO("$info->protocol:$host;dbname=$info->db", $info->user, $info->pass, static::$PDO_OPTIONS); } catch (PDOException $e) { diff --git a/lib/Table.php b/lib/Table.php index 5f08e1895..21dac9a33 100644 --- a/lib/Table.php +++ b/lib/Table.php @@ -395,7 +395,7 @@ private function get_meta_data() { // as more adapters are added probably want to do this a better way // than using instanceof but gud enuff for now - $quote_name = !($this->conn instanceof PgsqlAdapter); + $quote_name = !($this->conn instanceof PgsqlAdapter || $this->conn instanceof RedshiftAdapter); $table_name = $this->get_fully_qualified_table_name($quote_name); $conn = $this->conn; diff --git a/lib/adapters/RedshiftAdapter.php b/lib/adapters/RedshiftAdapter.php new file mode 100644 index 000000000..3c0487a88 --- /dev/null +++ b/lib/adapters/RedshiftAdapter.php @@ -0,0 +1,144 @@ + 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid +ORDER BY a.attnum +SQL; + $values = array($table); + return $this->query($sql,$values); + } + + public function query_for_tables() + { + return $this->query("SELECT tablename FROM pg_tables WHERE schemaname NOT IN('information_schema','pg_catalog')"); + } + + public function create_column(&$column) + { + $c = new Column(); + $c->inflected_name = Inflector::instance()->variablize($column['field']); + $c->name = $column['field']; + $c->nullable = ($column['not_nullable'] ? false : true); + //t == true, f == false + $c->pk = ($column['pk'] == 't'); + $c->auto_increment = false; + + if (substr($column['type'],0,9) == 'timestamp') + { + $c->raw_type = 'datetime'; + $c->length = 19; + } + elseif ($column['type'] == 'date') + { + $c->raw_type = 'date'; + $c->length = 10; + } + else + { + preg_match('/^([A-Za-z0-9_]+)(\(([0-9]+(,[0-9]+)?)\))?/',$column['type'],$matches); + + $c->raw_type = (count($matches) > 0 ? $matches[1] : $column['type']); + $c->length = count($matches) >= 4 ? intval($matches[3]) : intval($column['attlen']); + + if ($c->length < 0) + $c->length = null; + } + + $c->map_raw_type(); + + if ($column['default']) + { + preg_match("/^nextval\('(.*)'\)$/",$column['default'],$matches); + + if (count($matches) == 2) + $c->sequence = $matches[1]; + else + $c->default = $c->cast($column['default'],$this); + } + return $c; + } + + public function set_encoding($charset) + { + $this->query("SET NAMES '$charset'"); + } + + public function native_database_types() + { + return array( + 'primary_key' => 'serial primary key', + 'string' => array('name' => 'character varying', 'length' => 255), + 'text' => array('name' => 'text'), + 'integer' => array('name' => 'integer'), + 'float' => array('name' => 'float'), + 'datetime' => array('name' => 'datetime'), + 'timestamp' => array('name' => 'timestamp'), + 'time' => array('name' => 'time'), + 'date' => array('name' => 'date'), + 'binary' => array('name' => 'binary'), + 'boolean' => array('name' => 'boolean') + ); + } +} \ No newline at end of file From d00676710d946c08a5ed3f5a44cbc8bdc62d6767 Mon Sep 17 00:00:00 2001 From: Nevmera I Date: Tue, 24 Feb 2015 13:30:20 +0600 Subject: [PATCH 2/4] bug fixed check collumn pk --- lib/adapters/PgsqlAdapter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/adapters/PgsqlAdapter.php b/lib/adapters/PgsqlAdapter.php index 72da44182..56d9e8e2d 100644 --- a/lib/adapters/PgsqlAdapter.php +++ b/lib/adapters/PgsqlAdapter.php @@ -6,7 +6,7 @@ /** * Adapter for Postgres (not completed yet) - * + * * @package ActiveRecord */ class PgsqlAdapter extends Connection @@ -47,7 +47,7 @@ public function query_column_info($table) WHERE c.oid = pg_index.indrelid AND a.attnum = ANY (pg_index.indkey) AND pg_index.indisprimary = 't' - ) IS NOT NULL AS pk, + ) IS NOT NULL AS pk, REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE((SELECT pg_attrdef.adsrc FROM pg_attrdef WHERE c.oid = pg_attrdef.adrelid @@ -75,7 +75,7 @@ public function create_column(&$column) $c->inflected_name = Inflector::instance()->variablize($column['field']); $c->name = $column['field']; $c->nullable = ($column['not_nullable'] ? false : true); - $c->pk = ($column['pk'] ? true : false); + $c->pk = ($column['pk'] == 't'); $c->auto_increment = false; if (substr($column['type'],0,9) == 'timestamp') From 8605cf1dd866503bb5f449b29eb834eb39a9538f Mon Sep 17 00:00:00 2001 From: Nevmera I Date: Tue, 24 Feb 2015 13:31:49 +0600 Subject: [PATCH 3/4] RedshiftAdapter extends PgsqlAdapter, replace all space to tabs, and remove extra methods from RedshiftAdapter --- lib/adapters/RedshiftAdapter.php | 168 ++++++++----------------------- 1 file changed, 40 insertions(+), 128 deletions(-) diff --git a/lib/adapters/RedshiftAdapter.php b/lib/adapters/RedshiftAdapter.php index 3c0487a88..000b78225 100644 --- a/lib/adapters/RedshiftAdapter.php +++ b/lib/adapters/RedshiftAdapter.php @@ -4,141 +4,53 @@ */ namespace ActiveRecord; +require_once __DIR__ . '/PgsqlAdapter.php'; + /** - * Adapter for Redshift postgres version < 8.1 (not completed yet) + * Adapter for Redshift postgres version < 8.0.2 (not completed yet) * * @package ActiveRecord */ -class RedshiftAdapter extends Connection +class RedshiftAdapter extends PgsqlAdapter { - static $QUOTE_CHARACTER = '"'; - static $DEFAULT_PORT = 5432; - - public function supports_sequences() - { - return false; - } - - public function get_sequence_name($table, $column_name) - { - return "{$table}_{$column_name}_seq"; - } - - public function next_sequence_value($sequence_name) - { - return "nextval('" . str_replace("'","\\'",$sequence_name) . "')"; - } - - public function limit($sql, $offset, $limit) - { - return $sql . ' LIMIT ' . intval($limit) . ' OFFSET ' . intval($offset); - } - - public function query_column_info($table) - { - $sql = << 0 - AND a.attrelid = c.oid - AND a.atttypid = t.oid + AND a.attnum > 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid ORDER BY a.attnum SQL; - $values = array($table); - return $this->query($sql,$values); - } - - public function query_for_tables() - { - return $this->query("SELECT tablename FROM pg_tables WHERE schemaname NOT IN('information_schema','pg_catalog')"); - } - - public function create_column(&$column) - { - $c = new Column(); - $c->inflected_name = Inflector::instance()->variablize($column['field']); - $c->name = $column['field']; - $c->nullable = ($column['not_nullable'] ? false : true); - //t == true, f == false - $c->pk = ($column['pk'] == 't'); - $c->auto_increment = false; - - if (substr($column['type'],0,9) == 'timestamp') - { - $c->raw_type = 'datetime'; - $c->length = 19; - } - elseif ($column['type'] == 'date') - { - $c->raw_type = 'date'; - $c->length = 10; - } - else - { - preg_match('/^([A-Za-z0-9_]+)(\(([0-9]+(,[0-9]+)?)\))?/',$column['type'],$matches); - - $c->raw_type = (count($matches) > 0 ? $matches[1] : $column['type']); - $c->length = count($matches) >= 4 ? intval($matches[3]) : intval($column['attlen']); - - if ($c->length < 0) - $c->length = null; - } - - $c->map_raw_type(); - - if ($column['default']) - { - preg_match("/^nextval\('(.*)'\)$/",$column['default'],$matches); - - if (count($matches) == 2) - $c->sequence = $matches[1]; - else - $c->default = $c->cast($column['default'],$this); - } - return $c; - } - - public function set_encoding($charset) - { - $this->query("SET NAMES '$charset'"); - } - - public function native_database_types() - { - return array( - 'primary_key' => 'serial primary key', - 'string' => array('name' => 'character varying', 'length' => 255), - 'text' => array('name' => 'text'), - 'integer' => array('name' => 'integer'), - 'float' => array('name' => 'float'), - 'datetime' => array('name' => 'datetime'), - 'timestamp' => array('name' => 'timestamp'), - 'time' => array('name' => 'time'), - 'date' => array('name' => 'date'), - 'binary' => array('name' => 'binary'), - 'boolean' => array('name' => 'boolean') - ); - } -} \ No newline at end of file + $values = array($table); + return $this->query($sql,$values); + } +} From fb5c31d34f6a37745eea85877488f2fcb1d62a0c Mon Sep 17 00:00:00 2001 From: Nevmera I Date: Mon, 2 Mar 2015 12:31:31 +0600 Subject: [PATCH 4/4] revert !(->conn instanceof PgsqlAdapter || ->conn instanceof RedshiftAdapter) -> !(->conn instanceof PgsqlAdapter) --- lib/Table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Table.php b/lib/Table.php index 21dac9a33..5f08e1895 100644 --- a/lib/Table.php +++ b/lib/Table.php @@ -395,7 +395,7 @@ private function get_meta_data() { // as more adapters are added probably want to do this a better way // than using instanceof but gud enuff for now - $quote_name = !($this->conn instanceof PgsqlAdapter || $this->conn instanceof RedshiftAdapter); + $quote_name = !($this->conn instanceof PgsqlAdapter); $table_name = $this->get_fully_qualified_table_name($quote_name); $conn = $this->conn;