Commit current state of IBM DB2 driver, but it segfaults the hell out of the Doctrine Testsuite
This commit is contained in:
parent
7d179aaf95
commit
5fd6e687ce
@ -791,7 +791,7 @@ class Connection implements DriverConnection
|
|||||||
* Gets the SchemaManager that can be used to inspect or change the
|
* Gets the SchemaManager that can be used to inspect or change the
|
||||||
* database schema through the connection.
|
* database schema through the connection.
|
||||||
*
|
*
|
||||||
* @return Doctrine\DBAL\Schema\SchemaManager
|
* @return Doctrine\DBAL\Schema\AbstractSchemaManager
|
||||||
*/
|
*/
|
||||||
public function getSchemaManager()
|
public function getSchemaManager()
|
||||||
{
|
{
|
||||||
|
@ -25,12 +25,14 @@ class Db2Connection implements \Doctrine\DBAL\Driver\Connection
|
|||||||
{
|
{
|
||||||
private $_conn = null;
|
private $_conn = null;
|
||||||
|
|
||||||
public function __construct($dbname, $username, $password, $driverOptions = array(), $isPersistant = false)
|
public function __construct(array $params, $username, $password, $driverOptions = array())
|
||||||
{
|
{
|
||||||
|
$isPersistant = (isset($params['persistent']) && $params['persistent'] == true);
|
||||||
|
|
||||||
if ($isPersistant) {
|
if ($isPersistant) {
|
||||||
$this->_conn = db2_pconnect($dbname, $username, $password, $driverOptions);
|
$this->_conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
|
||||||
} else {
|
} else {
|
||||||
$this->_conn = db2_connect($dbname, $username, $password, $driverOptions);
|
$this->_conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
|
||||||
}
|
}
|
||||||
if (!$this->_conn) {
|
if (!$this->_conn) {
|
||||||
throw new Db2Exception(db2_conn_errormsg());
|
throw new Db2Exception(db2_conn_errormsg());
|
||||||
|
@ -46,9 +46,13 @@ class Db2Driver implements Driver
|
|||||||
*/
|
*/
|
||||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
|
||||||
{
|
{
|
||||||
|
if ( !isset($params['schema']) ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if ($params['host'] !== 'localhost' && $params['host'] != '127.0.0.1') {
|
if ($params['host'] !== 'localhost' && $params['host'] != '127.0.0.1') {
|
||||||
// if the host isn't localhost, use extended connection params
|
// if the host isn't localhost, use extended connection params
|
||||||
$dbname = 'DRIVER={IBM DB2 ODBC DRIVER}' .
|
$params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' .
|
||||||
';DATABASE=' . $params['dbname'] .
|
';DATABASE=' . $params['dbname'] .
|
||||||
';HOSTNAME=' . $params['host'] .
|
';HOSTNAME=' . $params['host'] .
|
||||||
';PORT=' . $params['port'] .
|
';PORT=' . $params['port'] .
|
||||||
@ -57,13 +61,9 @@ class Db2Driver implements Driver
|
|||||||
';PWD=' . $password .';';
|
';PWD=' . $password .';';
|
||||||
$username = null;
|
$username = null;
|
||||||
$password = null;
|
$password = null;
|
||||||
} else {
|
|
||||||
$dbname = $params['dbname'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$isPersistant = (isset($params['persistent']) && $params['persistent'] == true);
|
return new Db2Connection($params, $username, $password, $driverOptions);
|
||||||
|
|
||||||
return new Db2Connection($dbname, $username, $password, $driverOptions, $isPersistant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +74,7 @@ class Db2Driver implements Driver
|
|||||||
*/
|
*/
|
||||||
public function getDatabasePlatform()
|
public function getDatabasePlatform()
|
||||||
{
|
{
|
||||||
return new \Doctrine\DBAL\Platforms\IbmDb2Platform;
|
return new \Doctrine\DBAL\Platforms\Db2Platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,7 +86,7 @@ class Db2Driver implements Driver
|
|||||||
*/
|
*/
|
||||||
public function getSchemaManager(Connection $conn)
|
public function getSchemaManager(Connection $conn)
|
||||||
{
|
{
|
||||||
return new \Doctrine\DBAL\Schema\IbmDb2SchemaManager($conn);
|
return new \Doctrine\DBAL\Schema\Db2SchemaManager($conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,8 @@ final class DriverManager
|
|||||||
'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver',
|
'pdo_pgsql' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver',
|
||||||
'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver',
|
'pdo_oci' => 'Doctrine\DBAL\Driver\PDOOracle\Driver',
|
||||||
'pdo_mssql' => 'Doctrine\DBAL\Driver\PDOMsSql\Driver',
|
'pdo_mssql' => 'Doctrine\DBAL\Driver\PDOMsSql\Driver',
|
||||||
'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver'
|
'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver',
|
||||||
|
'ibm_db2' => 'Doctrine\DBAL\Driver\IbmDb2\Db2Driver',
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Private constructor. This class cannot be instantiated. */
|
/** Private constructor. This class cannot be instantiated. */
|
||||||
|
@ -21,7 +21,11 @@
|
|||||||
|
|
||||||
namespace Doctrine\DBAL\Platforms;
|
namespace Doctrine\DBAL\Platforms;
|
||||||
|
|
||||||
class IbmDb2Platform extends AbstractPlatform
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\Schema\Index;
|
||||||
|
use Doctrine\DBAL\Schema\TableDiff;
|
||||||
|
|
||||||
|
class Db2Platform extends AbstractPlatform
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Gets the SQL snippet used to declare a VARCHAR column type.
|
* Gets the SQL snippet used to declare a VARCHAR column type.
|
||||||
@ -122,6 +126,42 @@ class IbmDb2Platform extends AbstractPlatform
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain DBMS specific SQL to be used to create datetime fields in
|
||||||
|
* statements like CREATE TABLE
|
||||||
|
*
|
||||||
|
* @param array $fieldDeclaration
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||||
|
{
|
||||||
|
return 'TIMESTAMP(0)';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain DBMS specific SQL to be used to create date fields in statements
|
||||||
|
* like CREATE TABLE.
|
||||||
|
*
|
||||||
|
* @param array $fieldDeclaration
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
|
||||||
|
{
|
||||||
|
return 'DATE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain DBMS specific SQL to be used to create time fields in statements
|
||||||
|
* like CREATE TABLE.
|
||||||
|
*
|
||||||
|
* @param array $fieldDeclaration
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
|
||||||
|
{
|
||||||
|
return 'TIME';
|
||||||
|
}
|
||||||
|
|
||||||
public function getListDatabasesSQL()
|
public function getListDatabasesSQL()
|
||||||
{
|
{
|
||||||
throw DBALException::notSupported(__METHOD__);
|
throw DBALException::notSupported(__METHOD__);
|
||||||
@ -137,6 +177,13 @@ class IbmDb2Platform extends AbstractPlatform
|
|||||||
throw DBALException::notSupported(__METHOD__);
|
throw DBALException::notSupported(__METHOD__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code fragment is originally from the Zend_Db_Adapter_Db2 class.
|
||||||
|
*
|
||||||
|
* @license New BSD License
|
||||||
|
* @param string $table
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getListTableColumnsSQL($table)
|
public function getListTableColumnsSQL($table)
|
||||||
{
|
{
|
||||||
return "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
|
return "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
|
||||||
@ -155,7 +202,7 @@ class IbmDb2Platform extends AbstractPlatform
|
|||||||
|
|
||||||
public function getListTablesSQL()
|
public function getListTablesSQL()
|
||||||
{
|
{
|
||||||
return "SELECT 'NAME' FROM SYSIBM.TABLES";
|
return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getListUsersSQL()
|
public function getListUsersSQL()
|
||||||
@ -176,13 +223,13 @@ class IbmDb2Platform extends AbstractPlatform
|
|||||||
|
|
||||||
public function getListTableIndexesSQL($table)
|
public function getListTableIndexesSQL($table)
|
||||||
{
|
{
|
||||||
throw DBALException::notSupported(__METHOD__);
|
return "SELECT NAME, COLNAMES, UNIQUERULE FROM SYSIBM.SYSINDEXES WHERE TBNAME = UPPER('" . $table . "')";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getListTableForeignKeysSQL($table)
|
public function getListTableForeignKeysSQL($table)
|
||||||
{
|
{
|
||||||
return "SELECT TBNAME, RELNAME, REFTBNAME, 'DELETE_RULE', 'UPDATE_RULE', FKCOLNAMES, PKCOLNAMES ".
|
return "SELECT TBNAME, RELNAME, REFTBNAME, DELETERULE, UPDATERULE, FKCOLNAMES, PKCOLNAMES ".
|
||||||
"FROM SYSIBM.SYSRELS WHERE TBNAME = '".$table."'";
|
"FROM SYSIBM.SYSRELS WHERE TBNAME = UPPER('".$table."')";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCreateViewSQL($name, $sql)
|
public function getCreateViewSQL($name, $sql)
|
||||||
@ -219,4 +266,135 @@ class IbmDb2Platform extends AbstractPlatform
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL specific for the platform to get the current date.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCurrentDateSQL()
|
||||||
|
{
|
||||||
|
return 'current date';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL specific for the platform to get the current time.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCurrentTimeSQL()
|
||||||
|
{
|
||||||
|
return 'current time';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL specific for the platform to get the current timestamp
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCurrentTimestampSQL()
|
||||||
|
{
|
||||||
|
return 'current timestamp';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain DBMS specific SQL code portion needed to set an index
|
||||||
|
* declaration to be used in statements like CREATE TABLE.
|
||||||
|
*
|
||||||
|
* @param string $name name of the index
|
||||||
|
* @param Index $index index definition
|
||||||
|
* @return string DBMS specific SQL code portion needed to set an index
|
||||||
|
*/
|
||||||
|
public function getIndexDeclarationSQL($name, Index $index)
|
||||||
|
{
|
||||||
|
return $this->getUniqueConstraintDeclarationSQL($name, $index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tableName
|
||||||
|
* @param array $columns
|
||||||
|
* @param array $options
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
|
||||||
|
{
|
||||||
|
$indexes = array();
|
||||||
|
if (isset($options['indexes'])) {
|
||||||
|
$indexes = $options['indexes'];
|
||||||
|
}
|
||||||
|
$options['indexes'] = array();
|
||||||
|
|
||||||
|
$sqls = parent::_getCreateTableSQL($tableName, $columns, $options);
|
||||||
|
|
||||||
|
foreach ($indexes as $index => $definition) {
|
||||||
|
$sqls[] = $this->getCreateIndexSQL($definition, $tableName);
|
||||||
|
}
|
||||||
|
return $sqls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SQL to alter an existing table.
|
||||||
|
*
|
||||||
|
* @param TableDiff $diff
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAlterTableSQL(TableDiff $diff)
|
||||||
|
{
|
||||||
|
$sql = array();
|
||||||
|
|
||||||
|
$queryParts = array();
|
||||||
|
foreach ($diff->addedColumns AS $fieldName => $column) {
|
||||||
|
$queryParts[] = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($diff->removedColumns AS $column) {
|
||||||
|
$queryParts[] = 'DROP COLUMN ' . $column->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($diff->changedColumns AS $columnDiff) {
|
||||||
|
/* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
|
||||||
|
$column = $columnDiff->column;
|
||||||
|
$queryParts[] = 'ALTER ' . ($columnDiff->oldColumnName) . ' '
|
||||||
|
. $this->getColumnDeclarationSQL($column->getName(), $column->toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($diff->renamedColumns AS $oldColumnName => $column) {
|
||||||
|
$queryParts[] = 'RENAME ' . $oldColumnName . ' TO ' . $column->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($queryParts) > 0) {
|
||||||
|
$sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(" ", $queryParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
|
||||||
|
|
||||||
|
if ($diff->newName !== false) {
|
||||||
|
$sql[] = 'RENAME TABLE TO ' . $diff->newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultValueDeclarationSQL($field)
|
||||||
|
{
|
||||||
|
if (isset($field['notnull']) && $field['notnull'] && !isset($field['default'])) {
|
||||||
|
if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) {
|
||||||
|
$field['default'] = 0;
|
||||||
|
} else {
|
||||||
|
$field['default'] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getDefaultValueDeclarationSQL($field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsIdentityColumns()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prefersIdentityColumns()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
@ -412,91 +412,8 @@ class MySqlPlatform extends AbstractPlatform
|
|||||||
/**
|
/**
|
||||||
* Gets the SQL to alter an existing table.
|
* Gets the SQL to alter an existing table.
|
||||||
*
|
*
|
||||||
* @param string $name The name of the table that is intended to be changed.
|
* @param TableDiff $diff
|
||||||
* @param array $changes Associative array that contains the details of each type
|
* @return array
|
||||||
* 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 Metabase 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 Metabase 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 boolean
|
|
||||||
* @override
|
|
||||||
*/
|
*/
|
||||||
public function getAlterTableSQL(TableDiff $diff)
|
public function getAlterTableSQL(TableDiff $diff)
|
||||||
{
|
{
|
||||||
|
195
lib/Doctrine/DBAL/Schema/Db2SchemaManager.php
Normal file
195
lib/Doctrine/DBAL/Schema/Db2SchemaManager.php
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
<?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.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\DBAL\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IBM Db2 Schema Manager
|
||||||
|
*
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link www.doctrine-project.com
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
|
*/
|
||||||
|
class Db2SchemaManager extends AbstractSchemaManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return a list of all tables in the current database
|
||||||
|
*
|
||||||
|
* Apparently creator is the schema not the user who created it:
|
||||||
|
* {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm}
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listTableNames()
|
||||||
|
{
|
||||||
|
|
||||||
|
$sql = $this->_platform->getListTablesSQL();
|
||||||
|
$sql .= " AND CREATOR = UPPER('".$this->_conn->getUsername()."')";
|
||||||
|
|
||||||
|
$tables = $this->_conn->fetchAll($sql);
|
||||||
|
|
||||||
|
return $this->_getPortableTablesList($tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Table Column Definition
|
||||||
|
*
|
||||||
|
* @param array $tableColumn
|
||||||
|
* @return Column
|
||||||
|
*/
|
||||||
|
protected function _getPortableTableColumnDefinition($tableColumn)
|
||||||
|
{
|
||||||
|
$tableColumn = array_change_key_case($tableColumn, \CASE_LOWER);
|
||||||
|
|
||||||
|
$length = null;
|
||||||
|
$fixed = null;
|
||||||
|
$unsigned = false;
|
||||||
|
$scale = false;
|
||||||
|
$precision = false;
|
||||||
|
|
||||||
|
switch (strtolower($tableColumn['typename'])) {
|
||||||
|
case 'smallint':
|
||||||
|
case 'bigint':
|
||||||
|
case 'integer':
|
||||||
|
case 'time':
|
||||||
|
case 'date':
|
||||||
|
$type = strtolower($tableColumn['typename']);
|
||||||
|
break;
|
||||||
|
case 'varchar':
|
||||||
|
$type = 'string';
|
||||||
|
$length = $tableColumn['length'];
|
||||||
|
$fixed = false;
|
||||||
|
break;
|
||||||
|
case 'character':
|
||||||
|
$type = 'string';
|
||||||
|
$length = $tableColumn['length'];
|
||||||
|
$fixed = true;
|
||||||
|
break;
|
||||||
|
case 'clob':
|
||||||
|
$type = 'text';
|
||||||
|
$length = $tableColumn['length'];
|
||||||
|
break;
|
||||||
|
case 'decimal':
|
||||||
|
case 'double':
|
||||||
|
case 'real':
|
||||||
|
$type = 'decimal';
|
||||||
|
$scale = $tableColumn['scale'];
|
||||||
|
$precision = $tableColumn['length'];
|
||||||
|
break;
|
||||||
|
case 'timestamp':
|
||||||
|
$type = 'datetime';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \Doctrine\DBAL\DBALException("Unknown Type: ".$tableColumn['typename']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = array(
|
||||||
|
'length' => $length,
|
||||||
|
'unsigned' => (bool)$unsigned,
|
||||||
|
'fixed' => (bool)$fixed,
|
||||||
|
'default' => ($tableColumn['default'] == "NULL") ? null : $tableColumn['default'],
|
||||||
|
'notnull' => (bool) ($tableColumn['nulls'] == 'N'),
|
||||||
|
'scale' => null,
|
||||||
|
'precision' => null,
|
||||||
|
'platformOptions' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($scale !== null && $precision !== null) {
|
||||||
|
$options['scale'] = $scale;
|
||||||
|
$options['precision'] = $precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Column($tableColumn['colname'], \Doctrine\DBAL\Types\Type::getType($type), $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _getPortableTablesList($tables)
|
||||||
|
{
|
||||||
|
$tableNames = array();
|
||||||
|
foreach ($tables AS $tableRow) {
|
||||||
|
$tableRow = array_change_key_case($tableRow, \CASE_LOWER);
|
||||||
|
$tableNames[] = $tableRow['name'];
|
||||||
|
}
|
||||||
|
return $tableNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
|
||||||
|
{
|
||||||
|
$tableIndexRows = array();
|
||||||
|
$indexes = array();
|
||||||
|
foreach($tableIndexes AS $indexKey => $data) {
|
||||||
|
$data = array_change_key_case($data, \CASE_LOWER);
|
||||||
|
$unique = ($data['uniquerule'] == "D") ? false : true;
|
||||||
|
$primary = ($data['uniquerule'] == "P");
|
||||||
|
|
||||||
|
$indexName = strtolower($data['name']);
|
||||||
|
if ($primary) {
|
||||||
|
$keyName = 'primary';
|
||||||
|
} else {
|
||||||
|
$keyName = $indexName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes[$keyName] = new Index($indexName, explode("+", ltrim($data['colnames'], '+')), $unique, $primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
|
||||||
|
{
|
||||||
|
$tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER);
|
||||||
|
|
||||||
|
$tableForeignKey['deleterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['deleterule']);
|
||||||
|
$tableForeignKey['updaterule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['updaterule']);
|
||||||
|
|
||||||
|
return new ForeignKeyConstraint(
|
||||||
|
array_map('trim', (array)$tableForeignKey['fkcolnames']),
|
||||||
|
$tableForeignKey['reftbname'],
|
||||||
|
array_map('trim', (array)$tableForeignKey['pkcolnames']),
|
||||||
|
$tableForeignKey['relname'],
|
||||||
|
array(
|
||||||
|
'onUpdate' => $tableForeignKey['updaterule'],
|
||||||
|
'onDelete' => $tableForeignKey['deleterule'],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _getPortableForeignKeyRuleDef($def)
|
||||||
|
{
|
||||||
|
if ($def == "C") {
|
||||||
|
return "CASCADE";
|
||||||
|
} else if ($def == "N") {
|
||||||
|
return "SET NULL";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _getPortableViewDefinition($view)
|
||||||
|
{
|
||||||
|
$view = array_change_key_case($view, \CASE_LOWER);
|
||||||
|
$pos = strpos($view['text'], ' AS ');
|
||||||
|
$sql = substr($view['text'], $pos+4);
|
||||||
|
|
||||||
|
return new View($view['name'], $sql);
|
||||||
|
}
|
||||||
|
}
|
@ -1,83 +0,0 @@
|
|||||||
<?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.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\DBAL\Schema;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IBM Db2 Schema Manager
|
|
||||||
*
|
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
||||||
* @link www.doctrine-project.com
|
|
||||||
* @since 1.0
|
|
||||||
* @version $Revision$
|
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
|
||||||
*/
|
|
||||||
class IbmDb2SchemaManager extends AbstractSchemaManager
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Get Table Column Definition
|
|
||||||
*
|
|
||||||
* @param array $tableColumn
|
|
||||||
* @return Column
|
|
||||||
*/
|
|
||||||
protected function _getPortableTableColumnDefinition($tableColumn)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
|
|
||||||
{
|
|
||||||
$tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER);
|
|
||||||
|
|
||||||
$tableForeignKey['delete_rule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['delete_rule']);
|
|
||||||
$tableForeignKey['update_rule'] = $this->_getPortableForeignKeyRuleDef($tableForeignKey['update_rule']);
|
|
||||||
|
|
||||||
return new ForeignKeyConstraint(
|
|
||||||
(array)$tableForeignKey['pkcolnames'],
|
|
||||||
$tableForeignKey['referenced_table_name'],
|
|
||||||
(array)$tableForeignKey['fkcolnames'],
|
|
||||||
$tableForeignKey['relname'],
|
|
||||||
array(
|
|
||||||
'onUpdate' => $tableForeignKey['update_rule'],
|
|
||||||
'onDelete' => $tableForeignKey['delete_rule'],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function _getPortableForeignKeyRuleDef($def)
|
|
||||||
{
|
|
||||||
if ($def == "C") {
|
|
||||||
return "CASCADE";
|
|
||||||
} else if ($def == "N") {
|
|
||||||
return "SET NULL";
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function _getPortableViewDefinition($view)
|
|
||||||
{
|
|
||||||
$view = array_change_key_case($view, \CASE_LOWER);
|
|
||||||
$pos = strpos($view['text'], ' AS ');
|
|
||||||
$sql = substr($view['text'], $pos+4);
|
|
||||||
|
|
||||||
return new View($view['name'], $sql);
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,6 +28,8 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
$this->markTestSkipped('The ' . $testClass .' requires the use of ' . $dbms);
|
$this->markTestSkipped('The ' . $testClass .' requires the use of ' . $dbms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#$this->_conn->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||||
|
|
||||||
$this->_sm = $this->_conn->getSchemaManager();
|
$this->_sm = $this->_conn->getSchemaManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +61,10 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
|
|
||||||
public function testListDatabases()
|
public function testListDatabases()
|
||||||
{
|
{
|
||||||
|
if (!$this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
|
||||||
|
$this->markTestSkipped('Cannot drop Database client side with this Driver.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->_sm->dropAndCreateDatabase('test_create_database');
|
$this->_sm->dropAndCreateDatabase('test_create_database');
|
||||||
$databases = $this->_sm->listDatabases();
|
$databases = $this->_sm->listDatabases();
|
||||||
|
|
||||||
@ -73,12 +79,12 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
$tables = $this->_sm->listTables();
|
$tables = $this->_sm->listTables();
|
||||||
|
|
||||||
$this->assertType('array', $tables);
|
$this->assertType('array', $tables);
|
||||||
$this->assertTrue(count($tables) > 0);
|
$this->assertTrue(count($tables) > 0, "List Tables has to find at least one table named 'list_tables_test'.");
|
||||||
|
|
||||||
$foundTable = false;
|
$foundTable = false;
|
||||||
foreach ($tables AS $table) {
|
foreach ($tables AS $table) {
|
||||||
$this->assertType('Doctrine\DBAL\Schema\Table', $table);
|
$this->assertType('Doctrine\DBAL\Schema\Table', $table);
|
||||||
if ($table->getName() == 'list_tables_test') {
|
if (strtolower($table->getName()) == 'list_tables_test') {
|
||||||
$foundTable = true;
|
$foundTable = true;
|
||||||
|
|
||||||
$this->assertTrue($table->hasColumn('id'));
|
$this->assertTrue($table->hasColumn('id'));
|
||||||
@ -86,6 +92,8 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
$this->assertTrue($table->hasColumn('foreign_key_test'));
|
$this->assertTrue($table->hasColumn('foreign_key_test'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertTrue( $foundTable , "The 'list_tables_test' table has to be found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testListTableColumns()
|
public function testListTableColumns()
|
||||||
@ -122,7 +130,6 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
|
|
||||||
$this->assertEquals('foo', strtolower($columns['foo']->getname()));
|
$this->assertEquals('foo', strtolower($columns['foo']->getname()));
|
||||||
$this->assertType('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
|
$this->assertType('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
|
||||||
$this->assertEquals(null, $columns['foo']->getlength());
|
|
||||||
$this->assertEquals(false, $columns['foo']->getunsigned());
|
$this->assertEquals(false, $columns['foo']->getunsigned());
|
||||||
$this->assertEquals(false, $columns['foo']->getfixed());
|
$this->assertEquals(false, $columns['foo']->getfixed());
|
||||||
$this->assertEquals(true, $columns['foo']->getnotnull());
|
$this->assertEquals(true, $columns['foo']->getnotnull());
|
||||||
@ -171,6 +178,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
|
|
||||||
$this->assertEquals(3, count($tableIndexes));
|
$this->assertEquals(3, count($tableIndexes));
|
||||||
|
|
||||||
|
$this->assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
|
||||||
$this->assertEquals(array('id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
|
$this->assertEquals(array('id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
|
||||||
$this->assertTrue($tableIndexes['primary']->isUnique());
|
$this->assertTrue($tableIndexes['primary']->isUnique());
|
||||||
$this->assertTrue($tableIndexes['primary']->isPrimary());
|
$this->assertTrue($tableIndexes['primary']->isPrimary());
|
||||||
@ -218,7 +226,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
$this->_sm->dropAndCreateTable($tableA);
|
$this->_sm->dropAndCreateTable($tableA);
|
||||||
|
|
||||||
$fkConstraints = $this->_sm->listTableForeignKeys('test_create_fk');
|
$fkConstraints = $this->_sm->listTableForeignKeys('test_create_fk');
|
||||||
$this->assertEquals(1, count($fkConstraints));
|
$this->assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
|
||||||
|
|
||||||
$fkConstraint = current($fkConstraints);
|
$fkConstraint = current($fkConstraints);
|
||||||
$this->assertType('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
|
$this->assertType('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
|
||||||
@ -237,22 +245,20 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
$this->createTestTable('test_create_fk2');
|
$this->createTestTable('test_create_fk2');
|
||||||
|
|
||||||
$foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
|
$foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
|
||||||
array('foreign_key_test'), 'test_create_fk2', array('id'), 'foreign_key_test_fk', array('onUpdate' => 'CASCADE', 'onDelete' => 'CASCADE')
|
array('foreign_key_test'), 'test_create_fk2', array('id'), 'foreign_key_test_fk', array('onDelete' => 'CASCADE')
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
|
$this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
|
||||||
|
|
||||||
$fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
|
$fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
|
||||||
|
|
||||||
$this->assertEquals(1, count($fkeys));
|
$this->assertEquals(1, count($fkeys), "Table 'test_create_fk1' has to have one foreign key.");
|
||||||
|
|
||||||
$this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
|
$this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
|
||||||
$this->assertEquals(array('foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
|
$this->assertEquals(array('foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
|
||||||
$this->assertEquals(array('id'), array_map('strtolower', $fkeys[0]->getForeignColumns()));
|
$this->assertEquals(array('id'), array_map('strtolower', $fkeys[0]->getForeignColumns()));
|
||||||
$this->assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName()));
|
$this->assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName()));
|
||||||
|
|
||||||
if($fkeys[0]->hasOption('onUpdate')) {
|
|
||||||
$this->assertEquals('CASCADE', $fkeys[0]->getOption('onUpdate'));
|
|
||||||
}
|
|
||||||
if($fkeys[0]->hasOption('onDelete')) {
|
if($fkeys[0]->hasOption('onDelete')) {
|
||||||
$this->assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
|
$this->assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
|
||||||
}
|
}
|
||||||
@ -278,6 +284,8 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
|
|||||||
$this->markTestSkipped('Alter Table is not supported by this platform.');
|
$this->markTestSkipped('Alter Table is not supported by this platform.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->_conn->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||||
|
|
||||||
$this->createTestTable('alter_table');
|
$this->createTestTable('alter_table');
|
||||||
$this->createTestTable('alter_table_foreign');
|
$this->createTestTable('alter_table_foreign');
|
||||||
|
|
||||||
|
@ -68,7 +68,13 @@ class TestUtil
|
|||||||
|
|
||||||
$tmpConn->close();
|
$tmpConn->close();
|
||||||
} else {
|
} else {
|
||||||
// wipe everything?
|
$sm = $realConn->getSchemaManager();
|
||||||
|
|
||||||
|
$tableNames = $sm->listTableNames();
|
||||||
|
|
||||||
|
foreach ($tableNames AS $tableName) {
|
||||||
|
$sm->dropTable($tableName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$eventManager = null;
|
$eventManager = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user