Commit a6d9236e authored by romanb's avatar romanb

[2.0] Fixes and enhancements to sequence generators. Test suite now runs &...

[2.0] Fixes and enhancements to sequence generators. Test suite now runs & passes against postgres. Other minor, unrelated cleanups.
parent 16c4efcc
...@@ -6,8 +6,8 @@ Doctrine ...@@ -6,8 +6,8 @@ Doctrine
Doctrine is a Object Relational Mapper built from scratch with PHP5. It contains a few ports of other popular PHP classes/libraries. Doctrine is a Object Relational Mapper built from scratch with PHP5. It contains a few ports of other popular PHP classes/libraries.
Url: http://www.phpdoctrine.org Url: http://www.doctrine-project.org
Copyright: 2005-2007 Konsta Vesterinen Copyright: 2005-2009 Konsta Vesterinen
License: LGPL - see LICENSE file License: LGPL - see LICENSE file
symfony symfony
......
...@@ -149,6 +149,13 @@ class Connection ...@@ -149,6 +149,13 @@ class Connection
* @var Doctrine\DBAL\Driver * @var Doctrine\DBAL\Driver
*/ */
protected $_driver; protected $_driver;
/**
* Whether to quote identifiers. Read from the configuration upon construction.
*
* @var boolean
*/
protected $_quoteIdentifiers = false;
/** /**
* Initializes a new instance of the Connection class. * Initializes a new instance of the Connection class.
...@@ -171,14 +178,18 @@ class Connection ...@@ -171,14 +178,18 @@ class Connection
// Create default config and event manager if none given // Create default config and event manager if none given
if ( ! $config) { if ( ! $config) {
$this->_config = new Configuration(); $config = new Configuration();
} }
if ( ! $eventManager) { if ( ! $eventManager) {
$this->_eventManager = new EventManager(); $eventManager = new EventManager();
} }
$this->_config = $config;
$this->_eventManager = $eventManager;
$this->_platform = $driver->getDatabasePlatform(); $this->_platform = $driver->getDatabasePlatform();
$this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel(); $this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel();
$this->_quoteIdentifiers = $config->getQuoteIdentifiers();
$this->_platform->setQuoteIdentifiers($this->_quoteIdentifiers);
} }
/** /**
...@@ -354,29 +365,15 @@ class Connection ...@@ -354,29 +365,15 @@ class Connection
} }
/** /**
* Quote a string so it can be safely used as a table or column name. * Quote a string so it can be safely used as a table or column name, even if
* it is a reserved name.
* *
* Delimiting style depends on which database driver is being used. * Delimiting style depends on the underlying database platform that is being used.
* *
* NOTE: just because you CAN use delimited identifiers doesn't mean * NOTE: Just because you CAN use delimited identifiers doesn't mean
* you SHOULD use them. In general, they end up causing way more * you SHOULD use them. In general, they end up causing way more
* problems than they solve. * problems than they solve.
* *
* Portability is broken by using the following characters inside
* delimited identifiers:
* + backtick (<kbd>`</kbd>) -- due to MySQL
* + double quote (<kbd>"</kbd>) -- due to Oracle
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
*
* Delimited identifiers are known to generally work correctly under
* the following drivers:
* + mssql
* + mysql
* + mysqli
* + oci8
* + pgsql
* + sqlite
*
* @param string $str identifier name to be quoted * @param string $str identifier name to be quoted
* @param bool $checkOption check the 'quote_identifier' option * @param bool $checkOption check the 'quote_identifier' option
* *
...@@ -384,7 +381,10 @@ class Connection ...@@ -384,7 +381,10 @@ class Connection
*/ */
public function quoteIdentifier($str) public function quoteIdentifier($str)
{ {
return $this->_platform->quoteIdentifier($str); if ($this->_quoteIdentifiers) {
return $this->_platform->quoteIdentifier($str);
}
return $str;
} }
/** /**
......
...@@ -42,7 +42,27 @@ class Driver implements \Doctrine\DBAL\Driver ...@@ -42,7 +42,27 @@ class Driver implements \Doctrine\DBAL\Driver
*/ */
private function _constructPdoDsn(array $params) private function _constructPdoDsn(array $params)
{ {
//TODO $dsn = 'oci:';
if (isset($params['host'])) {
$dsn .= 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
'(HOST=' . $params['host'] . ')';
if (isset($params['port'])) {
$dsn .= '(PORT=' . $params['port'] . ')';
} else {
$dsn .= '(PORT=1521)';
}
$dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
} else {
$dsn .= 'dbname=' . $params['dbname'];
}
if (isset($params['charset'])) {
$dsn .= ';charset=' . $params['charset'];
}
return $dsn;
} }
public function getDatabasePlatform() public function getDatabasePlatform()
......
...@@ -35,21 +35,7 @@ use Doctrine\DBAL\Connection; ...@@ -35,21 +35,7 @@ use Doctrine\DBAL\Connection;
*/ */
abstract class AbstractPlatform abstract class AbstractPlatform
{ {
protected $_quoteIdentifiers = false; private $_quoteIdentifiers = false;
protected $valid_default_values = array(
'text' => '',
'boolean' => true,
'integer' => 0,
'decimal' => 0.0,
'float' => 0.0,
'timestamp' => '1970-01-01 00:00:00',
'time' => '00:00:00',
'date' => '1970-01-01',
'clob' => '',
'blob' => '',
'string' => ''
);
/** /**
* Constructor. * Constructor.
...@@ -61,7 +47,7 @@ abstract class AbstractPlatform ...@@ -61,7 +47,7 @@ abstract class AbstractPlatform
*/ */
public function setQuoteIdentifiers($bool) public function setQuoteIdentifiers($bool)
{ {
$this->_quoteIdentifiers = (bool)$bool; $this->_quoteIdentifiers = $bool;
} }
/** /**
...@@ -986,39 +972,34 @@ abstract class AbstractPlatform ...@@ -986,39 +972,34 @@ abstract class AbstractPlatform
} }
/** /**
* Enter description here... * Gets the SQL statement(s) to create a table with the specified name, columns and options
* on this platform.
* *
* @todo Throw exception by default? * @param string $table
* @param array $columns
* @param array $options
* @return array
*/ */
public function getCreateTableSql($table, array $columns, array $options = array()) public function getCreateTableSql($table, array $columns, array $options = array())
{ {
if ( ! $table) { $columnListSql = $this->getColumnDeclarationListSql($columns);
throw DoctrineException::updateMe('no valid table name specified');
}
if (empty($columns)) {
throw DoctrineException::updateMe('no fields specified for table ' . $name);
}
$queryFields = $this->getColumnDeclarationListSql($columns);
if (isset($options['primary']) && ! empty($options['primary'])) { if (isset($options['primary']) && ! empty($options['primary'])) {
$queryFields .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
} }
if (isset($options['indexes']) && ! empty($options['indexes'])) { if (isset($options['indexes']) && ! empty($options['indexes'])) {
foreach($options['indexes'] as $index => $definition) { foreach($options['indexes'] as $index => $definition) {
$queryFields .= ', ' . $this->getIndexDeclaration($index, $definition); $columnListSql .= ', ' . $this->getIndexDeclarationSql($index, $definition);
} }
} }
$query = 'CREATE TABLE ' . $this->quoteIdentifier($table, true) . ' (' . $queryFields; $query = 'CREATE TABLE ' . $this->quoteIdentifier($table, true) . ' (' . $columnListSql;
/*$check = $this->getCheckDeclaration($columns); $check = $this->getCheckDeclarationSql($columns);
if ( ! empty($check)) { if ( ! empty($check)) {
$query .= ', ' . $check; $query .= ', ' . $check;
}*/ }
$query .= ')'; $query .= ')';
$sql[] = $query; $sql[] = $query;
...@@ -1030,13 +1011,18 @@ abstract class AbstractPlatform ...@@ -1030,13 +1011,18 @@ abstract class AbstractPlatform
} }
} }
} }
return $sql; return $sql;
} }
/** /**
* Enter description here... * Gets the SQL to create a sequence on this platform.
* *
* @todo Throw exception by default? * @param string $sequenceName
* @param integer $start
* @param integer $allocationSize
* @return string
* @throws DoctrineException
*/ */
public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1) public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1)
{ {
...@@ -1044,7 +1030,7 @@ abstract class AbstractPlatform ...@@ -1044,7 +1030,7 @@ abstract class AbstractPlatform
} }
/** /**
* Creates a constraint on a table. * Gets the SQL to create a constraint on a table on this platform.
* *
* @param string $table name of the table on which the constraint is to be created * @param string $table name of the table on which the constraint is to be created
* @param string $name name of the constraint to be created * @param string $name name of the constraint to be created
...@@ -1062,6 +1048,7 @@ abstract class AbstractPlatform ...@@ -1062,6 +1048,7 @@ abstract class AbstractPlatform
* 'last_login' => array() * 'last_login' => array()
* ) * )
* ) * )
* @return string
*/ */
public function getCreateConstraintSql($table, $name, $definition) public function getCreateConstraintSql($table, $name, $definition)
{ {
...@@ -1083,12 +1070,11 @@ abstract class AbstractPlatform ...@@ -1083,12 +1070,11 @@ abstract class AbstractPlatform
} }
/** /**
* Get the stucture of a field into an array * Gets the SQL to create an index on a table on this platform.
* *
* @param string $table name of the table on which the index is to be created * @param string $table name of the table on which the index is to be created
* @param string $name name of the index to be created * @param string $name name of the index to be created
* @param array $definition associative array that defines properties of the index to be created. * @param array $definition associative array that defines properties of the index to be created.
* @see Doctrine_Export::createIndex()
* @return string * @return string
*/ */
public function getCreateIndexSql($table, $name, array $definition) public function getCreateIndexSql($table, $name, array $definition)
...@@ -1116,22 +1102,14 @@ abstract class AbstractPlatform ...@@ -1116,22 +1102,14 @@ abstract class AbstractPlatform
} }
/** /**
* Quote a string so it can be safely used as a table or column name. * Quotes a string so that it can be safely used as a table or column name,
* even if it is a reserved word of the platform.
* *
* Delimiting style depends on which database driver is being used. * NOTE: Just because you CAN use quoted identifiers doesn't mean
*
* NOTE: just because you CAN use delimited identifiers doesn't mean
* you SHOULD use them. In general, they end up causing way more * you SHOULD use them. In general, they end up causing way more
* problems than they solve. * problems than they solve.
* *
* Portability is broken by using the following characters inside
* delimited identifiers:
* + backtick (<kbd>`</kbd>) -- due to MySQL
* + double quote (<kbd>"</kbd>) -- due to Oracle
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
*
* @param string $str identifier name to be quoted * @param string $str identifier name to be quoted
* @param bool $checkOption check the 'quote_identifier' option
* @return string quoted identifier string * @return string quoted identifier string
*/ */
public function quoteIdentifier($str) public function quoteIdentifier($str)
......
...@@ -16,15 +16,13 @@ ...@@ -16,15 +16,13 @@
* *
* This software consists of voluntary contributions made by many individuals * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\DBAL\Platforms; namespace Doctrine\DBAL\Platforms;
/** /**
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central * OraclePlatform.
* point of abstraction of platform-specific behaviors, features and SQL dialects.
* They are a passive source of information.
* *
* @since 2.0 * @since 2.0
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
...@@ -40,24 +38,10 @@ class OraclePlatform extends AbstractPlatform ...@@ -40,24 +38,10 @@ class OraclePlatform extends AbstractPlatform
parent::__construct(); parent::__construct();
} }
/**
* Adds an driver-specific LIMIT clause to the query
*
* @param string $query query to modify
* @param integer $limit limit the number of rows
* @param integer $offset start reading from given offset
* @return string the modified query
* @override
*/
public function writeLimitClause($query, $limit = false, $offset = false)
{
return $this->_createLimitSubquery($query, $limit, $offset);
}
/** /**
* @todo Doc * @todo Doc
*/ */
private function _createLimitSubquery($query, $limit, $offset, $column = null) /*private function _createLimitSubquery($query, $limit, $offset, $column = null)
{ {
$limit = (int) $limit; $limit = (int) $limit;
$offset = (int) $offset; $offset = (int) $offset;
...@@ -81,27 +65,7 @@ class OraclePlatform extends AbstractPlatform ...@@ -81,27 +65,7 @@ class OraclePlatform extends AbstractPlatform
} }
} }
return $query; return $query;
} }*/
/**
* Creates the SQL for Oracle that can be used in the subquery for the limit-subquery
* algorithm.
*
* @override
*/
public function writeLimitClauseInSubquery(Doctrine_ClassMetadata $rootClass,
$query, $limit = false, $offset = false)
{
// NOTE: no composite key support
$columnNames = $rootClass->getIdentifierColumnNames();
if (count($columnNames) > 1) {
throw \Doctrine\Common\DoctrineException::updateMe("Composite keys in LIMIT queries are "
. "currently not supported.");
}
$column = $columnNames[0];
return $this->_createLimitSubquery($query, $limit, $offset, $column);
}
/** /**
* return string to call a function to get a substring inside an SQL statement * return string to call a function to get a substring inside an SQL statement
...@@ -188,7 +152,7 @@ class OraclePlatform extends AbstractPlatform ...@@ -188,7 +152,7 @@ class OraclePlatform extends AbstractPlatform
* declare the specified field. * declare the specified field.
* @override * @override
*/ */
public function getNativeDeclaration(array $field) /*public function getNativeDeclaration(array $field)
{ {
if ( ! isset($field['type'])) { if ( ! isset($field['type'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.'); throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.');
...@@ -232,7 +196,7 @@ class OraclePlatform extends AbstractPlatform ...@@ -232,7 +196,7 @@ class OraclePlatform extends AbstractPlatform
default: default:
} }
throw \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); throw \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.');
} }*/
/** /**
* Maps a native array description of a field to a doctrine datatype and length * Maps a native array description of a field to a doctrine datatype and length
...@@ -242,7 +206,7 @@ class OraclePlatform extends AbstractPlatform ...@@ -242,7 +206,7 @@ class OraclePlatform extends AbstractPlatform
* @throws Doctrine_DataDict_Oracle_Exception * @throws Doctrine_DataDict_Oracle_Exception
* @override * @override
*/ */
public function getPortableDeclaration(array $field) /*public function getPortableDeclaration(array $field)
{ {
if ( ! isset($field['data_type'])) { if ( ! isset($field['data_type'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Native oracle definition must have a data_type key specified'); throw \Doctrine\Common\DoctrineException::updateMe('Native oracle definition must have a data_type key specified');
...@@ -332,12 +296,24 @@ class OraclePlatform extends AbstractPlatform ...@@ -332,12 +296,24 @@ class OraclePlatform extends AbstractPlatform
'length' => $length, 'length' => $length,
'unsigned' => $unsigned, 'unsigned' => $unsigned,
'fixed' => $fixed); 'fixed' => $fixed);
}*/
/**
* {@inheritdoc}
*
* @return string
* @override
*/
public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1)
{
return 'CREATE SEQUENCE ' . $this->quoteIdentifier($sequenceName)
. ' START WITH ' . $start . ' INCREMENT BY ' . $allocationSize;
} }
/** /**
* Enter description here... * {@inheritdoc}
* *
* @param unknown_type $sequenceName * @param string $sequenceName
* @override * @override
*/ */
public function getSequenceNextValSql($sequenceName) public function getSequenceNextValSql($sequenceName)
...@@ -346,9 +322,9 @@ class OraclePlatform extends AbstractPlatform ...@@ -346,9 +322,9 @@ class OraclePlatform extends AbstractPlatform
} }
/** /**
* Enter description here... * {@inheritdoc}
* *
* @param unknown_type $level * @param integer $level
* @override * @override
*/ */
public function getSetTransactionIsolationSql($level) public function getSetTransactionIsolationSql($level)
...@@ -359,7 +335,7 @@ class OraclePlatform extends AbstractPlatform ...@@ -359,7 +335,7 @@ class OraclePlatform extends AbstractPlatform
/** /**
* Enter description here... * Enter description here...
* *
* @param unknown_type $level * @param integer $level
* @override * @override
*/ */
protected function _getTransactionIsolationLevelSql($level) protected function _getTransactionIsolationLevelSql($level)
......
...@@ -288,7 +288,6 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -288,7 +288,6 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getMd5Expression($column) public function getMd5Expression($column)
{ {
$column = $this->quoteIdentifier($column); $column = $this->quoteIdentifier($column);
if ($this->_version > 7) { if ($this->_version > 7) {
return 'MD5(' . $column . ')'; return 'MD5(' . $column . ')';
} else { } else {
...@@ -795,17 +794,8 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -795,17 +794,8 @@ class PostgreSqlPlatform extends AbstractPlatform
} }
/** /**
* return RDBMS specific create sequence statement * {@inheritdoc}
* *
* @throws Doctrine\DBAL\ConnectionException if something fails at database level
* @param string $seqName name of the sequence to be created
* @param string $start start value of the sequence; default is 1
* @param array $options An associative array of table options:
* array(
* 'comment' => 'Foo',
* 'charset' => 'utf8',
* 'collate' => 'utf8_unicode_ci',
* );
* @return string * @return string
* @override * @override
*/ */
...@@ -836,22 +826,15 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -836,22 +826,15 @@ class PostgreSqlPlatform extends AbstractPlatform
*/ */
public function getCreateTableSql($name, array $fields, array $options = array()) public function getCreateTableSql($name, array $fields, array $options = array())
{ {
if ( ! $name) {
throw DoctrineException::updateMe('no valid table name specified');
}
if (empty($fields)) {
throw DoctrineException::updateMe('no fields specified for table ' . $name);
}
$queryFields = $this->getColumnDeclarationListSql($fields); $queryFields = $this->getColumnDeclarationListSql($fields);
if (isset($options['primary']) && ! empty($options['primary'])) { if (isset($options['primary']) && ! empty($options['primary'])) {
$keyColumns = array_values($options['primary']); $keyColumns = array_unique(array_values($options['primary']));
$keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns); $keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns);
$queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
} }
$query = 'CREATE TABLE ' . $this->quoteIdentifier($name, true) . ' (' . $queryFields . ')'; $query = 'CREATE TABLE ' . $this->quoteIdentifier($name) . ' (' . $queryFields . ')';
$sql[] = $query; $sql[] = $query;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* *
* This software consists of voluntary contributions made by many individuals * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\ORM\Cache; namespace Doctrine\ORM\Cache;
......
...@@ -39,6 +39,7 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -39,6 +39,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/ */
public function __construct() public function __construct()
{ {
parent::__construct();
$this->_attributes = array_merge($this->_attributes, array( $this->_attributes = array_merge($this->_attributes, array(
'resultCacheImpl' => null, 'resultCacheImpl' => null,
'queryCacheImpl' => null, 'queryCacheImpl' => null,
......
...@@ -62,8 +62,8 @@ class SequenceGenerator extends AbstractIdGenerator implements \Serializable ...@@ -62,8 +62,8 @@ class SequenceGenerator extends AbstractIdGenerator implements \Serializable
// Allocate new values // Allocate new values
$conn = $em->getConnection(); $conn = $em->getConnection();
$sql = $conn->getDatabasePlatform()->getSequenceNextValSql($this->_sequenceName); $sql = $conn->getDatabasePlatform()->getSequenceNextValSql($this->_sequenceName);
$this->_maxValue = $conn->fetchOne($sql); $this->_nextValue = $conn->fetchOne($sql);
$this->_nextValue = $this->_maxValue - $this->_allocationSize; $this->_maxValue = $this->_nextValue + $this->_allocationSize;
} }
return $this->_nextValue++; return $this->_nextValue++;
} }
......
<?php
/*
* $Id: Reader.php 3882 2008-02-22 18:11:35Z jwage $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
namespace Doctrine\ORM\Import\Reader;
/**
* class Doctrine_Import_Reader
* Is responsible of reading a database definitions from a source and costructing a
* database schema
*
* @package Doctrine
* @subpackage Import
* @link www.phpdoctrine.org
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @since 1.0
* @version $Revision: 3882 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
abstract class AbstractRader
{
abstract public function read();
}
\ No newline at end of file
<?php
/*
* $Id: Db.php 3882 2008-02-22 18:11:35Z jwage $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
namespace Doctrine\ORM\Import\Reader;
/**
* class Doctrine_Import_Reader_Db
* Reads a database using the given PDO connection and constructs a database
* schema
*
* @package Doctrine
* @subpackage Import
* @link www.phpdoctrine.org
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @since 1.0
* @version $Revision: 3882 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Db extends AbstractReader
{
/**
* @access private
*/
private $pdo;
/**
*
* @param object pdo * @return
* @access public
*/
public function setPdo( $pdo )
{
} // end of member function setPdo
/**
*
* @return Doctrine_Schema
* @access public
*/
public function read()
{
$dataDict = Doctrine_Manager::getInstance()->getCurrentConnection()->getDataDict();
$schema = new Doctrine_Schema(); /* @todo FIXME i am incomplete*/
$db = new Doctrine_Schema_Database();
$schema->addDatabase($db);
$dbName = 'XXtest'; // @todo FIXME where should we get
$this->conn->set("name",$dbName);
$tableNames = $dataDict->listTables();
foreach ($tableNames as $tableName) {
$table = new Doctrine_Schema_Table();
$table->set("name",$tableName);
$tableColumns = $dataDict->listTableColumns($tableName);
foreach ($tableColumns as $tableColumn) {
$table->addColumn($tableColumn);
}
$this->conn->addTable($table);
if ($fks = $dataDict->listTableConstraints($tableName)) {
foreach ($fks as $fk) {
$relation = new Doctrine_Schema_Relation();
$relation->setRelationBetween($fk['referencingColumn'],$fk['referencedTable'],$fk['referencedColumn']);
$table->setRelation($relation);
}
}
}
return $schema;
}
}
\ No newline at end of file
<?php
/*
* $Id: Propel.php 3882 2008-02-22 18:11:35Z jwage $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
namespace Doctrine\ORM\Import\Reader;
/**
* class Doctrine_Import_Reader_Xml_Propel
*
* @package Doctrine
* @subpackage Import
* @link www.phpdoctrine.org
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @since 1.0
* @version $Revision: 3882 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Propel extends AbstractReader
{
/**
* @access private
*/
private $xml;
/**
*
* @param string xml * @return
* @access public
*/
public function setXml( $xml )
{
} // end of member function setXml
public function read()
{ }
}
\ No newline at end of file
...@@ -873,10 +873,11 @@ final class ClassMetadata ...@@ -873,10 +873,11 @@ final class ClassMetadata
} }
/** /**
* Sets the value of a field on an entity of the mapped class.
* *
* @param <type> $entity * @param object $entity
* @param <type> $field * @param string $field
* @param <type> $value * @param mixed $value
*/ */
public function setValue($entity, $field, $value) public function setValue($entity, $field, $value)
{ {
......
...@@ -141,7 +141,17 @@ class ClassMetadataFactory ...@@ -141,7 +141,17 @@ class ClassMetadataFactory
if ( ! $class->getIdentifier()) { if ( ! $class->getIdentifier()) {
throw MappingException::identifierRequired($className); throw MappingException::identifierRequired($className);
} }
$this->_completeIdGeneratorMapping($class); if ($parent) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->getSequenceGeneratorDefinition());
} else if ($parent->isIdGeneratorTable()) {
$class->getTableGeneratorDefinition($parent->getTableGeneratorDefinition());
}
$class->setIdGeneratorType($parent->getIdGeneratorType());
$class->setidGenerator($parent->getIdGenerator());
} else {
$this->_completeIdGeneratorMapping($class);
}
if ($parent && $parent->isInheritanceTypeSingleTable()) { if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setTableName($parent->getTableName()); $class->setTableName($parent->getTableName());
......
...@@ -75,12 +75,7 @@ class AnnotationDriver ...@@ -75,12 +75,7 @@ class AnnotationDriver
'length' => $discrColumnAnnot->length 'length' => $discrColumnAnnot->length
)); ));
} }
/*
// Evaluate DoctrineDiscriminatorMap annotation
if ($discrMapAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorMap')) {
$metadata->setDiscriminatorMap((array)$discrMapAnnot->value);
}
*/
// Evaluate DoctrineDiscriminatorMap annotation // Evaluate DoctrineDiscriminatorMap annotation
if ($discrValueAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorValue')) { if ($discrValueAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorValue')) {
$metadata->setDiscriminatorValue($discrValueAnnot->value); $metadata->setDiscriminatorValue($discrValueAnnot->value);
...@@ -91,6 +86,11 @@ class AnnotationDriver ...@@ -91,6 +86,11 @@ class AnnotationDriver
$metadata->setSubclasses($subClassesAnnot->value); $metadata->setSubclasses($subClassesAnnot->value);
} }
// Evaluate DoctrineChangeTrackingPolicy annotation
if ($changeTrackingAnnot = $annotClass->getAnnotation('DoctrineChangeTrackingPolicy')) {
$metadata->setChangeTrackingPolicy($changeTrackingAnnot->value);
}
// Evaluate annotations on properties/fields // Evaluate annotations on properties/fields
foreach ($annotClass->getProperties() as $property) { foreach ($annotClass->getProperties() as $property) {
if ($metadata->hasField($property->getName())) { if ($metadata->hasField($property->getName())) {
......
...@@ -96,3 +96,4 @@ final class DoctrineSequenceGenerator extends \Addendum\Annotation { ...@@ -96,3 +96,4 @@ final class DoctrineSequenceGenerator extends \Addendum\Annotation {
/** The name of the class that defines the generator. */ /** The name of the class that defines the generator. */
//public $definingClass; //public $definingClass;
} }
final class DoctrineChangeTrackingPolicy {}
<?php <?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\ORM\Mapping\Driver; namespace Doctrine\ORM\Mapping\Driver;
...@@ -12,7 +31,7 @@ if ( ! class_exists('sfYaml', false)) { ...@@ -12,7 +31,7 @@ if ( ! class_exists('sfYaml', false)) {
} }
/** /**
* The YamlDriver reads the mapping metadata from yaml schema files * The YamlDriver reads the mapping metadata from yaml schema files.
* *
* @author Jonathan H. Wage <jonwage@gmail.com> * @author Jonathan H. Wage <jonwage@gmail.com>
* @since 2.0 * @since 2.0
...@@ -54,8 +73,8 @@ class YamlDriver ...@@ -54,8 +73,8 @@ class YamlDriver
$metadata->setDiscriminatorColumn($entity['discriminatorColumn']); $metadata->setDiscriminatorColumn($entity['discriminatorColumn']);
} }
if (isset($entity['discriminatorMap']) && $entity['discriminatorMap']) { if (isset($entity['discriminatorValue']) && $entity['discriminatorValue']) {
$metadata->setDiscriminatorMap((array) $entity['discriminatorMap']); $metadata->setDiscriminatorValue($entity['discriminatorValue']);
} }
if (isset($entity['subClasses']) && $entity['subClasses']) { if (isset($entity['subClasses']) && $entity['subClasses']) {
...@@ -82,8 +101,7 @@ class YamlDriver ...@@ -82,8 +101,7 @@ class YamlDriver
if (in_array($type, $relationTypes)) { if (in_array($type, $relationTypes)) {
unset($property['type']); unset($property['type']);
switch ($type) switch ($type) {
{
case 'ManyToOne': case 'ManyToOne':
case 'OneToOne': case 'OneToOne':
$mapping['joinColumns'] = $joinColumns; $mapping['joinColumns'] = $joinColumns;
......
...@@ -77,9 +77,10 @@ class SchemaTool ...@@ -77,9 +77,10 @@ class SchemaTool
*/ */
public function getCreateSchemaSql(array $classes) public function getCreateSchemaSql(array $classes)
{ {
$processedClasses = array(); $sql = array(); // All SQL statements
$sql = array(); $processedClasses = array(); // Reminder for processed classes, used for hierarchies
$foreignKeyConstraints = array(); $foreignKeyConstraints = array(); // FK SQL statements. Appended to $sql at the end.
$sequences = array(); // Sequence SQL statements. Appended to $sql at the end.
// First we create the tables // First we create the tables
foreach ($classes as $class) { foreach ($classes as $class) {
...@@ -116,15 +117,27 @@ class SchemaTool ...@@ -116,15 +117,27 @@ class SchemaTool
$sql = array_merge($sql, $this->_platform->getCreateTableSql($class->getTableName(), $columns, $options)); $sql = array_merge($sql, $this->_platform->getCreateTableSql($class->getTableName(), $columns, $options));
$processedClasses[$class->getClassName()] = true; $processedClasses[$class->getClassName()] = true;
if ($class->isIdGeneratorSequence()) {
$seqDef = $class->getSequenceGeneratorDefinition();
$sequences[] = $this->_platform->getCreateSequenceSql(
$seqDef['sequenceName'],
$seqDef['initialValue'],
$seqDef['allocationSize']
);
}
} }
// Now create the foreign key constraints // Append the foreign key constraints SQL
if ($this->_platform->supportsForeignKeyConstraints()) { if ($this->_platform->supportsForeignKeyConstraints()) {
foreach ($foreignKeyConstraints as $fkConstraint) { foreach ($foreignKeyConstraints as $fkConstraint) {
$sql = array_merge($sql, (array)$this->_platform->getCreateForeignKeySql($fkConstraint['tableName'], $fkConstraint)); $sql = array_merge($sql, (array)$this->_platform->getCreateForeignKeySql($fkConstraint['tableName'], $fkConstraint));
} }
} }
// Append the sequence SQL
$sql = array_merge($sql, $sequences);
return $sql; return $sql;
} }
......
...@@ -313,6 +313,8 @@ class UnitOfWork implements PropertyChangedListener ...@@ -313,6 +313,8 @@ class UnitOfWork implements PropertyChangedListener
$entitySet = $this->_identityMap; $entitySet = $this->_identityMap;
} }
//TODO: Compute changesets for NEW entities first here
foreach ($entitySet as $className => $entities) { foreach ($entitySet as $className => $entities) {
$class = $this->_em->getClassMetadata($className); $class = $this->_em->getClassMetadata($className);
...@@ -338,7 +340,7 @@ class UnitOfWork implements PropertyChangedListener ...@@ -338,7 +340,7 @@ class UnitOfWork implements PropertyChangedListener
if ($state == self::STATE_MANAGED || $state == self::STATE_NEW) { if ($state == self::STATE_MANAGED || $state == self::STATE_NEW) {
$actualData = array(); $actualData = array();
foreach ($class->getReflectionProperties() as $name => $refProp) { foreach ($class->getReflectionProperties() as $name => $refProp) {
if ( ! $class->isIdentifier($name) || $class->isIdentifierNatural()) { if ( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) {
$actualData[$name] = $refProp->getValue($entity); $actualData[$name] = $refProp->getValue($entity);
} }
......
...@@ -42,7 +42,7 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -42,7 +42,7 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->flush(); $this->_em->flush();
$this->_em->clear(); $this->_em->clear();
$query = $this->_em->createQuery("select e from Doctrine\Tests\ORM\Functional\ParentEntity e"); $query = $this->_em->createQuery("select e from Doctrine\Tests\ORM\Functional\ParentEntity e order by e.id asc");
$entities = $query->getResultList(); $entities = $query->getResultList();
......
...@@ -26,7 +26,7 @@ class SequenceGeneratorTest extends \Doctrine\Tests\OrmTestCase ...@@ -26,7 +26,7 @@ class SequenceGeneratorTest extends \Doctrine\Tests\OrmTestCase
{ {
for ($i=0; $i < 42; ++$i) { for ($i=0; $i < 42; ++$i) {
if ($i % 10 == 0) { if ($i % 10 == 0) {
$this->_em->getConnection()->setFetchOneResult((int)($i / 10) * 10 + 10); $this->_em->getConnection()->setFetchOneResult((int)($i / 10) * 10);
} }
$id = $this->_seqGen->generate($this->_em, null); $id = $this->_seqGen->generate($this->_em, null);
$this->assertEquals($i, $id); $this->assertEquals($i, $id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment