diff --git a/_config/connectors.yml b/_config/connectors.yml index 944acbe..c723761 100644 --- a/_config/connectors.yml +++ b/_config/connectors.yml @@ -3,7 +3,7 @@ name: postgresqlconnectors --- Injector: PostgrePDODatabase: - class: 'PostgrePDODatabase' + class: 'PostgreSQLDatabase' properties: connector: %$PDOConnector schemaManager: %$PostgreSQLSchemaManager diff --git a/code/PostgreSQLDatabase.php b/code/PostgreSQLDatabase.php index ea55416..6e794e9 100644 --- a/code/PostgreSQLDatabase.php +++ b/code/PostgreSQLDatabase.php @@ -104,12 +104,12 @@ class PostgreSQLDatabase extends SS_Database { /** * Connection parameters specified at inital connection - * - * @var array + * + * @var array */ protected $parameters = array(); - function connect($parameters) { + public function connect($parameters) { // Check database name if(empty($parameters['database'])) { // Check if we can use the master database @@ -322,7 +322,7 @@ class PostgreSQLDatabase extends SS_Database { $method = self::default_fts_search_method(); $conditions[] = "\"{$row['table_name']}\".\"{$row['column_name']}\" $method q "; - $query = DataObject::get($row['table_name'], $where)->dataQuery()->query(); + $query = DataObject::get($row['table_name'], $conditions)->dataQuery()->query(); // Could parameterise this, but convention is only to to so for where conditions $query->addFrom(array( @@ -390,21 +390,21 @@ class PostgreSQLDatabase extends SS_Database { $this->query('BEGIN;'); if($transaction_mode) { - $this->preparedQuery('SET TRANSACTION ?;', array($transaction_mode)); + $this->query("SET TRANSACTION {$transaction_mode};"); } if($session_characteristics) { - $this->preparedQuery('SET SESSION CHARACTERISTICS AS TRANSACTION ?;', array($session_characteristics)); + $this->query("SET SESSION CHARACTERISTICS AS TRANSACTION {$session_characteristics};"); } } public function transactionSavepoint($savepoint){ - $this->preparedQuery("SAVEPOINT ?;", array($savepoint)); + $this->query("SAVEPOINT {$savepoint};"); } public function transactionRollback($savepoint = false){ if($savepoint) { - $this->preparedQuery("ROLLBACK TO ?;", array($savepoint)); + $this->query("ROLLBACK TO {$savepoint};"); } else { $this->query('ROLLBACK;'); } @@ -443,10 +443,9 @@ class PostgreSQLDatabase extends SS_Database { * %U = unix timestamp, can only be used on it's own * @return string SQL datetime expression to query for a formatted datetime */ - function formattedDatetimeClause($date, $format) { - + public function formattedDatetimeClause($date, $format) { preg_match_all('/%(.)/', $format, $matches); - foreach($matches[1] as $match) { + foreach($matches[1] as $match) { if(array_search($match, array('Y','m','d','H','i','s','U')) === false) { user_error('formattedDatetimeClause(): unsupported format character %' . $match, E_USER_WARNING); } @@ -489,8 +488,7 @@ class PostgreSQLDatabase extends SS_Database { * This includes the singular forms as well * @return string SQL datetime expression to query for a datetime (YYYY-MM-DD hh:mm:ss) which is the result of the addition */ - function datetimeIntervalClause($date, $interval) { - + public function datetimeIntervalClause($date, $interval) { if(preg_match('/^now$/i', $date)) { $date = "NOW()"; } else if(preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/i', $date)) { @@ -509,8 +507,7 @@ class PostgreSQLDatabase extends SS_Database { * @param string $date2 to be substracted of $date1, can be either 'now', literal datetime like '1973-10-14 10:30:00' or field name, e.g. '"SiteTree"."Created"' * @return string SQL datetime expression to query for the interval between $date1 and $date2 in seconds which is the result of the substraction */ - function datetimeDifferenceClause($date1, $date2) { - + public function datetimeDifferenceClause($date1, $date2) { if(preg_match('/^now$/i', $date1)) { $date1 = "NOW()"; } else if(preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/i', $date1)) { diff --git a/code/PostgreSQLSchemaManager.php b/code/PostgreSQLSchemaManager.php index f9c41be..d4ff6c1 100644 --- a/code/PostgreSQLSchemaManager.php +++ b/code/PostgreSQLSchemaManager.php @@ -542,11 +542,11 @@ class PostgreSQLSchemaManager extends DBSchemaManager { //if(!isset(self::$cached_fieldlists[$table])){ $fields = $this->preparedQuery(" - SELECT ordinal_position, column_name, data_type, column_default, + SELECT ordinal_position, column_name, data_type, column_default, is_nullable, character_maximum_length, numeric_precision, numeric_scale - FROM information_schema.columns WHERE table_name = ? + FROM information_schema.columns WHERE table_name = ? and table_schema = ? ORDER BY ordinal_position;", - array($table) + array($table, $this->database->currentSchema()) ); $output = array(); @@ -762,12 +762,11 @@ class PostgreSQLSchemaManager extends DBSchemaManager { /** * Given a trigger name attempt to determine the columns upon which it acts - * + * * @param string $triggerName Postgres trigger name * @return array List of columns */ - protected function extractTriggerColumns($triggerName) - { + protected function extractTriggerColumns($triggerName) { $trigger = $this->preparedQuery( "SELECT tgargs FROM pg_catalog.pg_trigger WHERE tgname = ?", array($triggerName) @@ -875,7 +874,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager { * * @param string $constraint */ - function constraintExists($constraint){ + protected function constraintExists($constraint){ if(!isset(self::$cached_constraints[$constraint])){ $exists = $this->preparedQuery(" SELECT conname,pg_catalog.pg_get_constraintdef(r.oid, true) @@ -920,11 +919,11 @@ class PostgreSQLSchemaManager extends DBSchemaManager { /** * Pass a legit trigger name and it will be dropped * This assumes that the trigger has been named in a unique fashion - * + * * @param string $triggerName Name of the trigger * @param string $tableName Name of the table */ - function dropTrigger($triggerName, $tableName){ + protected function dropTrigger($triggerName, $tableName){ $exists = $this->preparedQuery(" SELECT trigger_name FROM information_schema.triggers @@ -938,12 +937,11 @@ class PostgreSQLSchemaManager extends DBSchemaManager { /** * This will return the fields that the trigger is monitoring - * + * * @param string $trigger Name of the trigger * @return array */ - function triggerFieldsFromTrigger($trigger) { - + protected function triggerFieldsFromTrigger($trigger) { if($trigger){ $tsvector='tsvector_update_trigger'; $ts_pos=strpos($trigger, $tsvector); @@ -1229,7 +1227,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager { * @param string $name * @param array $spec */ - function fulltext($this_index, $tableName, $name){ + protected function fulltext($this_index, $tableName, $name){ //For full text search, we need to create a column for the index $columns = $this->quoteColumnSpecString($this_index['value']); @@ -1250,7 +1248,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager { ); } - function IdColumn($asDbValue = false, $hasAutoIncPK = true){ + public function IdColumn($asDbValue = false, $hasAutoIncPK = true){ if($asDbValue) return 'bigint'; else return 'serial8 not null'; } @@ -1265,14 +1263,14 @@ class PostgreSQLSchemaManager extends DBSchemaManager { /** * Returns the values of the given enum field - * + * * @todo Make a proper implementation - * + * * @param string $tableName Name of table to check * @param string $fieldName name of enum field to check * @return array List of enum values */ - function enumValuesForField($tableName, $fieldName) { + public function enumValuesForField($tableName, $fieldName) { //return array('SiteTree','Page'); $constraints = $this->constraintExists("{$tableName}_{$fieldName}_check"); if($constraints) { @@ -1282,7 +1280,25 @@ class PostgreSQLSchemaManager extends DBSchemaManager { } } - function dbDataType($type){ + /** + * Get the actual enum fields from the constraint value: + * + * @param string $constraint + * @return array + */ + protected function enumValuesFromConstraint($constraint){ + $constraint = substr($constraint, strpos($constraint, 'ANY (ARRAY[')+11); + $constraint = substr($constraint, 0, -11); + $constraints = array(); + $segments = explode(',', $constraint); + foreach($segments as $this_segment){ + $bits = preg_split('/ *:: */', $this_segment); + array_unshift($constraints, trim($bits[0], " '")); + } + return $constraints; + } + + public function dbDataType($type){ $values = array( 'unsigned integer' => 'INT' );