Commit be7931ed authored by zYne's avatar zYne

Added Doctrine_Hydrate_Alias for more flexible alias handling, small fixes for many classes

parent 83d68f5d
......@@ -50,8 +50,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* one of the following (true, false, 'emulated')
*/
protected $supported = array();
protected $options = array();
/**
* @var array $modules an array containing all modules
* transaction Doctrine_Transaction driver, handles savepoint and transaction isolation abstraction
......@@ -75,6 +73,10 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
'export' => false,
'unitOfWork' => false,
);
/**
* @var array $properties an array of connection properties
*/
protected $properties = array();
/**
* @var array $availibleDrivers an array containing all availible drivers
*/
......@@ -145,7 +147,10 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$class = 'Doctrine_' . ucwords($name) . '_' . $this->getName();
$this->modules[$name] = new $class($this);
}
}
}
if(isset($this->properties[$name]))
return $this->properties[$name];
return $this->modules[$name];
}
......@@ -206,9 +211,12 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
if ($checkOption && ! $this->getAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER)) {
return $str;
}
return $str;
//$str = str_replace($this->identifier_quoting['end'], $this->identifier_quoting['escape'] . $this->identifier_quoting['end'], $str);
//return $this->identifier_quoting['start'] . $str . $this->identifier_quoting['end'];
$str = str_replace($this->properties['identifier_quoting']['end'],
$this->properties['identifier_quoting']['escape'] .
$this->properties['identifier_quoting']['end'], $str);
return $this->properties['identifier_quoting']['start']
. $str . $this->properties['identifier_quoting']['end'];
}
/**
* returns the manager that created this connection
......@@ -291,7 +299,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public function getIndexName($idx) {
return sprintf($this->getAttribute(Doctrine::ATTR_IDXNAME_FORMAT),
preg_replace('/[^a-z0-9_\$]/i', '_', $idx));
preg_replace('/[^a-z0-9_\$]/i', '_', $idx));
}
/**
......
......@@ -65,9 +65,26 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common {
'identifier_quoting' => true,
'pattern_escaping' => true
);
$this->properties['string_quoting'] = array('start' => "'",
'end' => "'",
'escape' => '\\',
'escape_pattern' => '\\');
$this->properties['identifier_quoting'] = array('start' => '`',
'end' => '`',
'escape' => '`');
$this->properties['sql_comments'] = array(
array('start' => '-- ', 'end' => "\n", 'escape' => false),
array('start' => '#', 'end' => "\n", 'escape' => false),
array('start' => '/*', 'end' => '*/', 'escape' => false),
);
$this->properties['varchar_max_length'] = 255;
parent::__construct($manager, $adapter);
}
}
/**
* Returns the next free id of a sequence
*
......@@ -103,7 +120,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common {
$sequenceName = $this->quoteIdentifier($this->getSequenceName($seqName), true);
$seqcolName = $this->quoteIdentifier($this->options['seqcol_name'], true);
$query = 'SELECT MAX(' . $seqcolName . ') FROM ' . $sequenceName;
return $this->queryOne($query, 'integer');
return $this->fetchOne($query);
}
/**
* Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
......
......@@ -65,8 +65,6 @@ class Doctrine_Connection_Pgsql extends Doctrine_Connection_Common {
'pattern_escaping' => true,
);
$this->options['multi_query'] = false;
parent::__construct($manager, $adapter);
}
/**
......
......@@ -21,19 +21,20 @@
/**
* Doctrine_DataDict
*
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_DataDict {
protected $dbh;
public function __construct($dbh = null) {
$file = Doctrine::getPath().DIRECTORY_SEPARATOR."Doctrine".DIRECTORY_SEPARATOR."adodb-hack".DIRECTORY_SEPARATOR."adodb.inc.php";
if( ! file_exists($file))
......
......@@ -29,7 +29,7 @@ Doctrine::autoload('Doctrine_DataDict');
* @link www.phpdoctrine.com
* @since 1.0
*/
class Doctrine_DataDict_Mysql extends Doctrine_DataDict {
class Doctrine_DataDict_Mysql extends Doctrine_Connection_Module {
/**
* Obtain DBMS specific SQL code portion needed to declare an text type
* field to be used in statements like CREATE TABLE.
......@@ -55,6 +55,11 @@ class Doctrine_DataDict_Mysql extends Doctrine_DataDict {
*/
public function getNativeDeclaration($field) {
switch ($field['type']) {
case 'char':
$length = (! empty($field['length'])) ? $field['length'] : false;
return $length ? 'CHAR('.$length.')' : 'CHAR(255)';
case 'varchar':
case 'array':
case 'object':
case 'string':
......@@ -321,12 +326,15 @@ class Doctrine_DataDict_Mysql extends Doctrine_DataDict {
$field['default'] = empty($field['notnull']) ? null : 0;
}
$default = ' DEFAULT '.$this->conn->getDbh()->quote($field['default']);
} elseif (empty($field['notnull'])) {
}
/**
elseif (empty($field['notnull'])) {
$default = ' DEFAULT NULL';
}
*/
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
$unsigned = (isset($field['unsigned']) && $field['unsigned']) ? ' UNSIGNED' : '';
$name = $this->conn->quoteIdentifier($name, true);
......
......@@ -357,15 +357,15 @@ class Doctrine_DataDict_Pgsql extends Doctrine_Connection_Module {
*/
public function getNativeDeclaration(array $field) {
switch ($field['type']) {
case 'char':
case 'string':
case 'array':
case 'object':
case 'varchar':
case 'char':
$length = !empty($field['length'])
? $field['length'] : $db->options['default_text_field_length'];
$length = (isset($field['length']) && $field['length']) ? $field['length'] : null;
// TODO: $db->options['default_text_field_length'];
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
$fixed = ((isset($field['fixed']) && $field['fixed']) || $field['type'] == 'char') ? true : false;
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')')
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
......@@ -413,16 +413,16 @@ class Doctrine_DataDict_Pgsql extends Doctrine_Connection_Module {
}
}
/**
* Maps a native array description of a field to a MDB2 datatype and length
* Maps a native array description of a field to a portable Doctrine datatype and length
*
* @param array $field native field description
*
* @return array containing the various possible types, length, sign, fixed
*/
public function getDoctrineDeclaration(array $field) {
public function getPortableDeclaration(array $field) {
$length = $field['length'];
if ($length == '-1' && !empty($field['atttypmod'])) {
if ($length == '-1' && isset($field['atttypmod'])) {
$length = $field['atttypmod'] - 4;
}
if ((int)$length <= 0) {
......
......@@ -347,11 +347,102 @@ class Doctrine_Export extends Doctrine_Connection_Module {
* @return string
*/
public function getFieldDeclarationList(array $fields) {
foreach ($fields as $field_name => $field) {
$query = $this->conn->dataDict->getNativeDeclaration($field['type'], $field_name, $field);
$query_fields[] = $query;
foreach ($fields as $fieldName => $field) {
$query = $this->getDeclaration($fieldName, $field);
$queryFields[] = $query;
}
return implode(', ', $queryFields);
}
/**
* Obtain DBMS specific SQL code portion needed to declare a generic type
* field to be used in statements like CREATE TABLE.
*
* @param string $name name the field to be declared.
* @param array $field associative array with the name of the properties
* of the field being declared as array indexes. Currently, the types
* of supported field properties are as follows:
*
* length
* Integer value that determines the maximum length of the text
* field. If this argument is missing the field should be
* declared to have the longest length allowed by the DBMS.
*
* default
* Text value to be used as default for this field.
*
* notnull
* Boolean flag that indicates whether this field is constrained
* to not be set to null.
* charset
* Text value with the default CHARACTER SET for this field.
* collation
* Text value with the default COLLATION for this field.
* @return string DBMS specific SQL code portion that should be used to
* declare the specified field.
*/
public function getDeclaration($name, $field) {
$default = '';
if(isset($field['default'])) {
if ($field['default'] === '') {
$field['default'] = empty($field['notnull'])
? null : $this->valid_default_values[$field['type']];
if ($field['default'] === ''
&& ($db->options['portability'] & Doctrine::PORTABILITY_EMPTY_TO_NULL)
) {
$field['default'] = ' ';
}
}
$default = ' DEFAULT ' . $this->conn->getDbh()->quote($field['default']);
}
return implode(', ', $query_fields);
/**
TODO: is this really needed for portability?
elseif(empty($field['notnull'])) {
$default = ' DEFAULT NULL';
}
*/
$charset = empty($field['charset']) ? '' :
' '.$this->getCharsetFieldDeclaration($field['charset']);
$collation = empty($field['collation']) ? '' :
' '.$this->getCollationFieldDeclaration($field['collation']);
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
$name = $this->conn->quoteIdentifier($name, true);
$method = 'get' . $field['type'] . 'Declaration';
if(method_exists($this->conn->dataDict, $method))
return $this->conn->dataDict->$method($name, $field);
else
$dec = $this->conn->dataDict->getNativeDeclaration($field);
return $name . ' ' . $dec . $charset . $default . $notnull . $collation;
}
/**
* Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param string $charset name of the charset
* @return string DBMS specific SQL code portion needed to set the CHARACTER SET
* of a field declaration.
*/
public function getCharsetFieldDeclaration($charset) {
return '';
}
/**
* Obtain DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration to be used in statements like CREATE TABLE.
*
* @param string $collation name of the collation
* @return string DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration.
*/
public function getCollationFieldDeclaration($collation) {
return '';
}
/**
* export
......
......@@ -92,10 +92,8 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
protected $pendingAggregates = array();
protected $aggregateMap = array();
protected $shortAliases = array();
protected $shortAliasIndexes = array();
protected $aliasHandler;
/**
* @var array $parts SQL query string parts
*/
......@@ -120,6 +118,7 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
$connection = Doctrine_Manager::getInstance()->getCurrentConnection();
$this->connection = $connection;
$this->aliasHandler = new Doctrine_Hydrate_Alias();
}
/**
* getComponentAliases
......@@ -235,8 +234,7 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
$this->joins = array();
$this->tableIndexes = array();
$this->tableAliases = array();
$this->shortAliases = array();
$this->shortAliasIndexes = array();
$this->aliasHandler->clear();
}
/**
* getConnection
......@@ -544,34 +542,14 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
return false;
}
public function getShortAliasIndex($alias) {
if( ! isset($this->shortAliasIndexes[$alias]))
return 0;
return $this->shortAliasIndexes[$alias];
return $this->aliasHandler->getShortAliasIndex($alias);
}
public function generateShortAlias($tableName) {
$char = strtolower(substr($tableName, 0, 1));
$alias = $char;
if( ! isset($this->shortAliasIndexes[$alias]))
$this->shortAliasIndexes[$alias] = 1;
while(isset($this->shortAliases[$alias])) {
$alias = $char . ++$this->shortAliasIndexes[$alias];
}
$this->shortAliases[$alias] = $tableName;
return $alias;
return $this->aliasHandler->generateShortAlias($tableName);
}
public function getShortAlias($tableName) {
$alias = array_search($tableName, $this->shortAliases);
if($alias !== false)
return $alias;
return $this->generateShortAlias($tableName);
return $this->aliasHandler->getShortAlias($tableName);
}
/**
* applyInheritance
......
......@@ -98,8 +98,8 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
Doctrine::ATTR_AUTO_TYPE_VLD => true,
Doctrine::ATTR_CREATE_TABLES => true,
Doctrine::ATTR_QUERY_LIMIT => Doctrine::LIMIT_RECORDS,
Doctrine::ATTR_IDXNAME_FORMAT => '%_idx',
Doctrine::ATTR_SEQNAME_FORMAT => '%_seq',
Doctrine::ATTR_IDXNAME_FORMAT => "%s_idx",
Doctrine::ATTR_SEQNAME_FORMAT => "%s_seq",
Doctrine::ATTR_QUOTE_IDENTIFIER => false,
Doctrine::ATTR_SEQCOL_NAME => 'id',
Doctrine::ATTR_PORTABILITY => Doctrine::PORTABILITY_ALL,
......
......@@ -343,8 +343,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$this->fetchModes = array();
$this->tableIndexes = array();
$this->tableAliases = array();
$this->shortAliases = array();
$this->shortAliasIndexes = array();
$this->aliasHandler->clear();
$class = "Doctrine_Query_".ucwords($name);
$parser = new $class($this);
......@@ -621,8 +620,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
if(strpos($part, "'") !== false)
continue;
if(isset($this->shortAliases[$part])) {
$parts[$k] = $this->generateNewAlias($part);
if($this->aliasHandler->hasAliasFor($part)) {
$parts[$k] = $this->aliasHandler->generateNewAlias($part);
}
if(strpos($part, '.') !== false) {
......@@ -631,7 +630,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$trimmed = ltrim($e[0], '( ');
$pos = strpos($e[0], $trimmed);
$e[0] = substr($e[0], 0, $pos) . $this->generateNewAlias($trimmed);
$e[0] = substr($e[0], 0, $pos) . $this->aliasHandler->generateNewAlias($trimmed);
$parts[$k] = implode('.', $e);
}
}
......@@ -639,7 +638,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
return $subquery;
}
/**
public function generateNewAlias($alias) {
if(isset($this->shortAliases[$alias])) {
// generate a new alias
......@@ -656,6 +655,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
return $alias;
}
*/
......
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