2008-08-21 19:36:39 +00:00
< ? php
// $Id$
/**
* @ file
* Generic Database schema code .
*/
/**
* @ defgroup schemaapi Schema API
* @ {
*
* A Drupal schema definition is an array structure representing one or
* more tables and their related keys and indexes . A schema is defined by
* hook_schema (), which usually lives in a modulename . install file .
*
* By implementing hook_schema () and specifying the tables your module
* declares , you can easily create and drop these tables on all
* supported database engines . You don ' t have to deal with the
* different SQL dialects for table creation and alteration of the
* supported database engines .
*
* hook_schema () should return an array with a key for each table that
* the module defines .
*
* The following keys are defined :
*
2009-08-02 08:16:16 +00:00
* - 'description' : A string in non - markup plain text describing this table
* and its purpose . References to other tables should be enclosed in
2008-12-20 18:24:41 +00:00
* curly - brackets . For example , the node_revisions table
2008-08-21 19:36:39 +00:00
* description field might contain " Stores per-revision title and
* body data for each { node } . "
* - 'fields' : An associative array ( 'fieldname' => specification )
2008-12-20 18:24:41 +00:00
* that describes the table ' s database columns . The specification
* is also an array . The following specification parameters are defined :
2008-08-21 19:36:39 +00:00
*
2009-08-02 08:16:16 +00:00
* - 'description' : A string in non - markup plain text describing this field
* and its purpose . References to other tables should be enclosed in
2008-12-20 18:24:41 +00:00
* curly - brackets . For example , the node table vid field
2008-08-21 19:36:39 +00:00
* description might contain " Always holds the largest (most
2008-12-03 16:32:22 +00:00
* recent ) { node_revision } . vid value for this nid . "
2009-10-08 02:44:54 +00:00
* - 'type' : The generic datatype : 'char' , 'varchar' , 'text' , 'blob' , 'int' ,
* 'float' , 'numeric' , 'serial' , 'date' , 'datetime' or 'time' . Most types
* types just map to the according database engine specific datatypes . Use
* 'serial' for auto incrementing fields . This will expand to ' INT
* auto_increment ' on MySQL .
2009-08-02 08:16:16 +00:00
* - 'serialize' : A boolean indicating whether the field will be stored as
* a serialized string .
2008-08-21 19:36:39 +00:00
* - 'size' : The data size : 'tiny' , 'small' , 'medium' , 'normal' ,
2008-12-20 18:24:41 +00:00
* 'big' . This is a hint about the largest value the field will
2008-08-21 19:36:39 +00:00
* store and determines which of the database engine specific
* datatypes will be used ( e . g . on MySQL , TINYINT vs . INT vs . BIGINT ) .
* 'normal' , the default , selects the base type ( e . g . on MySQL ,
* INT , VARCHAR , BLOB , etc . ) .
*
* Not all sizes are available for all data types . See
* db_type_map () for possible combinations .
* - 'not null' : If true , no NULL values will be allowed in this
2008-12-20 18:24:41 +00:00
* database column . Defaults to false .
* - 'default' : The field ' s default value . The PHP type of the
* value matters : '' , '0' , and 0 are all different . If you
2008-08-21 19:36:39 +00:00
* specify '0' as the default value for a type 'int' field it
* will not work because '0' is a string containing the
* character " zero " , not an integer .
2009-07-09 10:12:14 +00:00
* - 'length' : The maximal length of a type 'char' , 'varchar' or 'text'
2008-12-20 18:24:41 +00:00
* field . Ignored for other field types .
2008-08-21 19:36:39 +00:00
* - 'unsigned' : A boolean indicating whether a type 'int' , 'float'
2008-12-20 18:24:41 +00:00
* and 'numeric' only is signed or unsigned . Defaults to
* FALSE . Ignored for other field types .
2008-08-21 19:36:39 +00:00
* - 'precision' , 'scale' : For type 'numeric' fields , indicates
* the precision ( total number of significant digits ) and scale
2008-12-20 18:24:41 +00:00
* ( decimal digits right of the decimal point ) . Both values are
* mandatory . Ignored for other field types .
2008-08-21 19:36:39 +00:00
*
* All parameters apart from 'type' are optional except that type
* 'numeric' columns must specify 'precision' and 'scale' .
*
* - 'primary key' : An array of one or more key column specifiers ( see below )
* that form the primary key .
2009-01-18 06:47:58 +00:00
* - 'unique keys' : An associative array of unique keys ( 'keyname' =>
2008-12-20 18:24:41 +00:00
* specification ) . Each specification is an array of one or more
2008-08-21 19:36:39 +00:00
* key column specifiers ( see below ) that form a unique key on the table .
2009-02-24 16:34:46 +00:00
* - 'foreign keys' : An associative array , each key references a column
* of the local table , each value is an array with a single key pair as
* 'tablename' => 'column' where 'column' is the foreign column to
* reference .
2010-01-25 10:38:35 +00:00
* - 'indexes' : An associative array of indexes ( 'indexname' =>
2008-12-20 18:24:41 +00:00
* specification ) . Each specification is an array of one or more
2008-08-21 19:36:39 +00:00
* key column specifiers ( see below ) that form an index on the
* table .
*
* A key column specifier is either a string naming a column or an
* array of two elements , column name and length , specifying a prefix
* of the named column .
*
* As an example , here is a SUBSET of the schema definition for
2008-12-20 18:24:41 +00:00
* Drupal 's ' node ' table . It show four fields ( nid , vid , type , and
2008-08-21 19:36:39 +00:00
* title ), the primary key on field 'nid' , a unique key named 'vid' on
* field 'vid' , and two indexes , one named 'nid' on field 'nid' and
* one named 'node_title_type' on the field 'title' and the first four
* bytes of the field 'type' :
*
* @ code
* $schema [ 'node' ] = array (
2009-06-01 22:07:10 +00:00
* 'description' => 'The base table for nodes.' ,
2008-08-21 19:36:39 +00:00
* 'fields' => array (
2009-06-01 22:07:10 +00:00
* 'nid' => array ( 'type' => 'serial' , 'unsigned' => TRUE , 'not null' => TRUE ),
* 'vid' => array ( 'type' => 'int' , 'unsigned' => TRUE , 'not null' => TRUE , 'default' => 0 ),
* 'type' => array ( 'type' => 'varchar' , 'length' => 32 , 'not null' => TRUE , 'default' => '' ),
* 'language' => array ( 'type' => 'varchar' , 'length' => 12 , 'not null' => TRUE , 'default' => '' ),
* 'title' => array ( 'type' => 'varchar' , 'length' => 255 , 'not null' => TRUE , 'default' => '' ),
* 'uid' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'status' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 1 ),
* 'created' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'changed' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'comment' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'promote' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'moderate' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'sticky' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
* 'tnid' => array ( 'type' => 'int' , 'unsigned' => TRUE , 'not null' => TRUE , 'default' => 0 ),
* 'translate' => array ( 'type' => 'int' , 'not null' => TRUE , 'default' => 0 ),
2008-08-21 19:36:39 +00:00
* ),
* 'indexes' => array (
2009-06-01 22:07:10 +00:00
* 'node_changed' => array ( 'changed' ),
* 'node_created' => array ( 'created' ),
* 'node_moderate' => array ( 'moderate' ),
* 'node_frontpage' => array ( 'promote' , 'status' , 'sticky' , 'created' ),
* 'node_status_type' => array ( 'status' , 'type' , 'nid' ),
2008-08-21 19:36:39 +00:00
* 'node_title_type' => array ( 'title' , array ( 'type' , 4 )),
2009-06-01 22:07:10 +00:00
* 'node_type' => array ( array ( 'type' , 4 )),
* 'uid' => array ( 'uid' ),
* 'tnid' => array ( 'tnid' ),
* 'translate' => array ( 'translate' ),
2008-08-21 19:36:39 +00:00
* ),
2009-06-01 22:07:10 +00:00
* 'unique keys' => array (
* 'vid' => array ( 'vid' ),
* ),
* 'foreign keys' => array (
* 'vid' => array ( 'node_revision' => 'vid' ),
* 'uid' => array ( 'users' => 'uid' ),
* ),
* 'primary key' => array ( 'nid' ),
2008-08-21 19:36:39 +00:00
* );
* @ endcode
*
* @ see drupal_install_schema ()
*/
2009-08-29 05:43:35 +00:00
abstract class DatabaseSchema implements QueryPlaceholderInterface {
2008-09-03 12:04:49 +00:00
2008-08-21 19:36:39 +00:00
protected $connection ;
2008-09-03 12:04:49 +00:00
2009-08-29 05:43:35 +00:00
/**
* The placeholder counter .
*/
protected $placeholder = 0 ;
2008-08-21 19:36:39 +00:00
public function __construct ( $connection ) {
$this -> connection = $connection ;
}
2008-09-03 12:04:49 +00:00
2009-08-29 05:43:35 +00:00
public function nextPlaceholder () {
return $this -> placeholder ++ ;
}
2009-01-08 09:52:12 +00:00
/**
* Build a condition to match a table name against a standard information_schema .
*
* The information_schema is a SQL standard that provides information about the
* database server and the databases , schemas , tables , columns and users within
2009-01-26 14:08:44 +00:00
* it . This makes information_schema a useful tool to use across the drupal
2009-01-08 09:52:12 +00:00
* database drivers and is used by a few different functions . The function below
* describes the conditions to be meet when querying information_schema . tables
* for drupal tables or information associated with drupal tables . Even though
* this is the standard method , not all databases follow standards and so this
* method should be overwritten by a database driver if the database provider
* uses alternate methods . Because information_schema . tables is used in a few
* different functions , a database driver will only need to override this function
* to make all the others work . For example see includes / databases / mysql / schema . inc .
*
* @ param $table_name
* The name of the table to explode .
* @ param $operator
* The operator to apply on the 'table' part of the condition .
2009-12-04 16:31:04 +00:00
* @ return QueryConditionInterface
2009-01-08 09:52:12 +00:00
* A DatabaseCondition object .
*/
protected function buildTableNameCondition ( $table_name , $operator = '=' ) {
$info = Database :: getConnectionInfo ();
// The table name may describe the schema eg. schema.table.
if ( strpos ( $table_name , '.' )) {
list ( $schema , $table_name ) = explode ( '.' , $table_name );
}
else {
$schema = 'public' ;
}
2009-01-19 01:28:28 +00:00
$condition = new DatabaseCondition ( 'AND' );
$condition -> condition ( 'table_catalog' , $info [ 'default' ][ 'database' ]);
$condition -> condition ( 'table_schema' , $schema );
$condition -> condition ( 'table_name' , $table_name , $operator );
2009-01-08 09:52:12 +00:00
return $condition ;
}
2008-08-21 19:36:39 +00:00
/**
* Check if a table exists .
2009-01-26 14:08:44 +00:00
*
2009-01-08 09:52:12 +00:00
* @ param $table
* The name of the table in drupal ( no prefixing ) .
* @ return
2010-03-01 11:30:37 +00:00
* TRUE if the given table exists , otherwise FALSE .
2008-08-21 19:36:39 +00:00
*/
2009-01-08 09:52:12 +00:00
public function tableExists ( $table ) {
$condition = $this -> buildTableNameCondition ( $this -> connection -> prefixTables ( '{' . $table . '}' ));
2009-08-29 05:43:35 +00:00
$condition -> compile ( $this -> connection , $this );
2009-01-08 09:52:12 +00:00
// Normally, we would heartily discourage the use of string
2010-01-25 10:38:35 +00:00
// concatenation for conditionals like this however, we
2009-01-08 09:52:12 +00:00
// couldn't use db_select() here because it would prefix
// information_schema.tables and the query would fail.
2009-05-29 01:51:46 +00:00
// Don't use {} around information_schema.tables table.
2010-03-01 11:30:37 +00:00
return ( bool ) $this -> connection -> query ( " SELECT 1 FROM information_schema.tables WHERE " . ( string ) $condition , $condition -> arguments ()) -> fetchField ();
2009-01-08 09:52:12 +00:00
}
/**
* Find all tables that are like the specified base table name .
*
* @ param $table_expression
* An SQL expression , for example " simpletest% " ( without the quotes ) .
* BEWARE : this is not prefixed , the caller should take care of that .
* @ return
* Array , both the keys and the values are the matching tables .
*/
public function findTables ( $table_expression ) {
$condition = $this -> buildTableNameCondition ( $table_expression , 'LIKE' );
2009-08-29 05:43:35 +00:00
$condition -> compile ( $this -> connection , $this );
2009-01-08 09:52:12 +00:00
// Normally, we would heartily discourage the use of string
2010-01-25 10:38:35 +00:00
// concatenation for conditionals like this however, we
2009-01-08 09:52:12 +00:00
// couldn't use db_select() here because it would prefix
// information_schema.tables and the query would fail.
2009-05-29 01:51:46 +00:00
// Don't use {} around information_schema.tables table.
2010-03-01 11:30:37 +00:00
return $this -> connection -> query ( " SELECT table_name FROM information_schema.tables WHERE " . ( string ) $condition , $condition -> arguments ()) -> fetchAllKeyed ( 0 , 0 );
2009-01-08 09:52:12 +00:00
}
2008-09-03 12:04:49 +00:00
2008-08-21 19:36:39 +00:00
/**
* Check if a column exists in the given table .
2010-03-01 11:30:37 +00:00
*
* @ param $table
* The name of the table in drupal ( no prefixing ) .
* @ param $name
* The name of the column .
* @ return
* TRUE if the given column exists , otherwise FALSE .
2008-08-21 19:36:39 +00:00
*/
2009-01-08 09:52:12 +00:00
public function columnExists ( $table , $column ) {
$condition = $this -> buildTableNameCondition ( $this -> connection -> prefixTables ( '{' . $table . '}' ));
$condition -> condition ( 'column_name' , $column );
2009-08-29 05:43:35 +00:00
$condition -> compile ( $this -> connection , $this );
2009-01-08 09:52:12 +00:00
// Normally, we would heartily discourage the use of string
2010-01-25 10:38:35 +00:00
// concatenation for conditionals like this however, we
2009-01-08 09:52:12 +00:00
// couldn't use db_select() here because it would prefix
// information_schema.tables and the query would fail.
2009-05-29 01:51:46 +00:00
// Don't use {} around information_schema.columns table.
2010-03-01 11:30:37 +00:00
return ( bool ) $this -> connection -> query ( " SELECT 1 FROM information_schema.columns WHERE " . ( string ) $condition , $condition -> arguments ()) -> fetchField ();
2009-01-08 09:52:12 +00:00
}
2008-09-03 12:04:49 +00:00
2008-08-21 19:36:39 +00:00
/**
* This maps a generic data type in combination with its data size
* to the engine - specific data type .
*/
abstract public function getFieldTypeMap ();
2008-09-03 12:04:49 +00:00
2008-08-21 19:36:39 +00:00
/**
* Rename a table .
*
* @ param $table
* The table to be renamed .
* @ param $new_name
* The new name for the table .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table doesn ' t exist .
* @ throws DatabaseSchemaObjectExistsException
2010-03-01 06:27:58 +00:00
* If a table with the specified new name already exists .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function renameTable ( $table , $new_name );
2008-08-21 19:36:39 +00:00
/**
* Drop a table .
*
* @ param $table
* The table to be dropped .
2010-02-28 20:03:05 +00:00
* @ return
* TRUE if the table was successfully dropped , FALSE if there was no table
* by that name to begin with .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function dropTable ( $table );
2008-09-03 12:04:49 +00:00
2008-08-21 19:36:39 +00:00
/**
* Add a new field to a table .
*
* @ param $table
* Name of the table to be altered .
* @ param $field
* Name of the field to be added .
* @ param $spec
* The field specification array , as taken from a schema definition .
* The specification may also contain the key 'initial' , the newly
* created field will be set to the value of the key in all rows .
* This is most useful for creating NOT NULL columns with no default
* value in existing tables .
* @ param $keys_new
* Optional keys and indexes specification to be created on the
* table along with adding the field . The format is the same as a
2008-12-20 18:24:41 +00:00
* table specification but without the 'fields' element . If you are
2008-08-21 19:36:39 +00:00
* adding a type 'serial' field , you MUST specify at least one key
2010-01-30 07:54:01 +00:00
* or index including it in this array . See db_change_field () for more
2008-08-21 19:36:39 +00:00
* explanation why .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table doesn ' t exist .
* @ throws DatabaseSchemaObjectExistsException
* If the specified table already has a field by that name .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function addField ( $table , $field , $spec , $keys_new = array ());
2008-08-21 19:36:39 +00:00
/**
* Drop a field .
*
* @ param $table
* The table to be altered .
* @ param $field
* The field to be dropped .
2010-02-28 20:03:05 +00:00
* @ return
* TRUE if the field was successfully dropped , FALSE if there was no field
* by that name to begin with .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function dropField ( $table , $field );
2008-08-21 19:36:39 +00:00
/**
* Set the default value for a field .
*
* @ param $table
* The table to be altered .
* @ param $field
* The field to be altered .
* @ param $default
* Default value to be set . NULL for 'default NULL' .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table or field doesn ' t exist .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function fieldSetDefault ( $table , $field , $default );
2008-08-21 19:36:39 +00:00
/**
* Set a field to have no default value .
*
* @ param $table
* The table to be altered .
* @ param $field
* The field to be altered .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table or field doesn ' t exist .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function fieldSetNoDefault ( $table , $field );
2008-08-21 19:36:39 +00:00
2009-12-15 08:30:53 +00:00
/**
2010-03-01 11:30:37 +00:00
* Checks if an index exists in the given table .
2009-12-15 08:30:53 +00:00
*
* @ param $table
2010-03-01 11:30:37 +00:00
* The name of the table in drupal ( no prefixing ) .
2009-12-15 08:30:53 +00:00
* @ param $name
2010-03-01 11:30:37 +00:00
* The name of the index in drupal ( no prefixing ) .
2009-12-15 08:30:53 +00:00
* @ return
2010-03-01 11:30:37 +00:00
* TRUE if the given index exists , otherwise FALSE .
2009-12-15 08:30:53 +00:00
*/
abstract public function indexExists ( $table , $name );
2008-08-21 19:36:39 +00:00
/**
* Add a primary key .
*
* @ param $table
* The table to be altered .
* @ param $fields
* Fields for the primary key .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table doesn ' t exist .
* @ throws DatabaseSchemaObjectExistsException
* If the specified table already has a primary key .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function addPrimaryKey ( $table , $fields );
2008-08-21 19:36:39 +00:00
/**
* Drop the primary key .
*
* @ param $table
* The table to be altered .
2010-02-28 20:03:05 +00:00
* @ return
* TRUE if the primary key was successfully dropped , FALSE if there was no
* primary key on this table to begin with .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function dropPrimaryKey ( $table );
2008-08-21 19:36:39 +00:00
/**
* Add a unique key .
*
* @ param $table
* The table to be altered .
* @ param $name
* The name of the key .
* @ param $fields
* An array of field names .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table doesn ' t exist .
* @ throws DatabaseSchemaObjectExistsException
* If the specified table already has a key by that name .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function addUniqueKey ( $table , $name , $fields );
2008-08-21 19:36:39 +00:00
/**
* Drop a unique key .
*
* @ param $table
* The table to be altered .
* @ param $name
* The name of the key .
2010-02-28 20:03:05 +00:00
* @ return
* TRUE if the key was successfully dropped , FALSE if there was no key by
* that name to begin with .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function dropUniqueKey ( $table , $name );
2008-08-21 19:36:39 +00:00
/**
* Add an index .
*
* @ param $table
* The table to be altered .
* @ param $name
* The name of the index .
* @ param $fields
* An array of field names .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table doesn ' t exist .
* @ throws DatabaseSchemaObjectExistsException
* If the specified table already has an index by that name .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function addIndex ( $table , $name , $fields );
2008-08-21 19:36:39 +00:00
/**
* Drop an index .
*
* @ param $table
* The table to be altered .
* @ param $name
* The name of the index .
2010-02-28 20:03:05 +00:00
* @ return
* TRUE if the index was successfully dropped , FALSE if there was no index
* by that name to begin with .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function dropIndex ( $table , $name );
2008-08-21 19:36:39 +00:00
/**
* Change a field definition .
*
* IMPORTANT NOTE : To maintain database portability , you have to explicitly
* recreate all indices and primary keys that are using the changed field .
*
* That means that you have to drop all affected keys and indexes with
* db_drop_ { primary_key , unique_key , index }() before calling db_change_field () .
* To recreate the keys and indices , pass the key definitions as the
* optional $keys_new argument directly to db_change_field () .
*
* For example , suppose you have :
* @ code
* $schema [ 'foo' ] = array (
* 'fields' => array (
* 'bar' => array ( 'type' => 'int' , 'not null' => TRUE )
* ),
* 'primary key' => array ( 'bar' )
* );
* @ endcode
* and you want to change foo . bar to be type serial , leaving it as the
2008-12-20 18:24:41 +00:00
* primary key . The correct sequence is :
2008-08-21 19:36:39 +00:00
* @ code
2009-09-29 15:13:57 +00:00
* db_drop_primary_key ( 'foo' );
* db_change_field ( 'foo' , 'bar' , 'bar' ,
2008-08-21 19:36:39 +00:00
* array ( 'type' => 'serial' , 'not null' => TRUE ),
* array ( 'primary key' => array ( 'bar' )));
* @ endcode
*
* The reasons for this are due to the different database engines :
*
* On PostgreSQL , changing a field definition involves adding a new field
* and dropping an old one which * causes any indices , primary keys and
* sequences ( from serial - type fields ) that use the changed field to be dropped .
*
* On MySQL , all type 'serial' fields must be part of at least one key
2008-12-20 18:24:41 +00:00
* or index as soon as they are created . You cannot use
2008-08-21 19:36:39 +00:00
* db_add_ { primary_key , unique_key , index }() for this purpose because
* the ALTER TABLE command will fail to add the column without a key
2008-12-20 18:24:41 +00:00
* or index specification . The solution is to use the optional
2008-08-21 19:36:39 +00:00
* $keys_new argument to create the key or index at the same time as
* field .
*
* You could use db_add_ { primary_key , unique_key , index }() in all cases
* unless you are converting a field to be type serial . You can use
* the $keys_new argument in all cases .
*
* @ param $table
* Name of the table .
* @ param $field
* Name of the field to change .
* @ param $field_new
* New name for the field ( set to the same as $field if you don ' t want to change the name ) .
* @ param $spec
* The field specification for the new field .
* @ param $keys_new
* Optional keys and indexes specification to be created on the
* table along with changing the field . The format is the same as a
* table specification but without the 'fields' element .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectDoesNotExistException
* If the specified table or source field doesn ' t exist .
* @ throws DatabaseSchemaObjectExistsException
* If the specified destination field already exists .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
abstract public function changeField ( $table , $field , $field_new , $spec , $keys_new = array ());
2008-08-21 19:36:39 +00:00
/**
* Create a new table from a Drupal table definition .
*
* @ param $name
* The name of the table to create .
* @ param $table
* A Schema API table definition array .
2010-02-28 20:03:05 +00:00
* @ throws DatabaseSchemaObjectExistsException
* If the specified table already exists .
2008-08-21 19:36:39 +00:00
*/
2009-09-29 15:13:57 +00:00
public function createTable ( $name , $table ) {
2010-02-28 20:03:05 +00:00
if ( $this -> tableExists ( $name )) {
throw new DatabaseSchemaObjectExistsException ( t ( 'Table %name already exists.' , array ( '%name' => $name )));
}
2009-09-29 15:13:57 +00:00
$statements = $this -> createTableSql ( $name , $table );
2008-08-21 19:36:39 +00:00
foreach ( $statements as $statement ) {
2009-09-29 15:13:57 +00:00
$this -> connection -> query ( $statement );
2008-08-21 19:36:39 +00:00
}
}
2008-09-03 12:04:49 +00:00
2008-08-21 19:36:39 +00:00
/**
* Return an array of field names from an array of key / index column specifiers .
*
* This is usually an identity function but if a key / index uses a column prefix
* specification , this function extracts just the name .
*
* @ param $fields
* An array of key / index column specifiers .
* @ return
* An array of field names .
*/
public function fieldNames ( $fields ) {
2009-09-29 15:13:57 +00:00
$return = array ();
2008-08-21 19:36:39 +00:00
foreach ( $fields as $field ) {
if ( is_array ( $field )) {
2009-09-29 15:13:57 +00:00
$return [] = $field [ 0 ];
2008-08-21 19:36:39 +00:00
}
else {
2009-09-29 15:13:57 +00:00
$return [] = $field ;
2008-08-21 19:36:39 +00:00
}
}
2009-09-29 15:13:57 +00:00
return $return ;
2008-08-21 19:36:39 +00:00
}
2009-03-14 20:34:17 +00:00
/**
* Prepare a table or column comment for database query .
2009-05-24 17:39:35 +00:00
*
2009-03-14 20:34:17 +00:00
* @ param $comment
* The comment string to prepare .
* @ param $length
* Optional upper limit on the returned string length .
* @ return
* The prepared comment .
*/
public function prepareComment ( $comment , $length = NULL ) {
return $this -> connection -> quote ( $comment );
}
2008-08-21 19:36:39 +00:00
}
2010-02-28 20:03:05 +00:00
/**
2010-03-01 06:27:58 +00:00
* Exception thrown if an object being created already exists .
*
* For example , this exception should be thrown whenever there is an attempt to
* create a new database table , field , or index that already exists in the
* database schema .
2010-02-28 20:03:05 +00:00
*/
class DatabaseSchemaObjectExistsException extends Exception {}
/**
2010-03-01 06:27:58 +00:00
* Exception thrown if an object being modified doesn ' t exist yet .
*
* For example , this exception should be thrown whenever there is an attempt to
* modify a database table , field , or index that does not currently exist in
* the database schema .
2010-02-28 20:03:05 +00:00
*/
class DatabaseSchemaObjectDoesNotExistException extends Exception {}
2008-08-21 19:36:39 +00:00
/**
* @ } End of " defgroup schemaapi " .
*/