2009-06-12 08:44:49 +00:00
< ? php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* PostgreSQL specific SQL code generator .
*
2012-06-05 12:14:02 +02:00
* @ package core_ddl
2009-06-12 08:44:49 +00:00
* @ copyright 1999 onwards Martin Dougiamas http :// dougiamas . com
* 2001 - 3001 Eloy Lafuente ( stronk7 ) http :// contiento . com
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2006-08-16 18:41:47 +00:00
2010-07-25 12:57:03 +00:00
defined ( 'MOODLE_INTERNAL' ) || die ();
2008-05-15 21:40:00 +00:00
require_once ( $CFG -> libdir . '/ddl/sql_generator.php' );
2012-06-05 12:14:02 +02:00
/**
* This class generate SQL code to be used against PostgreSQL
* It extends XMLDBgenerator so everything can be
* overridden as needed to generate correct SQL .
*
* @ package core_ddl
* @ copyright 1999 onwards Martin Dougiamas http :// dougiamas . com
* 2001 - 3001 Eloy Lafuente ( stronk7 ) http :// contiento . com
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2006-08-16 18:41:47 +00:00
2008-05-15 21:40:00 +00:00
class postgres_sql_generator extends sql_generator {
2006-08-16 18:41:47 +00:00
2012-06-05 12:14:02 +02:00
// Only set values that are different from the defaults present in XMLDBgenerator
/** @var string Proper type for NUMBER(x) in this DB. */
public $number_type = 'NUMERIC' ;
2006-08-16 18:41:47 +00:00
2012-06-05 12:14:02 +02:00
/** @var string To define the default to set for NOT NULLs CHARs without default (null=do nothing).*/
public $default_for_char = '' ;
2006-08-16 18:41:47 +00:00
2012-06-05 12:14:02 +02:00
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
public $sequence_extra_code = false ;
2006-08-16 18:41:47 +00:00
2012-06-05 12:14:02 +02:00
/** @var string The particular name for inline sequences in this generator.*/
public $sequence_name = 'BIGSERIAL' ;
2006-10-01 08:44:55 +00:00
2012-06-05 12:14:02 +02:00
/** @var string The particular name for inline sequences in this generator.*/
public $sequence_name_small = 'SERIAL' ;
2006-10-03 15:00:55 +00:00
2012-06-05 12:14:02 +02:00
/** @var bool To avoid outputting the rest of the field specs, leaving only the name and the sequence_name returned.*/
public $sequence_only = true ;
2006-09-30 19:43:16 +00:00
2012-06-05 12:14:02 +02:00
/** @var string SQL sentence to rename one index where 'TABLENAME', 'OLDINDEXNAME' and 'NEWINDEXNAME' are dynamically replaced.*/
public $rename_index_sql = 'ALTER TABLE OLDINDEXNAME RENAME TO NEWINDEXNAME' ;
/** @var string SQL sentence to rename one key 'TABLENAME', 'OLDKEYNAME' and 'NEWKEYNAME' are dynamically replaced.*/
public $rename_key_sql = null ;
/** @var string type of string quoting used - '' or \' quotes*/
protected $std_strings = null ;
2011-02-12 16:16:52 +01:00
2008-11-21 21:40:50 +00:00
/**
* Reset a sequence to the id field of a table .
2012-06-05 12:14:02 +02:00
*
* @ param xmldb_table | string $table name of table or the table object .
* @ return array of sql statements
2008-11-21 21:40:50 +00:00
*/
2009-08-31 14:23:40 +00:00
public function getResetSequenceSQL ( $table ) {
if ( $table instanceof xmldb_table ) {
2008-11-21 21:40:50 +00:00
$tablename = $table -> getName ();
2009-08-31 14:23:40 +00:00
} else {
$tablename = $table ;
2008-11-21 21:40:50 +00:00
}
2009-08-31 14:23:40 +00:00
2008-11-21 21:40:50 +00:00
// From http://www.postgresql.org/docs/7.4/static/sql-altersequence.html
$value = ( int ) $this -> mdb -> get_field_sql ( 'SELECT MAX(id) FROM {' . $tablename . '}' );
$value ++ ;
2009-08-31 14:23:40 +00:00
return array ( " ALTER SEQUENCE $this->prefix { $tablename } _id_seq RESTART WITH $value " );
2008-11-21 21:40:50 +00:00
}
2010-04-21 16:12:27 +00:00
/**
* Given one correct xmldb_table , returns the SQL statements
2012-06-05 12:14:02 +02:00
* to create temporary table ( inside one array ) .
*
* @ param xmldb_table $xmldb_table The xmldb_table object instance .
* @ return array of sql statements
2010-04-21 16:12:27 +00:00
*/
public function getCreateTempTableSQL ( $xmldb_table ) {
$this -> temptables -> add_temptable ( $xmldb_table -> getName ());
$sqlarr = $this -> getCreateTableSQL ( $xmldb_table );
$sqlarr = preg_replace ( '/^CREATE TABLE/' , " CREATE TEMPORARY TABLE " , $sqlarr );
return $sqlarr ;
}
2012-05-20 10:50:14 +02:00
/**
* Given one correct xmldb_index , returns the SQL statements
* needed to create it ( in array ) .
*
* @ param xmldb_table $xmldb_table The xmldb_table instance to create the index on .
* @ param xmldb_index $xmldb_index The xmldb_index to create .
* @ return array An array of SQL statements to create the index .
* @ throws coding_exception Thrown if the xmldb_index does not validate with the xmldb_table .
*/
public function getCreateIndexSQL ( $xmldb_table , $xmldb_index ) {
$sqls = parent :: getCreateIndexSQL ( $xmldb_table , $xmldb_index );
$hints = $xmldb_index -> getHints ();
$fields = $xmldb_index -> getFields ();
if ( in_array ( 'varchar_pattern_ops' , $hints ) and count ( $fields ) == 1 ) {
2012-07-02 06:02:22 +02:00
// Add the pattern index and keep the normal one, keep unique only the standard index to improve perf.
2012-05-20 10:50:14 +02:00
foreach ( $sqls as $sql ) {
$field = reset ( $fields );
$count = 0 ;
2012-07-02 06:02:22 +02:00
$newindex = preg_replace ( " /^CREATE( UNIQUE)? INDEX ([a-z0-9_]+) ON ([a-z0-9_]+) \ ( $field\ ) $ / " , " CREATE INDEX \\ 2_pattern ON \\ 3 USING btree ( $field varchar_pattern_ops) " , $sql , - 1 , $count );
2012-05-20 10:50:14 +02:00
if ( $count != 1 ) {
debugging ( 'Unexpected getCreateIndexSQL() structure.' );
continue ;
}
$sqls [] = $newindex ;
}
}
return $sqls ;
}
2006-08-16 18:41:47 +00:00
/**
2012-06-05 12:14:02 +02:00
* Given one XMLDB Type , length and decimals , returns the DB proper SQL type .
*
* @ param int $xmldb_type The xmldb_type defined constant . XMLDB_TYPE_INTEGER and other XMLDB_TYPE_ * constants .
* @ param int $xmldb_length The length of that data type .
* @ param int $xmldb_decimals The decimal places of precision of the data type .
* @ return string The DB defined data type .
2006-08-16 18:41:47 +00:00
*/
2008-05-15 21:40:00 +00:00
public function getTypeSQL ( $xmldb_type , $xmldb_length = null , $xmldb_decimals = null ) {
2006-08-16 18:41:47 +00:00
switch ( $xmldb_type ) {
case XMLDB_TYPE_INTEGER : // From http://www.postgresql.org/docs/7.4/interactive/datatype.html
if ( empty ( $xmldb_length )) {
$xmldb_length = 10 ;
}
if ( $xmldb_length > 9 ) {
$dbtype = 'BIGINT' ;
} else if ( $xmldb_length > 4 ) {
$dbtype = 'INTEGER' ;
} else {
$dbtype = 'SMALLINT' ;
}
break ;
case XMLDB_TYPE_NUMBER :
$dbtype = $this -> number_type ;
if ( ! empty ( $xmldb_length )) {
$dbtype .= '(' . $xmldb_length ;
if ( ! empty ( $xmldb_decimals )) {
$dbtype .= ',' . $xmldb_decimals ;
}
$dbtype .= ')' ;
}
break ;
case XMLDB_TYPE_FLOAT :
2006-08-25 17:11:43 +00:00
$dbtype = 'DOUBLE PRECISION' ;
2006-08-20 18:19:50 +00:00
if ( ! empty ( $xmldb_decimals )) {
if ( $xmldb_decimals < 6 ) {
$dbtype = 'REAL' ;
2006-08-16 18:41:47 +00:00
}
}
break ;
case XMLDB_TYPE_CHAR :
$dbtype = 'VARCHAR' ;
2006-09-22 10:15:51 +00:00
if ( empty ( $xmldb_length )) {
2006-08-16 18:41:47 +00:00
$xmldb_length = '255' ;
}
$dbtype .= '(' . $xmldb_length . ')' ;
break ;
case XMLDB_TYPE_TEXT :
$dbtype = 'TEXT' ;
break ;
case XMLDB_TYPE_BINARY :
$dbtype = 'BYTEA' ;
break ;
case XMLDB_TYPE_DATETIME :
$dbtype = 'TIMESTAMP' ;
break ;
}
return $dbtype ;
}
2006-09-24 15:25:49 +00:00
/**
2012-06-05 12:14:02 +02:00
* Returns the code ( array of statements ) needed to add one comment to the table .
*
* @ param xmldb_table $xmldb_table The xmldb_table object instance .
* @ return array Array of SQL statements to add one comment to the table .
2006-09-24 15:25:49 +00:00
*/
function getCommentSQL ( $xmldb_table ) {
2006-09-30 12:13:07 +00:00
$comment = " COMMENT ON TABLE " . $this -> getTableName ( $xmldb_table );
2008-05-15 21:40:00 +00:00
$comment .= " IS ' " . $this -> addslashes ( substr ( $xmldb_table -> getComment (), 0 , 250 )) . " ' " ;
2006-09-24 15:25:49 +00:00
return array ( $comment );
}
2006-10-01 08:44:55 +00:00
/**
2012-06-05 12:14:02 +02:00
* Returns the code ( array of statements ) needed to execute extra statements on table rename .
*
* @ param xmldb_table $xmldb_table The xmldb_table object instance .
* @ param string $newname The new name for the table .
* @ return array Array of extra SQL statements to rename a table .
2006-10-01 08:44:55 +00:00
*/
2008-05-15 21:40:00 +00:00
public function getRenameTableExtraSQL ( $xmldb_table , $newname ) {
2006-10-01 08:44:55 +00:00
$results = array ();
2008-05-20 23:24:40 +00:00
$newt = new xmldb_table ( $newname );
2006-10-01 08:44:55 +00:00
2008-05-20 23:24:40 +00:00
$xmldb_field = new xmldb_field ( 'id' ); // Fields having sequences should be exclusively, id.
2006-10-01 08:44:55 +00:00
$oldseqname = $this -> getTableName ( $xmldb_table ) . '_' . $xmldb_field -> getName () . '_seq' ;
$newseqname = $this -> getTableName ( $newt ) . '_' . $xmldb_field -> getName () . '_seq' ;
2012-06-05 12:14:02 +02:00
// Rename de sequence
2006-10-01 08:44:55 +00:00
$results [] = 'ALTER TABLE ' . $oldseqname . ' RENAME TO ' . $newseqname ;
return $results ;
}
2006-09-24 15:25:49 +00:00
/**
2012-06-05 12:14:02 +02:00
* Given one xmldb_table and one xmldb_field , return the SQL statements needed to alter the field in the table .
*
2006-09-24 15:25:49 +00:00
* PostgreSQL has some severe limits :
* - Any change of type or precision requires a new temporary column to be created , values to
2008-05-15 21:40:00 +00:00
* be transfered potentially casting them , to apply defaults if the column is not null and
2006-09-24 15:25:49 +00:00
* finally , to rename it
* - Changes in null / not null require the SET / DROP NOT NULL clause
* - Changes in default require the SET / DROP DEFAULT clause
2012-06-05 12:14:02 +02:00
*
* @ param xmldb_table $xmldb_table The table related to $xmldb_field .
* @ param xmldb_field $xmldb_field The instance of xmldb_field to create the SQL from .
* @ param string $skip_type_clause The type clause on alter columns , NULL by default .
* @ param string $skip_default_clause The default clause on alter columns , NULL by default .
* @ param string $skip_notnull_clause The null / notnull clause on alter columns , NULL by default .
* @ return string The field altering SQL statement .
2006-09-24 15:25:49 +00:00
*/
2011-03-18 14:40:20 +01:00
public function getAlterFieldSQL ( $xmldb_table , $xmldb_field , $skip_type_clause = NULL , $skip_default_clause = NULL , $skip_notnull_clause = NULL ) {
2012-06-05 12:14:02 +02:00
$results = array (); // To store all the needed SQL commands
2006-09-24 15:25:49 +00:00
2012-06-05 12:14:02 +02:00
// Get the normal names of the table and field
2008-05-15 21:40:00 +00:00
$tablename = $xmldb_table -> getName ();
$fieldname = $xmldb_field -> getName ();
2006-09-24 15:25:49 +00:00
2012-06-05 12:14:02 +02:00
// Take a look to field metadata
2009-09-28 23:16:05 +00:00
$meta = $this -> mdb -> get_columns ( $tablename );
2008-05-15 21:40:00 +00:00
$metac = $meta [ $xmldb_field -> getName ()];
$oldmetatype = $metac -> meta_type ;
2006-09-24 15:25:49 +00:00
$oldlength = $metac -> max_length ;
$olddecimals = empty ( $metac -> scale ) ? null : $metac -> scale ;
$oldnotnull = empty ( $metac -> not_null ) ? false : $metac -> not_null ;
2008-05-15 21:40:00 +00:00
$olddefault = empty ( $metac -> has_default ) ? null : $metac -> default_value ;
2006-09-24 15:25:49 +00:00
$typechanged = true ; //By default, assume that the column type has changed
$precisionchanged = true ; //By default, assume that the column precision has changed
$decimalchanged = true ; //By default, assume that the column decimal has changed
$defaultchanged = true ; //By default, assume that the column default has changed
$notnullchanged = true ; //By default, assume that the column notnull has changed
2012-06-05 12:14:02 +02:00
// Detect if we are changing the type of the column
2008-05-15 21:40:00 +00:00
if (( $xmldb_field -> getType () == XMLDB_TYPE_INTEGER && $oldmetatype == 'I' ) ||
2006-09-24 15:25:49 +00:00
( $xmldb_field -> getType () == XMLDB_TYPE_NUMBER && $oldmetatype == 'N' ) ||
( $xmldb_field -> getType () == XMLDB_TYPE_FLOAT && $oldmetatype == 'F' ) ||
2008-05-15 21:40:00 +00:00
( $xmldb_field -> getType () == XMLDB_TYPE_CHAR && $oldmetatype == 'C' ) ||
( $xmldb_field -> getType () == XMLDB_TYPE_TEXT && $oldmetatype == 'X' ) ||
2006-09-24 15:25:49 +00:00
( $xmldb_field -> getType () == XMLDB_TYPE_BINARY && $oldmetatype == 'B' )) {
$typechanged = false ;
}
2012-06-05 12:14:02 +02:00
// Detect if we are changing the precision
2006-09-24 15:25:49 +00:00
if (( $xmldb_field -> getType () == XMLDB_TYPE_TEXT ) ||
( $xmldb_field -> getType () == XMLDB_TYPE_BINARY ) ||
( $oldlength == - 1 ) ||
( $xmldb_field -> getLength () == $oldlength )) {
$precisionchanged = false ;
}
2012-06-05 12:14:02 +02:00
// Detect if we are changing the decimals
2006-09-24 15:25:49 +00:00
if (( $xmldb_field -> getType () == XMLDB_TYPE_INTEGER ) ||
( $xmldb_field -> getType () == XMLDB_TYPE_CHAR ) ||
( $xmldb_field -> getType () == XMLDB_TYPE_TEXT ) ||
( $xmldb_field -> getType () == XMLDB_TYPE_BINARY ) ||
( ! $xmldb_field -> getDecimals ()) ||
( ! $olddecimals ) ||
( $xmldb_field -> getDecimals () == $olddecimals )) {
$decimalchanged = false ;
}
2012-06-05 12:14:02 +02:00
// Detect if we are changing the default
2006-09-24 15:25:49 +00:00
if (( $xmldb_field -> getDefault () === null && $olddefault === null ) ||
2008-05-15 21:40:00 +00:00
( $xmldb_field -> getDefault () === $olddefault )) {
2006-09-24 15:25:49 +00:00
$defaultchanged = false ;
}
2012-06-05 12:14:02 +02:00
// Detect if we are changing the nullability
2006-09-24 15:25:49 +00:00
if (( $xmldb_field -> getNotnull () === $oldnotnull )) {
$notnullchanged = false ;
}
2012-06-05 12:14:02 +02:00
// Get the quoted name of the table and field
2008-05-15 21:40:00 +00:00
$tablename = $this -> getTableName ( $xmldb_table );
$fieldname = $this -> getEncQuoted ( $xmldb_field -> getName ());
2012-06-05 12:14:02 +02:00
// Decide if we have changed the column specs (type/precision/decimals)
2009-07-30 22:08:47 +00:00
$specschanged = $typechanged || $precisionchanged || $decimalchanged ;
2012-06-05 12:14:02 +02:00
// if specs have changed, need to alter column
2009-07-30 22:08:47 +00:00
if ( $specschanged ) {
2012-06-05 12:14:02 +02:00
// Always drop any exiting default before alter column (some type changes can cause casting error in default for column)
2009-07-30 22:08:47 +00:00
if ( $olddefault !== null ) {
2012-06-05 12:14:02 +02:00
$results [] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP DEFAULT' ; // Drop default clause
2009-07-30 22:08:47 +00:00
}
$alterstmt = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $this -> getEncQuoted ( $xmldb_field -> getName ()) .
2012-05-20 10:50:14 +02:00
' TYPE' . $this -> getFieldSQL ( $xmldb_table , $xmldb_field , null , true , true , null , false );
2012-06-05 12:14:02 +02:00
// Some castings must be performed explicitly (mainly from text|char to numeric|integer)
2009-07-30 22:08:47 +00:00
if (( $oldmetatype == 'C' || $oldmetatype == 'X' ) &&
( $xmldb_field -> getType () == XMLDB_TYPE_NUMBER || $xmldb_field -> getType () == XMLDB_TYPE_FLOAT )) {
$alterstmt .= ' USING CAST(' . $fieldname . ' AS NUMERIC)' ; // from char or text to number or float
} else if (( $oldmetatype == 'C' || $oldmetatype == 'X' ) &&
$xmldb_field -> getType () == XMLDB_TYPE_INTEGER ) {
$alterstmt .= ' USING CAST(CAST(' . $fieldname . ' AS NUMERIC) AS INTEGER)' ; // From char to integer
2006-09-24 15:25:49 +00:00
}
2009-07-30 22:08:47 +00:00
$results [] = $alterstmt ;
2006-09-24 15:25:49 +00:00
}
2009-07-30 22:08:47 +00:00
2012-06-05 12:14:02 +02:00
// If the default has changed or we have performed one change in specs
2009-07-30 22:08:47 +00:00
if ( $defaultchanged || $specschanged ) {
2008-05-15 21:40:00 +00:00
$default_clause = $this -> getDefaultClause ( $xmldb_field );
if ( $default_clause ) {
2012-06-05 12:14:02 +02:00
$sql = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $default_clause ; // Add default clause
2008-05-15 21:40:00 +00:00
$results [] = $sql ;
2006-09-24 15:25:49 +00:00
} else {
2012-06-05 12:14:02 +02:00
if ( ! $specschanged ) { // Only drop default if we haven't performed one specs change
$results [] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP DEFAULT' ; // Drop default clause
2006-09-24 15:25:49 +00:00
}
}
}
2009-07-30 22:08:47 +00:00
2012-06-05 12:14:02 +02:00
// If the not null has changed
2009-07-30 22:08:47 +00:00
if ( $notnullchanged ) {
2006-09-24 15:25:49 +00:00
if ( $xmldb_field -> getNotnull ()) {
$results [] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET NOT NULL' ;
} else {
$results [] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP NOT NULL' ;
}
}
2012-06-05 12:14:02 +02:00
// Return the results
2006-09-24 15:25:49 +00:00
return $results ;
}
2006-09-24 09:38:56 +00:00
2006-09-25 18:22:06 +00:00
/**
2012-06-05 12:14:02 +02:00
* Given one xmldb_table and one xmldb_field , return the SQL statements needed to add its default
2006-09-25 18:22:06 +00:00
* ( usually invoked from getModifyDefaultSQL ()
2012-06-05 12:14:02 +02:00
*
* @ param xmldb_table $xmldb_table The xmldb_table object instance .
* @ param xmldb_field $xmldb_field The xmldb_field object instance .
* @ return array Array of SQL statements to create a field ' s default .
2006-09-25 18:22:06 +00:00
*/
2008-05-15 21:40:00 +00:00
public function getCreateDefaultSQL ( $xmldb_table , $xmldb_field ) {
2012-06-05 12:14:02 +02:00
// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
// is capable of handling defaults
2006-09-25 18:22:06 +00:00
return $this -> getAlterFieldSQL ( $xmldb_table , $xmldb_field );
}
/**
2010-05-21 18:42:50 +00:00
* Given one xmldb_table and one xmldb_field , return the SQL statements needed to drop its default
2006-09-25 18:22:06 +00:00
* ( usually invoked from getModifyDefaultSQL ()
2012-06-05 12:14:02 +02:00
*
* Note that this method may be dropped in future .
*
* @ param xmldb_table $xmldb_table The xmldb_table object instance .
* @ param xmldb_field $xmldb_field The xmldb_field object instance .
* @ return array Array of SQL statements to create a field ' s default .
*
* @ todo MDL - 31147 Moodle 2.1 - Drop getDropDefaultSQL ()
2006-09-25 18:22:06 +00:00
*/
2008-05-15 21:40:00 +00:00
public function getDropDefaultSQL ( $xmldb_table , $xmldb_field ) {
2012-06-05 12:14:02 +02:00
// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
// is capable of handling defaults
2006-09-25 18:22:06 +00:00
return $this -> getAlterFieldSQL ( $xmldb_table , $xmldb_field );
}
2012-06-05 12:14:02 +02:00
/**
* Adds slashes to string .
* @ param string $s
* @ return string The escaped string .
*/
2011-02-12 16:16:52 +01:00
public function addslashes ( $s ) {
2011-02-15 09:44:24 +01:00
// Postgres is gradually switching to ANSI quotes, we need to check what is expected
2011-02-12 16:16:52 +01:00
if ( ! isset ( $this -> std_strings )) {
$this -> std_strings = ( $this -> mdb -> get_field_sql ( " select setting from pg_settings where name = 'standard_conforming_strings' " ) === 'on' );
}
if ( $this -> std_strings ) {
$s = str_replace ( " ' " , " '' " , $s );
} else {
// do not use php addslashes() because it depends on PHP quote settings!
$s = str_replace ( '\\' , '\\\\' , $s );
$s = str_replace ( " \0 " , " \\ \0 " , $s );
$s = str_replace ( " ' " , " \\ ' " , $s );
}
return $s ;
}
2012-06-05 12:14:02 +02:00
/**
* Given one xmldb_table returns one string with the sequence of the table
* in the table ( fetched from DB )
* The sequence name for Postgres has one standard name convention :
* tablename_fieldname_seq
* so we just calculate it and confirm it ' s present in pg_class
*
* @ param xmldb_table $xmldb_table The xmldb_table object instance .
* @ return string | bool If no sequence is found , returns false
*/
function getSequenceFromDB ( $xmldb_table ) {
2006-10-16 17:36:13 +00:00
2012-06-05 12:14:02 +02:00
$tablename = $this -> getTableName ( $xmldb_table );
$sequencename = $tablename . '_id_seq' ;
2006-10-16 17:36:13 +00:00
2013-01-08 17:12:31 +01:00
if ( ! $this -> mdb -> get_record_sql ( " SELECT c.*
FROM pg_catalog . pg_class c
JOIN pg_catalog . pg_namespace as ns ON ns . oid = c . relnamespace
WHERE c . relname = ? AND c . relkind = 'S'
AND ( ns . nspname = current_schema () OR ns . oid = pg_my_temp_schema ()) " ,
2012-05-20 10:50:14 +02:00
array ( $sequencename ))) {
2012-06-05 12:14:02 +02:00
$sequencename = false ;
}
2006-10-16 17:36:13 +00:00
2012-06-05 12:14:02 +02:00
return $sequencename ;
}
2006-10-16 17:36:13 +00:00
2007-01-27 17:37:39 +00:00
/**
2012-06-05 12:14:02 +02:00
* Given one object name and it ' s type ( pk , uk , fk , ck , ix , uix , seq , trg ) .
*
* ( MySQL requires the whole xmldb_table object to be specified , so we add it always )
*
* This is invoked from getNameForObject () .
* Only some DB have this implemented .
*
* @ param string $object_name The object ' s name to check for .
* @ param string $type The object ' s type ( pk , uk , fk , ck , ix , uix , seq , trg ) .
* @ param string $table_name The table ' s name to check in
* @ return bool If such name is currently in use ( true ) or no ( false )
2007-01-27 17:37:39 +00:00
*/
2008-05-15 21:40:00 +00:00
public function isNameInUse ( $object_name , $type , $table_name ) {
2007-01-27 17:37:39 +00:00
switch ( $type ) {
case 'ix' :
case 'uix' :
case 'seq' :
2013-01-08 17:12:31 +01:00
if ( $check = $this -> mdb -> get_records_sql ( " SELECT c.relname
FROM pg_class c
JOIN pg_catalog . pg_namespace as ns ON ns . oid = c . relnamespace
WHERE lower ( c . relname ) = ?
AND ( ns . nspname = current_schema () OR ns . oid = pg_my_temp_schema ()) " , array(strtolower( $object_name )))) {
2007-01-27 17:37:39 +00:00
return true ;
}
break ;
case 'pk' :
case 'uk' :
case 'fk' :
case 'ck' :
2013-01-08 17:12:31 +01:00
if ( $check = $this -> mdb -> get_records_sql ( " SELECT c.conname
FROM pg_constraint c
JOIN pg_catalog . pg_namespace as ns ON ns . oid = c . connamespace
WHERE lower ( c . conname ) = ?
AND ( ns . nspname = current_schema () OR ns . oid = pg_my_temp_schema ()) " , array(strtolower( $object_name )))) {
2007-01-27 17:37:39 +00:00
return true ;
}
break ;
case 'trg' :
2008-06-09 19:48:24 +00:00
if ( $check = $this -> mdb -> get_records_sql ( " SELECT tgname
FROM pg_trigger
WHERE lower ( tgname ) = ? " , array(strtolower( $object_name )))) {
2007-01-27 17:37:39 +00:00
return true ;
}
break ;
}
return false ; //No name in use found
}
2006-08-16 18:41:47 +00:00
/**
* Returns an array of reserved words ( lowercase ) for this DB
2012-06-05 12:14:02 +02:00
* @ return array An array of database specific reserved words
2006-08-16 18:41:47 +00:00
*/
2008-05-15 21:40:00 +00:00
public static function getReservedWords () {
2012-06-05 12:14:02 +02:00
// This file contains the reserved words for PostgreSQL databases
2012-05-20 10:50:14 +02:00
// This file contains the reserved words for PostgreSQL databases
2012-06-05 12:14:02 +02:00
// http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
2006-08-16 18:41:47 +00:00
$reserved_words = array (
2006-09-20 21:00:45 +00:00
'all' , 'analyse' , 'analyze' , 'and' , 'any' , 'array' , 'as' , 'asc' ,
'asymmetric' , 'authorization' , 'between' , 'binary' , 'both' , 'case' ,
'cast' , 'check' , 'collate' , 'column' , 'constraint' , 'create' , 'cross' ,
'current_date' , 'current_role' , 'current_time' , 'current_timestamp' ,
'current_user' , 'default' , 'deferrable' , 'desc' , 'distinct' , 'do' ,
'else' , 'end' , 'except' , 'false' , 'for' , 'foreign' , 'freeze' , 'from' ,
'full' , 'grant' , 'group' , 'having' , 'ilike' , 'in' , 'initially' , 'inner' ,
'intersect' , 'into' , 'is' , 'isnull' , 'join' , 'leading' , 'left' , 'like' ,
'limit' , 'localtime' , 'localtimestamp' , 'natural' , 'new' , 'not' ,
'notnull' , 'null' , 'off' , 'offset' , 'old' , 'on' , 'only' , 'or' , 'order' ,
2009-03-02 19:09:29 +00:00
'outer' , 'overlaps' , 'placing' , 'primary' , 'references' , 'returning' , 'right' , 'select' ,
2006-09-20 21:00:45 +00:00
'session_user' , 'similar' , 'some' , 'symmetric' , 'table' , 'then' , 'to' ,
'trailing' , 'true' , 'union' , 'unique' , 'user' , 'using' , 'verbose' ,
2009-03-02 19:09:29 +00:00
'when' , 'where' , 'with'
2006-09-20 21:00:45 +00:00
);
2006-08-16 18:41:47 +00:00
return $reserved_words ;
}
}