1
0
mirror of synced 2024-12-13 06:46:03 +03:00

[2.0] Oracle SchemaManager tests and general refactoring of tests

This commit is contained in:
jwage 2009-05-30 02:27:50 +00:00
parent 92b395cff2
commit d34a05a257
18 changed files with 778 additions and 1234 deletions

View File

@ -83,6 +83,6 @@ class Driver implements \Doctrine\DBAL\Driver
public function getDatabase(\Doctrine\DBAL\Connection $conn)
{
$params = $conn->getParams();
return $params['dbname'];
return $params['user'];
}
}

View File

@ -520,16 +520,16 @@ abstract class AbstractPlatform
public function getDropConstraintSql($table, $name, $primary = false)
{
$table = $this->_conn->getDatabasePlatform()->quoteIdentifier($table);
$name = $this->_conn->getDatabasePlatform()->quoteIdentifier($name);
$table = $this->quoteIdentifier($table);
$name = $this->quoteIdentifier($name);
return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $name;
}
public function getDropForeignKeySql($table, $name)
{
$table = $this->_conn->getDatabasePlatform()->quoteIdentifier($table);
$name = $this->_conn->getDatabasePlatform()->quoteIdentifier($name);
$table = $this->quoteIdentifier($table);
$name = $this->quoteIdentifier($name);
return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $name;
}

View File

