Skip to content

Commit

Permalink
Merge branch 'DBAL-21'
Browse files Browse the repository at this point in the history
  • Loading branch information
beberlei committed Jun 20, 2010
2 parents ea700de + 287833a commit 93ad4c2
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 52 deletions.
16 changes: 16 additions & 0 deletions lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
Expand Up @@ -125,6 +125,22 @@ public function getDoctrineTypeMapping($dbType)
}
}

/**
* Check if a database type is currently supported by this platform.
*
* @param string $dbType
* @return bool
*/
public function hasDoctrineTypeMappingFor($dbType)
{
if ($this->doctrineTypeMapping === null) {
$this->initializeDoctrineTypeMappings();
}

$dbType = strtolower($dbType);
return isset($this->doctrineTypeMapping[$dbType]);
}

/**
* Lazy load Doctrine Type Mappings
*
Expand Down
3 changes: 3 additions & 0 deletions lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
Expand Up @@ -249,6 +249,9 @@ public function getListTableColumnsSQL($table)
a.attname AS field,
t.typname AS type,
format_type(a.atttypid, a.atttypmod) AS complete_type,
(SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
(SELECT format_type(t2.typbasetype, t2.typtypmod) FROM pg_catalog.pg_type t2
WHERE t2.typtype = 'd' AND t2.typname = format_type(a.atttypid, a.atttypmod)) AS domain_complete_type,
a.attnotnull AS isnotnull,
(SELECT 't'
FROM pg_index
Expand Down
112 changes: 60 additions & 52 deletions lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php
@@ -1,4 +1,5 @@
<?php

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Expand Down Expand Up @@ -31,62 +32,63 @@
*/
class PostgreSqlSchemaManager extends AbstractSchemaManager
{

protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
{
$onUpdate = null;
$onDelete = null;

if(preg_match('(ON UPDATE ([a-zA-Z0-9]+))', $tableForeignKey['condef'], $match)) {
if (preg_match('(ON UPDATE ([a-zA-Z0-9]+))', $tableForeignKey['condef'], $match)) {
$onUpdate = $match[1];
}
if(preg_match('(ON DELETE ([a-zA-Z0-9]+))', $tableForeignKey['condef'], $match)) {
if (preg_match('(ON DELETE ([a-zA-Z0-9]+))', $tableForeignKey['condef'], $match)) {
$onDelete = $match[1];
}

if(preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values)) {
if (preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values)) {
$localColumns = explode(",", $values[1]);
$foreignColumns = explode(",", $values[3]);
$foreignTable = $values[2];
}

return new ForeignKeyConstraint(
$localColumns, $foreignTable, $foreignColumns, $tableForeignKey['conname'],
array('onUpdate' => $onUpdate, 'onDelete' => $onDelete)
$localColumns, $foreignTable, $foreignColumns, $tableForeignKey['conname'],
array('onUpdate' => $onUpdate, 'onDelete' => $onDelete)
);
}

public function dropDatabase($database)
{
$params = $this->_conn->getParams();
$params["dbname"] = "postgres";
$tmpPlatform = $this->_platform;
$tmpConn = $this->_conn;
$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
$this->_platform = $this->_conn->getDatabasePlatform();
parent::dropDatabase($database);
$this->_platform = $tmpPlatform;
$this->_conn = $tmpConn;
$params = $this->_conn->getParams();
$params["dbname"] = "postgres";
$tmpPlatform = $this->_platform;
$tmpConn = $this->_conn;

$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
$this->_platform = $this->_conn->getDatabasePlatform();

parent::dropDatabase($database);

$this->_platform = $tmpPlatform;
$this->_conn = $tmpConn;
}

public function createDatabase($database)
{
$params = $this->_conn->getParams();
$params["dbname"] = "postgres";
$tmpPlatform = $this->_platform;
$tmpConn = $this->_conn;
$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
$this->_platform = $this->_conn->getDatabasePlatform();
parent::createDatabase($database);
$this->_platform = $tmpPlatform;
$this->_conn = $tmpConn;
$params = $this->_conn->getParams();
$params["dbname"] = "postgres";
$tmpPlatform = $this->_platform;
$tmpConn = $this->_conn;

$this->_conn = \Doctrine\DBAL\DriverManager::getConnection($params);
$this->_platform = $this->_conn->getDatabasePlatform();

parent::createDatabase($database);

$this->_platform = $tmpPlatform;
$this->_conn = $tmpConn;
}

protected function _getPortableTriggerDefinition($trigger)
{
return $trigger['trigger_name'];
Expand Down Expand Up @@ -120,18 +122,18 @@ protected function _getPortableTableDefinition($table)
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
{
$buffer = array();
foreach($tableIndexes AS $row) {
$colNumbers = explode( ' ', $row['indkey'] );
$colNumbersSql = 'IN (' . join( ' ,', $colNumbers ) . ' )';
foreach ($tableIndexes AS $row) {
$colNumbers = explode(' ', $row['indkey']);
$colNumbersSql = 'IN (' . join(' ,', $colNumbers) . ' )';
$columnNameSql = "SELECT attnum, attname FROM pg_attribute
WHERE attrelid={$row['indrelid']} AND attnum $colNumbersSql ORDER BY attnum ASC;";

$stmt = $this->_conn->executeQuery($columnNameSql);
$indexColumns = $stmt->fetchAll();

// required for getting the order of the columns right.
foreach ($colNumbers AS $colNum) {
foreach ( $indexColumns as $colRow ) {
foreach ($indexColumns as $colRow) {
if ($colNum == $colRow['attnum']) {
$buffer[] = array(
'key_name' => $row['relname'],
Expand All @@ -153,7 +155,7 @@ protected function _getPortableDatabaseDefinition($database)

protected function _getPortableSequenceDefinition($sequence)
{
$data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM '.$sequence['relname']);
$data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM ' . $sequence['relname']);
return new Sequence($sequence['relname'], $data[0]['increment_by'], $data[0]['min_value']);
}

Expand All @@ -166,7 +168,7 @@ protected function _getPortableTableColumnDefinition($tableColumn)
$length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']);
$tableColumn['length'] = $length;
}

$matches = array();

$autoincrement = false;
Expand All @@ -175,29 +177,34 @@ protected function _getPortableTableColumnDefinition($tableColumn)
$tableColumn['default'] = null;
$autoincrement = true;
}

if (stripos($tableColumn['default'], 'NULL') === 0) {
$tableColumn['default'] = null;
}

$length = (isset($tableColumn['length'])) ? $tableColumn['length'] : null;
if ($length == '-1' && isset($tableColumn['atttypmod'])) {
$length = $tableColumn['atttypmod'] - 4;
}
if ((int)$length <= 0) {
if ((int) $length <= 0) {
$length = null;
}
$type = array();
$fixed = null;
if ( ! isset($tableColumn['name'])) {

if (!isset($tableColumn['name'])) {
$tableColumn['name'] = '';
}

$precision = null;
$scale = null;

$dbType = strtolower($tableColumn['type']);

if ($this->_platform->hasDoctrineTypeMappingFor($tableColumn['type'])) {
$dbType = strtolower($tableColumn['type']);
} else {
$dbType = strtolower($tableColumn['domain_type']);
$tableColumn['complete_type'] = $tableColumn['domain_complete_type'];
}

$type = $this->_platform->getDoctrineTypeMapping($dbType);
switch ($dbType) {
Expand Down Expand Up @@ -239,7 +246,7 @@ protected function _getPortableTableColumnDefinition($tableColumn)
case 'decimal':
case 'money':
case 'numeric':
if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['complete_type'], $match)) {
if (preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['complete_type'], $match)) {
$precision = $match[1];
$scale = $match[2];
$length = null;
Expand All @@ -251,17 +258,18 @@ protected function _getPortableTableColumnDefinition($tableColumn)
}

$options = array(
'length' => $length,
'notnull' => (bool) $tableColumn['isnotnull'],
'default' => $tableColumn['default'],
'primary' => (bool) ($tableColumn['pri'] == 't'),
'length' => $length,
'notnull' => (bool) $tableColumn['isnotnull'],
'default' => $tableColumn['default'],
'primary' => (bool) ($tableColumn['pri'] == 't'),
'precision' => $precision,
'scale' => $scale,
'fixed' => $fixed,
'unsigned' => false,
'scale' => $scale,
'fixed' => $fixed,
'unsigned' => false,
'autoincrement' => $autoincrement,
);

return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
}

}
Expand Up @@ -3,10 +3,46 @@
namespace Doctrine\Tests\DBAL\Functional\Schema;

use Doctrine\DBAL\Schema;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

require_once __DIR__ . '/../../../TestInit.php';

class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
{
/**
* @group DBAL-21
*/
public function testSupportDomainTypeFallback()
{
$createDomainTypeSQL = "CREATE DOMAIN MyMoney AS DECIMAL(18,2)";
$this->_conn->exec($createDomainTypeSQL);

$createTableSQL = "CREATE TABLE domain_type_test (id INT PRIMARY KEY, value MyMoney)";
$this->_conn->exec($createTableSQL);

$table = $this->_conn->getSchemaManager()->listTableDetails('domain_type_test');
$this->assertType('Doctrine\DBAL\Types\DecimalType', $table->getColumn('value')->getType());

Type::addType('MyMoney', 'Doctrine\Tests\DBAL\Functional\Schema\MoneyType');
$this->_conn->getDatabasePlatform()->registerDoctrineTypeMapping('MyMoney', 'MyMoney');

$table = $this->_conn->getSchemaManager()->listTableDetails('domain_type_test');
$this->assertType('Doctrine\Tests\DBAL\Functional\Schema\MoneyType', $table->getColumn('value')->getType());
}
}

class MoneyType extends Type
{

public function getName()
{
return "MyMoney";
}

public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return 'MyMoney';
}

}

0 comments on commit 93ad4c2

Please sign in to comment.