2006-09-26 01:16:08 +04:00
< ? php
/*
* $Id $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL . For more information , see
* < http :// www . phpdoctrine . com >.
*/
2006-11-19 15:06:42 +03:00
Doctrine :: autoload ( 'Doctrine_DataDict' );
2006-09-26 01:16:08 +04:00
/**
2006-11-19 15:06:42 +03:00
* @ package Doctrine
* @ license http :// www . opensource . org / licenses / lgpl - license . php LGPL
* @ author Konsta Vesterinen < kvesteri @ cc . hut . fi >
2006-10-20 00:56:59 +04:00
* @ author Lukas Smith < smith @ pooteeweet . org > ( PEAR MDB2 library )
2006-11-19 15:06:42 +03:00
* @ version $Revision $
* @ category Object Relational Mapping
* @ link www . phpdoctrine . com
* @ since 1.0
*/
2006-11-28 01:22:31 +03:00
class Doctrine_DataDict_Mysql extends Doctrine_Connection_Module {
2006-10-20 00:56:59 +04:00
/**
* Obtain DBMS specific SQL code portion needed to declare an text type
* field to be used in statements like CREATE TABLE .
*
* @ param array $field associative array with the name of the properties
* of the field being declared as array indexes . Currently , the types
* of supported field properties are as follows :
*
* length
* Integer value that determines the maximum length of the text
* field . If this argument is missing the field should be
* declared to have the longest length allowed by the DBMS .
*
* default
* Text value to be used as default for this field .
*
* notnull
* Boolean flag that indicates whether this field is constrained
* to not be set to null .
2006-11-19 15:06:42 +03:00
*
2006-10-20 00:56:59 +04:00
* @ return string DBMS specific SQL code portion that should be used to
* declare the specified field .
*/
2006-11-26 22:48:55 +03:00
public function getNativeDeclaration ( $field ) {
2006-10-20 00:56:59 +04:00
switch ( $field [ 'type' ]) {
2006-11-28 01:22:31 +03:00
case 'char' :
$length = ( ! empty ( $field [ 'length' ])) ? $field [ 'length' ] : false ;
return $length ? 'CHAR(' . $length . ')' : 'CHAR(255)' ;
case 'varchar' :
2006-10-20 00:56:59 +04:00
case 'array' :
case 'object' :
case 'string' :
if ( empty ( $field [ 'length' ]) && array_key_exists ( 'default' , $field )) {
$field [ 'length' ] = $this -> dbh -> varchar_max_length ;
}
$length = ( ! empty ( $field [ 'length' ])) ? $field [ 'length' ] : false ;
$fixed = ( ! empty ( $field [ 'fixed' ])) ? $field [ 'fixed' ] : false ;
return $fixed ? ( $length ? 'CHAR(' . $length . ')' : 'CHAR(255)' )
: ( $length ? 'VARCHAR(' . $length . ')' : 'TEXT' );
case 'clob' :
if ( ! empty ( $field [ 'length' ])) {
$length = $field [ 'length' ];
if ( $length <= 255 ) {
return 'TINYTEXT' ;
} elseif ( $length <= 65532 ) {
return 'TEXT' ;
} elseif ( $length <= 16777215 ) {
return 'MEDIUMTEXT' ;
}
}
return 'LONGTEXT' ;
case 'blob' :
if ( ! empty ( $field [ 'length' ])) {
$length = $field [ 'length' ];
if ( $length <= 255 ) {
return 'TINYBLOB' ;
} elseif ( $length <= 65532 ) {
return 'BLOB' ;
} elseif ( $length <= 16777215 ) {
return 'MEDIUMBLOB' ;
}
}
return 'LONGBLOB' ;
case 'integer' :
if ( ! empty ( $field [ 'length' ])) {
$length = $field [ 'length' ];
if ( $length <= 1 ) {
return 'TINYINT' ;
} elseif ( $length == 2 ) {
return 'SMALLINT' ;
} elseif ( $length == 3 ) {
return 'MEDIUMINT' ;
} elseif ( $length == 4 ) {
return 'INT' ;
} elseif ( $length > 4 ) {
return 'BIGINT' ;
}
}
return 'INT' ;
case 'boolean' :
return 'TINYINT(1)' ;
case 'date' :
return 'DATE' ;
case 'time' :
return 'TIME' ;
case 'timestamp' :
return 'DATETIME' ;
case 'float' :
return 'DOUBLE' ;
case 'decimal' :
$length = ! empty ( $field [ 'length' ]) ? $field [ 'length' ] : 18 ;
return 'DECIMAL(' . $length . ',' . $this -> dbh -> options [ 'decimal_places' ] . ')' ;
}
return '' ;
}
2006-10-23 20:19:47 +04:00
/**
* Maps a native array description of a field to a MDB2 datatype and length
*
* @ param array $field native field description
* @ return array containing the various possible types , length , sign , fixed
*/
2006-11-26 22:48:55 +03:00
public function getDoctrineDeclaration ( $field ) {
2006-10-23 20:19:47 +04:00
$db_type = strtolower ( $field [ 'type' ]);
$db_type = strtok ( $db_type , '(), ' );
if ( $db_type == 'national' ) {
$db_type = strtok ( '(), ' );
}
if ( ! empty ( $field [ 'length' ])) {
$length = $field [ 'length' ];
$decimal = '' ;
} else {
$length = strtok ( '(), ' );
$decimal = strtok ( '(), ' );
}
$type = array ();
$unsigned = $fixed = null ;
switch ( $db_type ) {
2006-10-30 02:24:50 +03:00
case 'tinyint' :
$type [] = 'integer' ;
2006-10-23 20:19:47 +04:00
$type [] = 'boolean' ;
if ( preg_match ( '/^(is|has)/' , $field [ 'name' ])) {
$type = array_reverse ( $type );
}
2006-10-30 02:24:50 +03:00
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
$length = 1 ;
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'smallint' :
$type [] = 'integer' ;
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
$length = 2 ;
break ;
case 'mediumint' :
$type [] = 'integer' ;
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
$length = 3 ;
break ;
case 'int' :
case 'integer' :
$type [] = 'integer' ;
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
$length = 4 ;
break ;
case 'bigint' :
$type [] = 'integer' ;
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
$length = 8 ;
break ;
case 'tinytext' :
case 'mediumtext' :
case 'longtext' :
case 'text' :
case 'text' :
case 'varchar' :
$fixed = false ;
case 'string' :
case 'char' :
$type [] = 'text' ;
if ( $length == '1' ) {
2006-10-23 20:19:47 +04:00
$type [] = 'boolean' ;
if ( preg_match ( '/^(is|has)/' , $field [ 'name' ])) {
$type = array_reverse ( $type );
}
2006-10-30 02:24:50 +03:00
} elseif ( strstr ( $db_type , 'text' )) {
$type [] = 'clob' ;
if ( $decimal == 'binary' ) {
$type [] = 'blob' ;
}
}
if ( $fixed !== false ) {
$fixed = true ;
2006-10-23 20:19:47 +04:00
}
break ;
2006-10-30 02:24:50 +03:00
case 'enum' :
$type [] = 'text' ;
preg_match_all ( '/\'.+\'/U' , $field [ 'type' ], $matches );
$length = 0 ;
$fixed = false ;
if ( is_array ( $matches )) {
foreach ( $matches [ 0 ] as $value ) {
$length = max ( $length , strlen ( $value ) - 2 );
}
if ( $length == '1' && count ( $matches [ 0 ]) == 2 ) {
$type [] = 'boolean' ;
if ( preg_match ( '/^(is|has)/' , $field [ 'name' ])) {
$type = array_reverse ( $type );
}
}
}
$type [] = 'integer' ;
case 'set' :
$fixed = false ;
$type [] = 'text' ;
$type [] = 'integer' ;
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'date' :
$type [] = 'date' ;
$length = null ;
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'datetime' :
case 'timestamp' :
$type [] = 'timestamp' ;
$length = null ;
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'time' :
$type [] = 'time' ;
$length = null ;
break ;
case 'float' :
case 'double' :
case 'real' :
$type [] = 'float' ;
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'unknown' :
case 'decimal' :
case 'numeric' :
$type [] = 'decimal' ;
$unsigned = preg_match ( '/ unsigned/i' , $field [ 'type' ]);
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'tinyblob' :
case 'mediumblob' :
case 'longblob' :
case 'blob' :
$type [] = 'blob' ;
$length = null ;
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
case 'year' :
$type [] = 'integer' ;
$type [] = 'date' ;
$length = null ;
2006-10-23 20:19:47 +04:00
break ;
2006-10-30 02:24:50 +03:00
default :
throw new Doctrine_DataDict_Mysql_Exception ( 'unknown database attribute type: ' . $db_type );
2006-10-23 20:19:47 +04:00
}
return array ( $type , $length , $unsigned , $fixed );
}
2006-11-25 13:59:33 +03:00
/**
* Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration to be used in statements like CREATE TABLE .
*
* @ param string $charset name of the charset
* @ return string DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration .
*/
public function getCharsetFieldDeclaration ( $charset ) {
return 'CHARACTER SET ' . $charset ;
}
/**
* Obtain DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration to be used in statements like CREATE TABLE .
*
* @ param string $collation name of the collation
* @ return string DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration .
*/
public function getCollationFieldDeclaration ( $collation ) {
return 'COLLATE ' . $collation ;
}
/**
* Obtain DBMS specific SQL code portion needed to declare an integer type
* field to be used in statements like CREATE TABLE .
*
* @ param string $name name the field to be declared .
* @ param string $field associative array with the name of the properties
* of the field being declared as array indexes .
* Currently , the types of supported field
* properties are as follows :
*
* unsigned
* Boolean flag that indicates whether the field
* should be declared as unsigned integer if
* possible .
*
* default
* Integer value to be used as default for this
* field .
*
* notnull
* Boolean flag that indicates whether this field is
* constrained to not be set to null .
* @ return string DBMS specific SQL code portion that should be used to
* declare the specified field .
*/
public function getIntegerDeclaration ( $name , $field ) {
$default = $autoinc = '' ;
if ( ! empty ( $field [ 'autoincrement' ])) {
$autoinc = ' AUTO_INCREMENT PRIMARY KEY' ;
} elseif ( array_key_exists ( 'default' , $field )) {
if ( $field [ 'default' ] === '' ) {
$field [ 'default' ] = empty ( $field [ 'notnull' ]) ? null : 0 ;
}
$default = ' DEFAULT ' . $this -> conn -> getDbh () -> quote ( $field [ 'default' ]);
2006-11-28 01:22:31 +03:00
}
/**
elseif ( empty ( $field [ 'notnull' ])) {
2006-11-25 13:59:33 +03:00
$default = ' DEFAULT NULL' ;
}
2006-11-28 01:22:31 +03:00
*/
2006-11-25 13:59:33 +03:00
2006-11-28 01:22:31 +03:00
$notnull = ( isset ( $field [ 'notnull' ]) && $field [ 'notnull' ]) ? ' NOT NULL' : '' ;
$unsigned = ( isset ( $field [ 'unsigned' ]) && $field [ 'unsigned' ]) ? ' UNSIGNED' : '' ;
2006-11-26 22:48:55 +03:00
2006-11-25 13:59:33 +03:00
$name = $this -> conn -> quoteIdentifier ( $name , true );
2006-11-26 22:48:55 +03:00
return $name . ' ' . $this -> getNativeDeclaration ( $field ) . $unsigned . $default . $notnull . $autoinc ;
2006-11-25 13:59:33 +03:00
}
2006-09-26 01:16:08 +04:00
/**
* lists all databases
*
* @ return array
*/
public function listDatabases () {
2006-10-30 23:53:25 +03:00
$sql = 'SHOW DATABASES' ;
2006-10-31 21:48:13 +03:00
return $this -> dbh -> query ( $sql ) -> fetchAll ( PDO :: FETCH_COLUMN );
2006-09-26 01:16:08 +04:00
}
/**
* lists all availible database functions
*
* @ return array
*/
public function listFunctions () {
}
/**
* lists all database triggers
*
* @ param string | null $database
* @ return array
*/
public function listTriggers ( $database = null ) {
}
/**
* lists all database sequences
*
* @ param string | null $database
* @ return array
*/
public function listSequences ( $database = null ) {
}
/**
* lists table constraints
*
* @ param string $table database table name
* @ return array
*/
public function listTableConstraints ( $table ) {
2006-11-03 23:16:19 +03:00
$sql = 'select KCU.COLUMN_NAME as referencingColumn, TC.CONSTRAINT_NAME as constraintName, KCU.REFERENCED_TABLE_SCHEMA as referencedTableSchema, KCU.REFERENCED_TABLE_NAME as referencedTable, KCU.REFERENCED_COLUMN_NAME as referencedColumn from INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC inner JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU on TC.CONSTRAINT_NAME=KCU.CONSTRAINT_NAME and TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA and TC.TABLE_NAME=KCU.TABLE_NAME WHERE TC.TABLE_SCHEMA=database() AND TC.TABLE_NAME="' . $table . '" AND CONSTRAINT_TYPE="FOREIGN KEY"' ;
2006-11-24 01:54:10 +03:00
return $this -> dbh -> query ( $sql ) -> fetchAll ( PDO :: FETCH_ASSOC );
2006-09-26 01:16:08 +04:00
}
/**
* lists table constraints
*
* @ param string $table database table name
* @ return array
*/
public function listTableColumns ( $table ) {
$sql = " DESCRIBE $table " ;
$result = $this -> dbh -> query ( $sql ) -> fetchAll ( PDO :: FETCH_ASSOC );
$description = array ();
2006-10-30 23:53:25 +03:00
foreach ( $result as $key => $val2 ) {
$val = array ();
foreach ( array_keys ( $val2 ) as $valKey ){ // lowercase the key names
$val [ strtolower ( $valKey )] = $val2 [ $valKey ];
}
2006-09-26 01:24:31 +04:00
$description = array (
2006-09-26 01:16:08 +04:00
'name' => $val [ 'field' ],
'type' => $val [ 'type' ],
'primary' => ( strtolower ( $val [ 'key' ]) == 'pri' ),
'default' => $val [ 'default' ],
'notnull' => ( bool ) ( $val [ 'null' ] != 'YES' ),
2006-11-24 01:54:10 +03:00
'autoinc' => ( bool ) ( strpos ( $val [ 'extra' ], 'auto_increment' ) > - 1 ),
2006-09-26 01:16:08 +04:00
);
$columns [ $val [ 'field' ]] = new Doctrine_Schema_Column ( $description );
}
return $columns ;
}
/**
* lists table constraints
*
* @ param string $table database table name
* @ return array
*/
public function listTableIndexes ( $table ) {
}
/**
* lists tables
*
* @ param string | null $database
* @ return array
*/
public function listTables ( $database = null ) {
2006-10-20 00:56:59 +04:00
$sql = 'SHOW TABLES' ;
2006-09-26 01:16:08 +04:00
2006-10-31 21:48:13 +03:00
return $this -> dbh -> query ( $sql ) -> fetchAll ( PDO :: FETCH_COLUMN );
2006-09-26 01:16:08 +04:00
}
/**
* lists table triggers
*
* @ param string $table database table name
* @ return array
*/
public function listTableTriggers ( $table ) {
}
/**
* lists table views
*
* @ param string $table database table name
* @ return array
*/
public function listTableViews ( $table ) {
}
/**
* lists database users
*
* @ return array
*/
public function listUsers () {
}
/**
* lists database views
*
* @ param string | null $database
* @ return array
*/
public function listViews ( $database = null ) {
}
}