@ -101,18 +101,14 @@ class OraclePlatform extends AbstractPlatform
return 'SYS_GUID()';
}
/**
* {@inheritdoc}
*
* @return string
* @override
*/
public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1)
{
return 'CREATE SEQUENCE ' . $this->quoteIdentifier($sequenceName)
. ' START WITH ' . $start . ' INCREMENT BY ' . $allocationSize;
$query = 'CREATE SEQUENCE ' . $this->quoteIdentifier($sequenceName) . ' START WITH ' . $start . ' INCREMENT BY 1 NOCACHE';
$query .= ($start < 1 ? ' MINVALUE ' . $start : '');
return $query;
}
/**
* {@inheritdoc}
*
@ -204,6 +200,228 @@ class OraclePlatform extends AbstractPlatform
: ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)');
}
public function getListDatabasesSql()
{
return 'SELECT username FROM sys.dba_users';
}
public function getListFunctionsSql()
{
return "SELECT name FROM sys.user_source WHERE line = 1 AND type = 'FUNCTION'";
}
public function getCreateTableSql($table, array $columns, array $options = array())
{
$indexes = isset($options['indexes']) ? $options['indexes']:array();
$options['indexes'] = array();
$sql = parent::getCreateTableSql($table, $columns, $options);
foreach ($columns as $name => $column) {
if (isset($column['sequence'])) {
$sql[] = $this->getCreateSequenceSql($column['sequence'], 1);
}
if (isset($column['autoincrement']) && $column['autoincrement'] ||
(isset($column['autoinc']) && $column['autoinc'])) {
$sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table));
}
}
if (isset($indexes) && ! empty($indexes)) {
foreach ($indexes as $indexName => $definition) {
// create nonunique indexes, as they are a part od CREATE TABLE DDL
if ( ! isset($definition['type']) ||
(isset($definition['type']) && strtolower($definition['type']) != 'unique')) {
$sql[] = $this->getCreateIndexSql($table, $indexName, $definition);
}
}
}
return $sql;
}
public function getListTableIndexesSql($table)
{
return "SELECT * FROM user_indexes"
. " WHERE table_name = '" . strtoupper($table) . "'";
}
public function getListTablesSql()
{
return 'SELECT * FROM sys.user_tables';
}
public function getListUsersSql()
{
return 'SELECT * FROM sys.dba_users';
}
public function getListViewsSql()
{
return 'SELECT view_name FROM sys.user_views';
}
public function getCreateViewSql($name, $sql)
{
return 'CREATE VIEW ' . $name . ' AS ' . $sql;
}
public function getDropViewSql($name)
{
return 'DROP VIEW '. $name;
}
public function getCreateAutoincrementSql($name, $table, $start = 1)
{
$table = strtoupper($table);
$sql = array();
$indexName = $table . '_AI_PK';
$definition = array(
'primary' => true,
'fields' => array($name => true),
);
$sql[] = 'DECLARE
constraints_Count NUMBER;
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\';
IF constraints_Count = 0 OR constraints_Count = \'\' THEN
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSql($table, $indexName, $definition).'\';
END IF;
END;';
$sequenceName = $table . '_SEQ';
$sql[] = $this->getCreateSequenceSql($sequenceName, $start);
$triggerName = $this->quoteIdentifier($table . '_AI_PK', true);
$table = $this->quoteIdentifier($table, true);
$name = $this->quoteIdentifier($name, true);
$sql[] = 'CREATE TRIGGER ' . $triggerName . '
BEFORE INSERT
ON ' . $table . '
FOR EACH ROW
DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
SELECT ' . $this->quoteIdentifier($sequenceName) . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL;
IF (:NEW.' . $name . ' IS NULL OR :NEW.'.$name.' = 0) THEN
SELECT ' . $this->quoteIdentifier($sequenceName) . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = \'' . $sequenceName . '\';
SELECT :NEW.' . $name . ' INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ' . $this->quoteIdentifier($sequenceName) . '.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
END IF;
END;';
return $sql;
}
public function getDropAutoincrementSql($table)
{
$table = strtoupper($table);
$trigger = $table . '_AI_PK';
if ($trigger) {
$sql[] = 'DROP TRIGGER ' . $trigger;
$sql[] = $this->getDropSequenceSql($table.'_SEQ');
$indexName = $table . '_AI_PK';
$sql[] = $this->getDropConstraintSql($table, $indexName);
}
return $sql;
}
public function getListTableConstraintsSql($table)
{
$table = strtoupper($table);
return 'SELECT * FROM user_constraints WHERE table_name = \'' . $table . '\'';
}
public function getListTableColumnsSql($table)
{
$table = strtoupper($table);
return "SELECT * FROM all_tab_columns WHERE table_name = '" . $table . "' ORDER BY column_name";
}
public function getDropSequenceSql($sequenceName)
{
return 'DROP SEQUENCE ' . $this->quoteIdentifier($sequenceName);
}
public function getDropDatabaseSql($database)
{
return 'DROP USER ' . $database . ' CASCADE';
}
public function getAlterTableSql($name, array $changes, $check = false)
{
if ( ! $name) {
throw DoctrineException::updateMe('no valid table name specified');
}
foreach ($changes as $changeName => $change) {
switch ($changeName) {
case 'add':
case 'remove':
case 'change':
case 'name':
case 'rename':
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('change type "' . $changeName . '" not yet supported');
}
}
if ($check) {
return false;
}
$name = $this->quoteIdentifier($name);
if ( ! empty($changes['add']) && is_array($changes['add'])) {
$fields = array();
foreach ($changes['add'] as $fieldName => $field) {
$fields[] = $this->getColumnDeclarationSql($fieldName, $field);
}
$sql[] = 'ALTER TABLE ' . $name . ' ADD (' . implode(', ', $fields) . ')';
}
if ( ! empty($changes['change']) && is_array($changes['change'])) {
$fields = array();
foreach ($changes['change'] as $fieldName => $field) {
$fields[] = $fieldName. ' ' . $this->getColumnDeclarationSql('', $field['definition']);
}
$sql[] = 'ALTER TABLE ' . $name . ' MODIFY (' . implode(', ', $fields) . ')';
}
if ( ! empty($changes['rename']) && is_array($changes['rename'])) {
foreach ($changes['rename'] as $fieldName => $field) {
$sql[] = 'ALTER TABLE ' . $name . ' RENAME COLUMN ' . $this->quoteIdentifier($fieldName)
. ' TO ' . $this->quoteIdentifier($field['name']);
}
}
if ( ! empty($changes['remove']) && is_array($changes['remove'])) {
$fields = array();
foreach ($changes['remove'] as $fieldName => $field) {
$fields[] = $this->quoteIdentifier($fieldName);
}
$sql[] = 'ALTER TABLE ' . $name . ' DROP COLUMN ' . implode(', ', $fields);
}
if ( ! empty($changes['name'])) {
$changeName = $this->quoteIdentifier($changes['name']);
$sql[] = 'ALTER TABLE ' . $name . ' RENAME TO ' . $changeName;
}
return $sql;
}
/**
* Whether the platform prefers sequences for ID generation.
*

View File

@ -22,6 +22,7 @@
namespace Doctrine\DBAL\Schema;
use \Doctrine\DBAL\Types;
use \Doctrine\Common\DoctrineException;
/**
* Base class for schema managers. Schema managers are used to inspect and/or
@ -865,4 +866,61 @@ abstract class AbstractSchemaManager
}
return $result;
}
public function tryMethod()
{
$args = func_get_args();
$method = $args[0];
unset($args[0]);
$args = array_values($args);
try {
return call_user_func_array(array($this, $method), $args);
} catch (\Exception $e) {
return false;
}
}
private function _handleDropAndCreate($method, $arguments)
{
if (substr($method, 0, 13) == 'dropAndCreate') {
$base = substr($method, 13, strlen($method));
$dropMethod = 'drop' . $base;
$createMethod = 'create' . $base;
call_user_func_array(array($this, 'tryMethod'),
array_merge(array($dropMethod), $arguments));
call_user_func_array(array($this, 'tryMethod'),
array_merge(array($createMethod), $arguments));
return true;
}
return false;
}
private function _handleTryMethod($method, $arguments)
{
if (substr($method, 0, 3) == 'try') {
$method = substr($method, 3, strlen($method));
$method = strtolower($method[0]).substr($method, 1, strlen($method));
return call_user_func_array(array($this, 'tryMethod'),
array_merge(array($method), $arguments));
}
}
public function __call($method, $arguments)
{
if ($result = $this->_handleDropAndCreate($method, $arguments)) {
return $result;
}
if ($result = $this->_handleTryMethod($method, $arguments)) {
return $result;
}
throw DoctrineException::updateMe("Invalid method named `" . $method . "` on class `" . __CLASS__ . "`");
}
}

View File

@ -579,18 +579,6 @@ class FirebirdSchemaManager extends AbstractSchemaManager
return $result;
}
/**
* A method to return the required SQL string that fits between CREATE ... TABLE
* to create the table as a temporary table.
*
* @return string The string required to be placed between "CREATE" and "TABLE"
* to generate a temporary table, if possible.
*/
public function getTemporaryTableQuery()
{
return 'GLOBAL TEMPORARY';
}
/**
* create sequence
*

View File

@ -62,16 +62,6 @@ class MsSqlSchemaManager extends AbstractSchemaManager
return $this->conn->standaloneQuery('DROP DATABASE ' . $name, null, true);
}
/**
* Override the parent method.
*
* @return string The string required to be placed between "CREATE" and "TABLE"
* to generate a temporary table, if possible.
*/
public function getTemporaryTableQuery()
{
return '';
}
/**
* alter an existing table
*

View File

@ -34,10 +34,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
{
protected function _getPortableViewDefinition($view)
{
return array(
'name' => $view['table_name'],
'sql' => $view['view_definition']
);
return $view['table_name'];
}
protected function _getPortableTableDefinition($table)

View File

@ -31,158 +31,184 @@ namespace Doctrine\DBAL\Schema;
* @since 2.0
*/
class OracleSchemaManager extends AbstractSchemaManager
{
/**
* create a new database
*
* @param object $db database object that is extended by this class
* @param string $name name of the database that should be created
* @return mixed MDB2_OK on success, a MDB2 error on failure
* @access public
*/
public function createDatabase($name)
{
protected function _getPortableViewDefinition($view)
{
if ( ! $this->conn->getAttribute(Doctrine::ATTR_EMULATE_DATABASE))
throw \Doctrine\Common\DoctrineException::updateMe('database creation is only supported if the "emulate_database" attribute is enabled');
return array(
'name' => $view['view_name']
);
}
$username = sprintf($this->conn->getAttribute(Doctrine::ATTR_DB_NAME_FORMAT), $name);
$password = $this->conn->dsn['password'] ? $this->conn->dsn['password'] : $name;
protected function _getPortableUserDefinition($user)
{
return array(
'user' => $user['username'],
'password' => $user['password']
);
}
$tablespace = $this->conn->getAttribute(Doctrine::ATTR_DB_NAME_FORMAT)
? ' DEFAULT TABLESPACE '.$this->conn->options['default_tablespace'] : '';
protected function _getPortableTableDefinition($table)
{
return $table['table_name'];
}
$query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password . $tablespace;
$result = $this->conn->exec($query);
protected function _getPortableTableIndexDefinition($tableIndex)
{
return array(
'name' => $tableIndex['index_name'],
'unique' => (isset($tableIndex['uniqueness']) && $tableIndex['uniqueness'] == 'UNIQUE') ? true : false
);
}
protected function _getPortableTableColumnDefinition($tableColumn)
{
$dbType = strtolower($tableColumn['data_type']);
$type = array();
$length = $unsigned = $fixed = null;
if ( ! empty($tableColumn['data_length'])) {
$length = $tableColumn['data_length'];
}
if ( ! isset($tableColumn['column_name'])) {
$tableColumn['column_name'] = '';
}
if (stripos($tableColumn['data_default'], 'NULL') !== null) {
$tableColumn['data_default'] = null;
}
switch ($dbType) {
case 'integer':
case 'pls_integer':
case 'binary_integer':
if ($length == '1' && preg_match('/^(is|has)/', $tableColumn['column_name'])) {
$type = 'boolean';
} else {
$type = 'integer';
}
break;
case 'varchar':
case 'varchar2':
case 'nvarchar2':
$fixed = false;
case 'char':
case 'nchar':
if ($length == '1' && preg_match('/^(is|has)/', $tableColumn['column_name'])) {
$type = 'boolean';
} else {
$type = 'string';
}
if ($fixed !== false) {
$fixed = true;
}
break;
case 'date':
case 'timestamp':
$type = 'timestamp';
$length = null;
break;
case 'float':
$type = 'float';
break;
case 'number':
if ( ! empty($tableColumn['data_scale'])) {
$type = 'decimal';
} else {
if ($length == '1' && preg_match('/^(is|has)/', $tableColumn['column_name'])) {
$type = 'boolean';
} else {
$type = 'integer';
}
}
break;
case 'long':
$type = 'string';
case 'clob':
case 'nclob':
$type = 'clob';
break;
case 'blob':
case 'raw':
case 'long raw':
case 'bfile':
$type = 'blob';
$length = null;
break;
case 'rowid':
case 'urowid':
default:
$type = 'string';
$length = null;
}
$decl = array(
'type' => $type,
'length' => $length,
'unsigned' => $unsigned,
'fixed' => $fixed
);
return array(
'name' => $tableColumn['column_name'],
'notnull' => (bool) ($tableColumn['nullable'] === 'N'),
'type' => $decl['type'],
'fixed' => (bool) $decl['fixed'],
'unsigned' => (bool) $decl['unsigned'],
'default' => $tableColumn['data_default'],
'length' => $tableColumn['data_length'],
'precision' => $tableColumn['data_precision'],
'scale' => $tableColumn['data_scale'],
);
}
protected function _getPortableTableConstraintDefinition($tableConstraint)
{
return $tableConstraint['constraint_name'];
}
protected function _getPortableFunctionDefinition($function)
{
return $function['name'];
}
protected function _getPortableDatabaseDefinition($database)
{
return $database['username'];
}
public function createDatabase($database = null)
{
if (is_null($database)) {
$database = $this->_conn->getDatabase();
}
$params = $this->_conn->getParams();
$username = $database;
$password = $params['password'];
$query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password;
$result = $this->_conn->exec($query);
try {
$query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO ' . $username;
$result = $this->conn->exec($query);
$result = $this->_conn->exec($query);
} catch (Exception $e) {
$query = 'DROP USER '.$username.' CASCADE';
$result2 = $this->conn->exec($query);
$this->dropDatabase($database);
}
return true;
}
/**
* drop an existing database
*
* @param object $this->conn database object that is extended by this class
* @param string $name name of the database that should be dropped
* @return mixed MDB2_OK on success, a MDB2 error on failure
* @access public
*/
public function dropDatabase($name)
{
if ( ! $this->conn->getAttribute(Doctrine::ATTR_EMULATE_DATABASE))
throw \Doctrine\Common\DoctrineException::updateMe('database dropping is only supported if the
"emulate_database" option is enabled');
$username = sprintf($this->conn->getAttribute(Doctrine::ATTR_DB_NAME_FORMAT), $name);
return $this->conn->exec('DROP USER ' . $username . ' CASCADE');
}
/**
* add an autoincrement sequence + trigger
*
* @param string $name name of the PK field
* @param string $table name of the table
* @param string $start start value for the sequence
* @return mixed MDB2_OK on success, a MDB2 error on failure
* @access private
*/
public function _makeAutoincrement($name, $table, $start = 1)
{
$sql = array();
$table = strtoupper($table);
$indexName = $table . '_AI_PK';
$definition = array(
'primary' => true,
'fields' => array($name => true),
);
$sql[] = $this->createConstraintSql($table, $indexName, $definition);
if (is_null($start)) {
$query = 'SELECT MAX(' . $this->conn->quoteIdentifier($name, true) . ') FROM ' . $this->conn->quoteIdentifier($table, true);
$start = $this->conn->fetchOne($query);
++$start;
}
$sql[] = $this->createSequenceSql($table, $start);
$sequenceName = $this->conn->formatter->getSequenceName($table);
$triggerName = $this->conn->quoteIdentifier($table . '_AI_PK', true);
$table = $this->conn->quoteIdentifier($table, true);
$name = $this->conn->quoteIdentifier($name, true);
$sql[] = 'CREATE TRIGGER ' . $triggerName . '
BEFORE INSERT
ON '.$table.'
FOR EACH ROW
DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
SELECT '.$sequenceName.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL;
IF (:NEW.'.$name.' IS NULL OR :NEW.'.$name.' = 0) THEN
SELECT '.$sequenceName.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE UPPER(Sequence_Name) = UPPER(\''.$sequenceName.'\');
SELECT :NEW.id INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
END IF;
END;
';
return $sql;
}
/**
* drop an existing autoincrement sequence + trigger
*
* @param string $table name of the table
* @return void
*/
public function dropAutoincrement($table)
{
$table = strtoupper($table);
$triggerName = $table . '_AI_PK';
$trigger_name_quoted = $this->conn->quote($triggerName);
$query = 'SELECT trigger_name FROM user_triggers';
$query.= ' WHERE trigger_name='.$trigger_name_quoted.' OR trigger_name='.strtoupper($trigger_name_quoted);
$trigger = $this->conn->fetchOne($query);
if ($trigger) {
$trigger_name = $this->conn->quoteIdentifier($table . '_AI_PK', true);
$trigger_sql = 'DROP TRIGGER ' . $trigger_name;
// if throws exception, trigger for autoincrement PK could not be dropped
$this->conn->exec($trigger_sql);
// if throws exception, sequence for autoincrement PK could not be dropped
$this->dropSequence($table);
$indexName = $table . '_AI_PK';
// if throws exception, primary key for autoincrement PK could not be dropped
$this->dropConstraint($table, $indexName);
$sql = $this->_platform->getDropAutoincrementSql($table);
foreach ($sql as $query) {
try {
$this->_conn->exec($query);
} catch (\Exception $e) {}
}
}
/**
* A method to return the required SQL string that fits between CREATE ... TABLE
* to create the table as a temporary table.
*
* @return string The string required to be placed between "CREATE" and "TABLE"
* to generate a temporary table, if possible.
*/
public function getTemporaryTableQuery()
{
return 'GLOBAL TEMPORARY';
return true;
}
/**
@ -213,255 +239,13 @@ END;
return $query;
}
/**
* create a new table
*
* @param string $name Name of the database that should be created
* @param array $fields Associative array that contains the definition of each field of the new table
* The indexes of the array entries are the names of the fields of the table an
* the array entry values are associative arrays like those that are meant to be
* passed with the field definitions to get[Type]Declaration() functions.
*
* Example
* array(
*
* 'id' => array(
* 'type' => 'integer',
* 'unsigned' => 1
* 'notnull' => 1
* 'default' => 0
* ),
* 'name' => array(
* 'type' => 'text',
* 'length' => 12
* ),
* 'password' => array(
* 'type' => 'text',
* 'length' => 12
* )
* );
* @param array $options An associative array of table options:
*
* @return void
*/
public function createTable($name, array $fields, array $options = array())
{
$this->conn->beginTransaction();
foreach ($this->createTableSql($name, $fields, $options) as $sql) {
$this->conn->exec($sql);
}
$this->conn->commit();
}
/**
* create a new table
*
* @param string $name Name of the database that should be created
* @param array $fields Associative array that contains the definition of each field of the new table
* The indexes of the array entries are the names of the fields of the table an
* the array entry values are associative arrays like those that are meant to be
* passed with the field definitions to get[Type]Declaration() functions.
*
* Example
* array(
*
* 'id' => array(
* 'type' => 'integer',
* 'unsigned' => 1
* 'notnull' => 1
* 'default' => 0
* ),
* 'name' => array(
* 'type' => 'text',
* 'length' => 12
* ),
* 'password' => array(
* 'type' => 'text',
* 'length' => 12
* )
* );
* @param array $options An associative array of table options:
*
* @return void
*/
public function createTableSql($name, array $fields, array $options = array())
{
$sql = parent::createTableSql($name, $fields, $options);
foreach ($fields as $fieldName => $field) {
if (isset($field['autoincrement']) && $field['autoincrement'] ||
(isset($field['autoinc']) && $fields['autoinc'])) {
$sql = array_merge($sql, $this->_makeAutoincrement($fieldName, $name));
}
}
return $sql;
}
/**
* drop an existing table
*
* @param string $name name of the table that should be dropped
* @return void
*/
public function dropTable($name)
{
//$this->conn->beginNestedTransaction();
$result = $this->dropAutoincrement($name);
$result = parent::dropTable($name);
//$this->conn->completeNestedTransaction();
return $result;
}
try {
$this->dropAutoincrement($name);
} catch (\Exception $e) {}
/**
* alter an existing table
*
* @param string $name name of the table that is intended to be changed.
* @param array $changes associative array that contains the details of each type
* of change that is intended to be performed. The types of
* changes that are currently supported are defined as follows:
*
* name
*
* New name for the table.
*
* add
*
* Associative array with the names of fields to be added as
* indexes of the array. The value of each entry of the array
* should be set to another associative array with the properties
* of the fields to be added. The properties of the fields should
* be the same as defined by the MDB2 parser.
*
*
* remove
*
* Associative array with the names of fields to be removed as indexes
* of the array. Currently the values assigned to each entry are ignored.
* An empty array should be used for future compatibility.
*
* rename
*
* Associative array with the names of fields to be renamed as indexes
* of the array. The value of each entry of the array should be set to
* another associative array with the entry named name with the new
* field name and the entry named Declaration that is expected to contain
* the portion of the field declaration already in DBMS specific SQL code
* as it is used in the CREATE TABLE statement.
*
* change
*
* Associative array with the names of the fields to be changed as indexes
* of the array. Keep in mind that if it is intended to change either the
* name of a field and any other properties, the change array entries
* should have the new names of the fields as array indexes.
*
* The value of each entry of the array should be set to another associative
* array with the properties of the fields to that are meant to be changed as
* array entries. These entries should be assigned to the new values of the
* respective properties. The properties of the fields should be the same
* as defined by the MDB2 parser.
*
* Example
* array(
* 'name' => 'userlist',
* 'add' => array(
* 'quota' => array(
* 'type' => 'integer',
* 'unsigned' => 1
* )
* ),
* 'remove' => array(
* 'file_limit' => array(),
* 'time_limit' => array()
* ),
* 'change' => array(
* 'name' => array(
* 'length' => '20',
* 'definition' => array(
* 'type' => 'text',
* 'length' => 20,
* ),
* )
* ),
* 'rename' => array(
* 'sex' => array(
* 'name' => 'gender',
* 'definition' => array(
* 'type' => 'text',
* 'length' => 1,
* 'default' => 'M',
* ),
* )
* )
* )
*
* @param boolean $check indicates whether the function should just check if the DBMS driver
* can perform the requested table alterations if the value is true or
* actually perform them otherwise.
* @return void
*/
public function alterTable($name, array $changes, $check = false)
{
foreach ($changes as $changeName => $change) {
switch ($changeName) {
case 'add':
case 'remove':
case 'change':
case 'name':
case 'rename':
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('change type "' . $changeName . '" not yet supported');
}
}
if ($check) {
return false;
}
$name = $this->conn->quoteIdentifier($name, true);
if ( ! empty($changes['add']) && is_array($changes['add'])) {
$fields = array();
foreach ($changes['add'] as $fieldName => $field) {
$fields[] = $this->conn->getDeclaration($fieldName, $field);
}
$result = $this->conn->exec('ALTER TABLE ' . $name . ' ADD (' . implode(', ', $fields) . ')');
}
if ( ! empty($changes['change']) && is_array($changes['change'])) {
$fields = array();
foreach ($changes['change'] as $fieldName => $field) {
$fields[] = $fieldName. ' ' . $this->conn->getDeclaration('', $field['definition']);
}
$result = $this->conn->exec('ALTER TABLE ' . $name . ' MODIFY (' . implode(', ', $fields) . ')');
}
if ( ! empty($changes['rename']) && is_array($changes['rename'])) {
foreach ($changes['rename'] as $fieldName => $field) {
$query = 'ALTER TABLE ' . $name . ' RENAME COLUMN ' . $this->conn->quoteIdentifier($fieldName, true)
. ' TO ' . $this->conn->quoteIdentifier($field['name']);
$result = $this->conn->exec($query);
}
}
if ( ! empty($changes['remove']) && is_array($changes['remove'])) {
$fields = array();
foreach ($changes['remove'] as $fieldName => $field) {
$fields[] = $this->conn->quoteIdentifier($fieldName, true);
}
$result = $this->conn->exec('ALTER TABLE ' . $name . ' DROP COLUMN ' . implode(', ', $fields));
}
if ( ! empty($changes['name'])) {
$changeName = $this->conn->quoteIdentifier($changes['name'], true);
$result = $this->conn->exec('ALTER TABLE ' . $name . ' RENAME TO ' . $changeName);
}
return parent::dropTable($name);
}
/**
@ -497,55 +281,6 @@ END;
$sequenceName = $this->_conn->quoteIdentifier($this->_conn->formatter->getSequenceName($seqName), true);
return 'DROP SEQUENCE ' . $sequenceName;
}
/**
* lists all databases
*
* @return array
*/
public function listDatabases()
{
if ( ! $this->_conn->getAttribute(Doctrine::ATTR_EMULATE_DATABASE)) {
throw \Doctrine\Common\DoctrineException::updateMe('database listing is only supported if the "emulate_database" option is enabled');
}
/**
if ($this->_conn->options['database_name_prefix']) {
$query = 'SELECT SUBSTR(username, ';
$query.= (strlen($this->_conn->getAttribute(['database_name_prefix'])+1);
$query.= ") FROM sys.dba_users WHERE username LIKE '";
$query.= $this->_conn->options['database_name_prefix']."%'";
} else {
*/
$query = 'SELECT username FROM sys.dba_users';
$result2 = $this->_conn->standaloneQuery($query);
$result = $result2->fetchColumn();
return $result;
}
/**
* lists all availible database functions
*
* @return array
*/
public function listFunctions()
{
$query = "SELECT name FROM sys.user_source WHERE line = 1 AND type = 'FUNCTION'";
return $this->_conn->fetchColumn($query);
}
/**
* lists all database triggers
*
* @param string|null $database
* @return array
*/
public function listTriggers($database = null)
{
}
/**
* lists all database sequences
@ -559,149 +294,6 @@ END;
$tableNames = $this->_conn->fetchColumn($query);
return array_map(array($this->_conn->formatter, 'fixSequenceName'), $tableNames);
}
/**
* lists table constraints
*
* @param string $table database table name
* @return array
*/
public function listTableConstraints($table)
{
$table = $this->_conn->quote($table, 'text');
$query = 'SELECT index_name name FROM user_constraints'
. ' WHERE table_name = ' . $table . ' OR table_name = ' . strtoupper($table);
$constraints = $this->_conn->fetchColumn($query);
return array_map(array($this->_conn->formatter, 'fixIndexName'), $constraints);
}
/**
* lists table constraints
*
* @param string $table database table name
* @return array
*/
public function listTableColumns($table)
{
$table = strtoupper($table);
$sql = "SELECT column_name, data_type, data_length, nullable, data_default, data_scale, data_precision FROM all_tab_columns"
. " WHERE table_name = '" . $table . "' ORDER BY column_name";
$result = $this->_conn->fetchAssoc($sql);
$descr = array();
foreach($result as $val) {
$val = array_change_key_case($val, CASE_LOWER);
$decl = $this->_conn->dataDict->getPortableDeclaration($val);
$descr[$val['column_name']] = array(
'name' => $val['column_name'],
'notnull' => (bool) ($val['nullable'] === 'N'),
'ntype' => $val['data_type'],
'type' => $decl['type'][0],
'alltypes' => $decl['type'],
'fixed' => $decl['fixed'],
'unsigned' => $decl['unsigned'],
'default' => $val['data_default'],
'length' => $val['data_length'],
'precision' => $val['data_precision'],
'scale' => $val['scale'],
);
}
return $descr;
}
/**
* lists table constraints
*
* @param string $table database table name
* @return array
*/
public function listTableIndexes($table)
{
$table = $this->_conn->quote($table, 'text');
$query = 'SELECT index_name name FROM user_indexes'
. ' WHERE table_name = ' . $table . ' OR table_name = ' . strtoupper($table)
. ' AND generated = ' . $this->_conn->quote('N', 'text');
$indexes = $this->_conn->fetchColumn($query);
return array_map(array($this->_conn->formatter, 'fixIndexName'), $indexes);
}
/**
* lists tables
*
* @param string|null $database
* @return array
*/
public function listTables($database = null)
{
$query = 'SELECT table_name FROM sys.user_tables';
return $this->_conn->fetchColumn($query);
}
/**
* 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()
{
/**
if ($this->_conn->options['emulate_database'] && $this->_conn->options['database_name_prefix']) {
$query = 'SELECT SUBSTR(username, ';
$query.= (strlen($this->_conn->options['database_name_prefix'])+1);
$query.= ") FROM sys.dba_users WHERE username NOT LIKE '";
$query.= $this->_conn->options['database_name_prefix']."%'";
} else {
*/
$query = 'SELECT username FROM sys.dba_users';
//}
return $this->_conn->fetchColumn($query);
}
/**
* lists database views
*
* @param string|null $database
* @return array
*/
public function listViews($database = null)
{
$query = 'SELECT view_name FROM sys.user_views';
return $this->_conn->fetchColumn($query);
return $tableNames;
}
}

View File

@ -53,8 +53,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
protected function _getPortableViewDefinition($view)
{
return array(
'name' => $view['viewname'],
'sql' => $view['definition']
'name' => $view['viewname']
);
}

View File

@ -36,15 +36,17 @@ class SqliteSchemaManager extends AbstractSchemaManager
public function dropDatabase($database = null)
{
if (is_null($database)) {
$database = $this->_conn->getDriver()->getDatabase($this->_conn);
$database = $this->_conn->getDatabase();
}
if (file_exists($database)) {
unlink($database);
}
unlink($database);
}
public function createDatabase($database = null)
{
if (is_null($database)) {
$database = $this->_conn->getDriver()->getDatabase($this->_conn);
$database = $this->_conn->getDatabase();
}
// TODO: Can we do this better?
$this->_conn->close();

View File

@ -2,137 +2,46 @@
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\Tests\TestUtil;
use Doctrine\DBAL\Schema;
use Doctrine\DBAL\Types\Type;
require_once __DIR__ . '/../../../TestInit.php';
class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
class MySqlSchemaManagerTest extends SchemaManagerFunctionalTest
{
private $_conn;
protected function setUp()
{
$this->_conn = TestUtil::getConnection();
if ($this->_conn->getDatabasePlatform()->getName() !== 'mysql')
{
$this->markTestSkipped('The MySqlSchemaTest requires the use of mysql');
}
$this->_sm = $this->_conn->getSchemaManager();
}
public function testListDatabases()
{
try {
$this->_sm->dropDatabase('test_mysql_create_database');
} catch (\Exception $e) {}
$this->_sm->createDatabase('test_mysql_create_database');
$this->_sm->dropAndCreateDatabase('test_create_database');
$databases = $this->_sm->listDatabases();
$this->assertEquals(true, in_array('test_mysql_create_database', $databases));
$this->assertEquals(true, in_array('test_create_database', $databases));
}
public function testListFunctions()
{
try {
$this->_sm->listFunctions();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite listFunctions() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listFunctions');
}
public function testListTriggers()
{
try {
$this->_sm->listTriggers();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite listTriggers() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listTriggers');
}
public function testListSequences()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_sequences_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_sequences_test', $columns, $options);
$this->createTestTable('list_sequences_test');
$sequences = $this->_sm->listSequences();
$this->assertEquals(true, in_array('list_sequences_test', $sequences));
}
public function testListTableConstraints()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_table_constraints_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_constraints_test', $columns, $options);
$this->createTestTable('list_table_constraints_test');
$tableConstraints = $this->_sm->listTableConstraints('list_table_constraints_test');
$this->assertEquals(array('PRIMARY'), $tableConstraints);
}
public function testListTableColumns()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_tables_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_tables_test', $columns, $options);
$this->createTestTable('list_tables_test');
$columns = $this->_sm->listTableColumns('list_tables_test');
@ -157,20 +66,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListTableIndexes()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array(
$data['options'] = array(
'indexes' => array(
'test_index_name' => array(
'fields' => array(
@ -181,11 +77,7 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
)
);
try {
$this->_sm->dropTable('list_table_indexes_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_indexes_test', $columns, $options);
$this->createTestTable('list_table_indexes_test', $data);
$tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
@ -196,29 +88,8 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListTables()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_tables_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_tables_test', $columns, $options);
$this->createTestTable('list_tables_test');
$tables = $this->_sm->listTables();
$this->assertEquals(true, in_array('list_tables_test', $tables));
}
@ -239,76 +110,35 @@ class MysqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListViews()
{
try {
$this->_sm->dropView('test_create_view');
} catch (\Exception $e) {}
$this->_sm->createView('test_create_view', 'SELECT * from mysql.user');
$this->_sm->dropAndCreateView('test_create_view', 'SELECT * from mysql.user');
$views = $this->_sm->listViews();
$this->assertEquals('test_create_view', $views[0]['name']);
$this->assertEquals('/* ALGORITHM=UNDEFINED */ select `mysql`.`user`.`Host` AS `Host`,`mysql`.`user`.`User` AS `User`,`mysql`.`user`.`Password` AS `Password`,`mysql`.`user`.`Select_priv` AS `Select_priv`,`mysql`.`user`.`Insert_priv` AS `Insert_priv`,`mysql`.`user`.`Update_priv` AS `Update_priv`,`mysql`.`user`.`Delete_priv` AS `Delete_priv`,`mysql`.`user`.`Create_priv` AS `Create_priv`,`mysql`.`user`.`Drop_priv` AS `Drop_priv`,`mysql`.`user`.`Reload_priv` AS `Reload_priv`,`mysql`.`user`.`Shutdown_priv` AS `Shutdown_priv`,`mysql`.`user`.`Process_priv` AS `Process_priv`,`mysql`.`user`.`File_priv` AS `File_priv`,`mysql`.`user`.`Grant_priv` AS `Grant_priv`,`mysql`.`user`.`References_priv` AS `References_priv`,`mysql`.`user`.`Index_priv` AS `Index_priv`,`mysql`.`user`.`Alter_priv` AS `Alter_priv`,`mysql`.`user`.`Show_db_priv` AS `Show_db_priv`,`mysql`.`user`.`Super_priv` AS `Super_priv`,`mysql`.`user`.`Create_tmp_table_priv` AS `Create_tmp_table_priv`,`mysql`.`user`.`Lock_tables_priv` AS `Lock_tables_priv`,`mysql`.`user`.`Execute_priv` AS `Execute_priv`,`mysql`.`user`.`Repl_slave_priv` AS `Repl_slave_priv`,`mysql`.`user`.`Repl_client_priv` AS `Repl_client_priv`,`mysql`.`user`.`Create_view_priv` AS `Create_view_priv`,`mysql`.`user`.`Show_view_priv` AS `Show_view_priv`,`mysql`.`user`.`Create_routine_priv` AS `Create_routine_priv`,`mysql`.`user`.`Alter_routine_priv` AS `Alter_routine_priv`,`mysql`.`user`.`Create_user_priv` AS `Create_user_priv`,`mysql`.`user`.`ssl_type` AS `ssl_type`,`mysql`.`user`.`ssl_cipher` AS `ssl_cipher`,`mysql`.`user`.`x509_issuer` AS `x509_issuer`,`mysql`.`user`.`x509_subject` AS `x509_subject`,`mysql`.`user`.`max_questions` AS `max_questions`,`mysql`.`user`.`max_updates` AS `max_updates`,`mysql`.`user`.`max_connections` AS `max_connections`,`mysql`.`user`.`max_user_connections` AS `max_user_connections` from `mysql`.`user`', $views[0]['sql']);
$this->assertEquals('test_create_view', $views[0]);
}
public function testListTableForeignKeys()
{
// Create table that has foreign key
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('integer'),
'length' => 4
)
);
$data['options'] = array('type' => 'innodb');
$this->createTestTable('list_table_foreign_keys_test1', $data);
$this->createTestTable('list_table_foreign_keys_test2', $data);
$options = array('type' => 'innodb');
try {
$this->_sm->dropTable('list_table_foreign_keys_test2');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_foreign_keys_test2', $columns, $options);
// Create the table that is being referenced in the foreign key
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'whatever' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array('type' => 'innodb');
try {
$this->_sm->dropTable('list_table_foreign_keys_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_foreign_keys_test', $columns, $options);
// Create the foreign key between the tables
$definition = array(
'name' => 'testing',
'local' => 'test',
'local' => 'foreign_key_test',
'foreign' => 'id',
'foreignTable' => 'list_table_foreign_keys_test'
'foreignTable' => 'list_table_foreign_keys_test2'
);
$this->_sm->createForeignKey('list_table_foreign_keys_test2', $definition);
$this->_sm->createForeignKey('list_table_foreign_keys_test1', $definition);
$tableForeignKeys = $this->_sm->listTableForeignKeys('list_table_foreign_keys_test2');
$tableForeignKeys = $this->_sm->listTableForeignKeys('list_table_foreign_keys_test1');
$this->assertEquals(1, count($tableForeignKeys));
$this->assertEquals('list_table_foreign_keys_test', $tableForeignKeys[0]['table']);
$this->assertEquals('test', $tableForeignKeys[0]['local']);
$this->assertEquals('list_table_foreign_keys_test2', $tableForeignKeys[0]['table']);
$this->assertEquals('foreign_key_test', $tableForeignKeys[0]['local']);
$this->assertEquals('id', $tableForeignKeys[0]['foreign']);
}
public function testDropAndCreate()
{
$this->_sm->dropAndCreateView('testing_a_new_view', 'SELECT * from mysql.user');
$this->_sm->dropAndCreateView('testing_a_new_view', 'SELECT * from mysql.user');
}
}

View File

@ -0,0 +1,139 @@
<?php
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\DBAL\Schema;
require_once __DIR__ . '/../../../TestInit.php';
class OracleSchemaManagerTest extends SchemaManagerFunctionalTest
{
public function testListDatabases()
{
$this->_sm->dropAndCreateDatabase('test_oracle_create_database');
$databases = $this->_sm->listDatabases();
$this->assertEquals(true, in_array('TEST_ORACLE_CREATE_DATABASE', $databases));
}
public function testListFunctions()
{
$functions = $this->_sm->listFunctions();
$this->assertEquals(array(), $functions);
}
public function testListTriggers()
{
return $this->assertUnsupportedMethod('listTriggers');
}
public function testListSequences()
{
$this->createTestTable('list_sequences_test');
$sequences = $this->_sm->listSequences();
$this->assertEquals(true, in_array('LIST_SEQUENCES_TEST_SEQ', $sequences));
}
public function testListTableConstraints()
{
$this->createTestTable('test_constraints');
$tableConstraints = $this->_sm->listTableConstraints('test_constraints');
$this->assertEquals(2, count($tableConstraints));
}
public function testListTableColumns()
{
$this->createTestTable('list_tables_test');
$columns = $this->_sm->listTableColumns('list_tables_test');
$this->assertEquals('ID', $columns[1]['name']);
$this->assertEquals('Doctrine\DBAL\Types\IntegerType', get_class($columns[1]['type']));
$this->assertEquals(22, $columns[1]['length']);
$this->assertEquals(false, $columns[1]['unsigned']);
$this->assertEquals(false, $columns[1]['fixed']);
$this->assertEquals(true, $columns[1]['notnull']);
$this->assertEquals(null, $columns[1]['default']);
$this->assertEquals('TEST', $columns[2]['name']);
$this->assertEquals('Doctrine\DBAL\Types\StringType', get_class($columns[2]['type']));
$this->assertEquals(255, $columns[2]['length']);
$this->assertEquals(false, $columns[2]['unsigned']);
$this->assertEquals(false, $columns[2]['fixed']);
$this->assertEquals(false, $columns[2]['notnull']);
$this->assertEquals(null, $columns[2]['default']);
}
public function testListTableIndexes()
{
$data['options'] = array(
'indexes' => array(
'test_index_name' => array(
'fields' => array(
'test' => array()
),
'type' => 'unique'
)
)
);
$this->createTestTable('list_table_indexes_test', $data);
$tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
$this->assertEquals(true, is_string($tableIndexes[0]['name']));
$this->assertEquals(true, $tableIndexes[0]['unique']);
}
public function testListTables()
{
$this->createTestTable('list_tables_test');
$tables = $this->_sm->listTables();
$this->assertEquals(true, in_array('LIST_TABLES_TEST', $tables));
}
public function testListUsers()
{
$users = $this->_sm->listUsers();
$this->assertEquals(true, is_array($users));
$params = $this->_conn->getParams();
$testUser = strtoupper($params['user']);
$found = false;
foreach ($users as $user) {
if ($user['user'] == $testUser) {
$found = true;
}
}
$this->assertEquals(true, $found);
}
public function testListViews()
{
$this->_sm->dropAndCreateView('test_create_view', 'SELECT * FROM sys.user_tables');
$views = $this->_sm->listViews();
$view = end($views);
$this->assertEquals('TEST_CREATE_VIEW', $view['name']);
}
public function testListTableForeignKeys()
{
return $this->assertUnsupportedMethod('listTableForeignKeys');
}
public function testRenameTable()
{
$this->_sm->tryDropTable('list_tables_test');
$this->_sm->tryDropTable('list_tables_test_new_name');
$this->createTestTable('list_tables_test');
$this->_sm->renameTable('list_tables_test', 'list_tables_test_new_name');
$tables = $this->_sm->listTables();
$this->assertEquals(true, in_array('LIST_TABLES_TEST_NEW_NAME', $tables));
}
public function testDropAndCreate()
{
$this->_sm->dropAndCreateView('testing_a_new_view', 'SELECT * FROM sys.user_tables');
$this->_sm->dropAndCreateView('testing_a_new_view', 'SELECT * FROM sys.user_tables');
}
}

View File

@ -2,48 +2,22 @@
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\Tests\TestUtil;
use Doctrine\DBAL\Schema;
use Doctrine\DBAL\Types\Type;
require_once __DIR__ . '/../../../TestInit.php';
class PostgreSqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTest
{
private $_conn;
protected function setUp()
{
$this->_conn = TestUtil::getConnection();
if ($this->_conn->getDatabasePlatform()->getName() !== 'postgresql')
{
$this->markTestSkipped('The PostgreSQLSchemaTest requires the use of postgresql');
}
$this->_sm = $this->_conn->getSchemaManager();
}
public function testListDatabases()
{
try {
$this->_sm->dropDatabase('test_pgsql_create_database');
} catch (\Exception $e) {}
$this->_sm->createDatabase('test_pgsql_create_database');
$this->_sm->dropAndCreateDatabase('test_create_database');
$databases = $this->_sm->listDatabases();
$this->assertEquals(in_array('test_pgsql_create_database', $databases), true);
$this->assertEquals(true, in_array('test_create_database', $databases));
}
public function testListFunctions()
{
try {
$this->_sm->listFunctions();
} catch (\Exception $e) {
return;
}
$this->fail('PostgreSql listFunctions() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listFunctions');
}
public function testListTriggers()
@ -55,83 +29,21 @@ class PostgreSqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListSequences()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_sequences_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_sequences_test', $columns, $options);
$this->createTestTable('list_sequences_test');
$sequences = $this->_sm->listSequences();
$this->assertEquals(true, in_array('list_sequences_test_id_seq', $sequences));
}
public function testListTableConstraints()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_table_constraints_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_constraints_test', $columns, $options);
$this->createTestTable('list_table_constraints_test');
$tableConstraints = $this->_sm->listTableConstraints('list_table_constraints_test');
$this->assertEquals(array('list_table_constraints_test_pkey'), $tableConstraints);
}
public function testListTableColumns()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_tables_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_tables_test', $columns, $options);
$this->createTestTable('list_tables_test');
$columns = $this->_sm->listTableColumns('list_tables_test');
$this->assertEquals('id', $columns[0]['name']);
@ -155,20 +67,7 @@ class PostgreSqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListTableIndexes()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array(
$data['options'] = array(
'indexes' => array(
'test' => array(
'fields' => array(
@ -179,41 +78,15 @@ class PostgreSqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
)
);
try {
$this->_sm->dropTable('list_table_indexes_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_indexes_test', $columns, $options);
$this->createTestTable('list_table_indexes_test', $data);
$tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
$this->assertEquals('test', $tableIndexes[0]['name']);
$this->assertEquals(true, $tableIndexes[0]['unique']);
}
public function testListTables()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
try {
$this->_sm->dropTable('list_tables_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_tables_test', $columns, $options);
$this->createTestTable('list_tables_test');
$tables = $this->_sm->listTables();
$this->assertEquals(true, in_array('list_tables_test', $tables));
}
@ -235,11 +108,7 @@ class PostgreSqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListViews()
{
try {
$this->_sm->dropView('test_create_view');
} catch (\Exception $e) {}
$this->_sm->createView('test_create_view', 'SELECT usename, passwd FROM pg_user');
$this->_sm->dropAndCreateView('test_create_view', 'SELECT usename, passwd FROM pg_user');
$views = $this->_sm->listViews();
$found = false;
@ -251,68 +120,26 @@ class PostgreSqlSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
}
$this->assertEquals(true, $found);
$this->assertEquals('SELECT pg_user.usename, pg_user.passwd FROM pg_user;', $view['sql']);
}
public function testListTableForeignKeys()
{
// Create table that has foreign key
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('integer'),
'length' => 4
)
);
$data['options'] = array('type' => 'innodb');
$this->createTestTable('list_table_foreign_keys_test1', $data);
$this->createTestTable('list_table_foreign_keys_test2', $data);
$options = array('type' => 'innodb');
try {
$this->_sm->dropTable('list_table_foreign_keys_test2');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_foreign_keys_test2', $columns, $options);
// Create the table that is being referenced in the foreign key
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'whatever' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array('type' => 'innodb');
try {
$this->_sm->dropTable('list_table_foreign_keys_test');
} catch (\Exception $e) {}
$this->_sm->createTable('list_table_foreign_keys_test', $columns, $options);
// Create the foreign key between the tables
$definition = array(
'name' => 'testing',
'local' => 'test',
'local' => 'foreign_key_test',
'foreign' => 'id',
'foreignTable' => 'list_table_foreign_keys_test'
'foreignTable' => 'list_table_foreign_keys_test2'
);
$this->_sm->createForeignKey('list_table_foreign_keys_test2', $definition);
$this->_sm->createForeignKey('list_table_foreign_keys_test1', $definition);
$tableForeignKeys = $this->_sm->listTableForeignKeys('list_table_foreign_keys_test2');
$tableForeignKeys = $this->_sm->listTableForeignKeys('list_table_foreign_keys_test1');
$this->assertEquals(1, count($tableForeignKeys));
$this->assertEquals('list_table_foreign_keys_test', $tableForeignKeys[0]['table']);
$this->assertEquals('test', $tableForeignKeys[0]['local']);
$this->assertEquals('list_table_foreign_keys_test2', $tableForeignKeys[0]['table']);
$this->assertEquals('foreign_key_test', $tableForeignKeys[0]['local']);
$this->assertEquals('id', $tableForeignKeys[0]['foreign']);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\DBAL\Types\Type;
class SchemaManagerFunctionalTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$class = get_class($this);
$e = explode('\\', $class);
$testClass = end($e);
$dbms = strtolower(str_replace('SchemaManagerTest', null, $testClass));
if ($this->_conn->getDatabasePlatform()->getName() !== $dbms)
{
$this->markTestSkipped('The ' . $testClass .' requires the use of ' . $dbms);
}
$this->_sm = $this->_conn->getSchemaManager();
}
public function createTestTable($name = 'test_table', $data = array())
{
if ( ! isset($data['columns'])) {
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
),
'foreign_key_test' => array(
'type' => Type::getType('integer')
)
);
} else {
$columns = $data['columns'];
}
$options = array();
if (isset($data['options'])) {
$options = $data['options'];
}
$this->_sm->dropAndCreateTable($name, $columns, $options);
}
public function assertUnsupportedMethod($method)
{
try {
$this->_sm->$method();
} catch (\Exception $e) {
return;
}
$this->fail($method . '() should throw an exception because it is not supported in ' . $this->_conn->getDatabasePlatform()->getName());
}
}

View File

@ -2,78 +2,30 @@
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\Tests\TestUtil;
use Doctrine\DBAL\Schema;
use Doctrine\DBAL\Types\Type;
require_once __DIR__ . '/../../../TestInit.php';
class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
class SqliteSchemaManagerTest extends SchemaManagerFunctionalTest
{
private $_conn;
protected function setUp()
{
$this->_conn = TestUtil::getConnection();
if ($this->_conn->getDatabasePlatform()->getName() !== 'sqlite')
{
$this->markTestSkipped('The SqliteSchemaTest requires the use of sqlite');
}
$this->_sm = $this->_conn->getSchemaManager();
}
public function testListDatabases()
{
try {
$this->_sm->listDatabases();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite listDatabases() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listDatabases');
}
public function testListFunctions()
{
try {
$this->_sm->listFunctions();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite listFunctions() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listFunctions');
}
public function testListTriggers()
{
try {
$this->_sm->listTriggers();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite listTriggers() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listTriggers');
}
public function testListSequences()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
$this->_sm->createTable('list_sequences_test', $columns, $options);
$this->createTestTable('list_sequences_test');
$sequences = $this->_sm->listSequences();
$this->assertEquals('list_sequences_test', $sequences[0]['name']);
$this->assertEquals('sqlite_sequence', $sequences[1]['name']);
@ -90,22 +42,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListTableColumns()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
$this->_sm->createTable('list_table_columns_test', $columns, $options);
$this->createTestTable('list_table_columns_test');
$tableColumns = $this->_sm->listTableColumns('list_table_columns_test');
@ -130,20 +67,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListTableIndexes()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array(
$data['options'] = array(
'indexes' => array(
'test' => array(
'fields' => array(
@ -154,7 +78,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
)
);
$this->_sm->createTable('list_table_indexes_test', $columns, $options);
$this->createTestTable('list_table_indexes_test', $data);
$tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
$this->assertEquals('test', $tableIndexes[0]['name']);
@ -163,62 +87,20 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testListTables()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
$this->_sm->createTable('list_tables_test', $columns, $options);
$this->createTestTable('list_tables_test');
$tables = $this->_sm->listTables();
$this->assertEquals(true, in_array('list_tables_test', $tables));
}
public function testListUsers()
{
try {
$this->_sm->listUsers();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite listUsers() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('listUsers');
}
public function testListViews()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
$this->_sm->createTable('test_views', $columns, $options);
try {
$this->_sm->dropView('test_create_view');
} catch (\Exception $e) {}
$this->_sm->createView('test_create_view', 'SELECT * from test_views');
$this->createTestTable('test_views');
$this->_sm->dropAndCreateView('test_create_view', 'SELECT * from test_views');
$views = $this->_sm->listViews();
$this->assertEquals('test_create_view', $views[0]['name']);
@ -249,22 +131,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testCreateTable()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$options = array();
$this->_sm->createTable('test_create_table', $columns, $options);
$this->createTestTable('test_create_table');
$tables = $this->_sm->listTables();
$this->assertEquals(true, in_array('test_create_table', $tables));
@ -291,45 +158,18 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testCreateSequence()
{
try {
$this->_sm->createSequence();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite createSequence() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('createSequence');
}
public function testCreateConstraint()
{
try {
$this->_sm->createConstraint();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite createConstraint() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('createConstraint');
}
public function testCreateIndex()
{
$columns = array(
'id' => array(
'type' => Type::getType('integer'),
'autoincrement' => true,
'primary' => true,
'notnull' => true
),
'test' => array(
'type' => Type::getType('string'),
'length' => 255
)
);
$this->createTestTable('test_create_index');
$options = array();
$this->_sm->createTable('test_create_index', $columns, $options);
$index = array(
'fields' => array(
'test' => array()
@ -337,7 +177,7 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
'type' => 'unique'
);
$this->_sm->createIndex('test_create_index', 'test', $index);
$this->_sm->dropAndCreateIndex('test_create_index', 'test', $index);
$tableIndexes = $this->_sm->listTableIndexes('test_create_index');
$this->assertEquals('test', $tableIndexes[0]['name']);
$this->assertEquals(true, $tableIndexes[0]['unique']);
@ -345,68 +185,32 @@ class SqliteSchemaManagerTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testCreateForeignKey()
{
try {
$this->_sm->createForeignKey();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite createForeignKey() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('createForeignKey');
}
public function testRenameTable()
{
try {
$this->_sm->renameTable();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite renameTable() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('renameTable');
}
public function testAddTableColumn()
{
try {
$this->_sm->addTableColumn();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite addTableColumn() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('addTableColumn');
}
public function testRemoveTableColumn()
{
try {
$this->_sm->removeTableColumn();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite removeTableColumn() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('removeTableColumn');
}
public function testChangeTableColumn()
{
try {
$this->_sm->changeTableColumn();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite changeTableColumn() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('changeTableColumn');
}
public function testRenameTableColumn()
{
try {
$this->_sm->renameTableColumn();
} catch (\Exception $e) {
return;
}
$this->fail('Sqlite renameTableColumn() should throw an exception because it is not supported');
return $this->assertUnsupportedMethod('renameTableColumn');
}
}

View File

@ -4,5 +4,12 @@ namespace Doctrine\Tests;
class DbalFunctionalTestCase extends DbalTestCase
{
protected $_conn;
protected function setUp()
{
if ( ! isset($this->_conn)) {
$this->_conn = TestUtil::getConnection();
}
}
}

View File

@ -4,4 +4,17 @@ namespace Doctrine\Tests;
class DbalFunctionalTestSuite extends DbalTestSuite
{
protected $_conn;
protected function setUp()
{
if ( ! isset($this->_conn)) {
$this->_conn = TestUtil::getConnection();
}
}
protected function tearDown()
{
$this->_conn = null;
}
}

View File

@ -3,7 +3,7 @@
namespace Doctrine\Tests;
class TestUtil
{
{
public static function getConnection()
{
if (isset($GLOBALS['db_type'], $GLOBALS['db_username'], $GLOBALS['db_password'],
@ -23,6 +23,20 @@ class TestUtil
);
}
return \Doctrine\DBAL\DriverManager::getConnection($params);
$conn = \Doctrine\DBAL\DriverManager::getConnection($params);
$sm = $conn->getSchemaManager();
try {
$sm->dropDatabase();
} catch (\Exception $e) {}
try {
$sm->createDatabase();
} catch (\Exception $e) {}
$conn->close();
$conn = \Doctrine\DBAL\DriverManager::getConnection($params);
return $conn;
}
}