1
0
mirror of synced 2025-01-18 06:21:40 +03:00

fixed identifier quoting

This commit is contained in:
zYne 2007-07-06 20:55:15 +00:00
parent 7cfbd7481b
commit 56768b613f
7 changed files with 101 additions and 56 deletions

View File

@ -62,6 +62,16 @@ abstract class Doctrine_Configurable extends Doctrine_Object
*/
public function setAttribute($attribute,$value)
{
if (is_string($attribute)) {
$upper = strtoupper($attribute);
$const = 'Doctrine::ATTR_' . $attribute;
if (defined($const)) {
$this->_state = constant($const);
} else {
throw new Doctrine_Exception('Unknown attribute ' . $attribute);
}
}
switch ($attribute) {
case Doctrine::ATTR_FETCHMODE:
if ($value < 0) {

View File

@ -881,11 +881,13 @@ class Doctrine_Hydrate extends Doctrine_Object implements Serializable
foreach ($maps as $map) {
$b = array();
foreach ($map as $field => $value) {
$identifier = $this->_conn->quoteIdentifier($tableAlias . $field);
if ($index > 0) {
$b[] = '(' . $tableAlias . $field . ' = ' . $value
. ' OR ' . $tableAlias . $field . ' IS NULL)';
$b[] = '(' . $identifier . ' = ' . $value
. ' OR ' . $identifier . ' IS NULL)';
} else {
$b[] = $tableAlias . $field . ' = ' . $value;
$b[] = $identifier . ' = ' . $value;
}
}

View File

@ -368,7 +368,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
foreach ($fields as $name) {
$name = $table->getColumnName($name);
$this->parts['select'][] = $tableAlias . '.' .$name . ' AS ' . $tableAlias . '__' . $name;
$this->parts['select'][] = $this->_conn->quoteIdentifier($tableAlias . '.' . $name)
. ' AS '
. $this->_conn->quoteIdentifier($tableAlias . '__' . $name);
}
$this->neededTables[] = $tableAlias;
@ -520,7 +522,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$sqlAlias = $tableAlias . '__' . count($this->aggregateMap);
$this->parts['select'][] = '(' . $sql . ') AS ' . $sqlAlias;
$this->parts['select'][] = '(' . $sql . ') AS ' . $this->_conn->quoteIdentifier($sqlAlias);
$this->aggregateMap[$alias] = $sqlAlias;
$this->_aliasMap[$componentAlias]['agg'][] = $alias;
@ -568,7 +570,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$tableAliases[$tableAlias] = true;
// build sql expression
$expression = str_replace($component, $tableAlias . '.' . $field, $expression);
$identifier = $this->_conn->quoteIdentifier($tableAlias . '.' . $field);
$expression = str_replace($component, $identifier, $expression);
}
}
@ -578,7 +582,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
}
$index = count($this->aggregateMap);
$sqlAlias = $tableAlias . '__' . $index;
$sqlAlias = $this->_conn->quoteIdentifier($tableAlias . '__' . $index);
$this->parts['select'][] = $expression . ' AS ' . $sqlAlias;
@ -804,7 +808,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
// only append the subquery if it actually contains something
if ($subquery !== '') {
array_unshift($this->parts['where'], $field. ' IN (' . $subquery . ')');
array_unshift($this->parts['where'], $this->_conn->quoteIdentifier($field) . ' IN (' . $subquery . ')');
}
$modifyLimit = false;
@ -853,7 +857,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$primaryKey = $alias . '.' . $table->getIdentifier();
// initialize the base of the subquery
$subquery = 'SELECT DISTINCT ' . $primaryKey;
$subquery = 'SELECT DISTINCT ' . $this->_conn->quoteIdentifier($primaryKey);
$driverName = $this->_conn->getAttribute(Doctrine::ATTR_DRIVER_NAME);
@ -917,14 +921,16 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$subquery = $this->_conn->modifyLimitQuery($subquery, $this->parts['limit'], $this->parts['offset']);
$parts = Doctrine_Tokenizer::quoteExplode($subquery, ' ', "'", "'");
//print_r($parts);
foreach ($parts as $k => $part) {
if (strpos($part, "'") !== false) {
if (strpos($part, ' ') !== false) {
continue;
}
$part = trim($part, "\"'`");
if ($this->hasTableAlias($part)) {
$parts[$k] = $this->generateNewTableAlias($part);
$parts[$k] = $this->_conn->quoteIdentifier($this->generateNewTableAlias($part));
continue;
}
@ -1153,8 +1159,13 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$localAlias = $this->getTableAlias($parent, $table->getTableName());
$foreignAlias = $this->getTableAlias($componentAlias, $relation->getTable()->getTableName());
$localSql = $this->_conn->quoteIdentifier($table->getTableName()) . ' ' . $localAlias;
$foreignSql = $this->_conn->quoteIdentifier($relation->getTable()->getTableName()) . ' ' . $foreignAlias;
$localSql = $this->_conn->quoteIdentifier($table->getTableName())
. ' '
. $this->_conn->quoteIdentifier($localAlias);
$foreignSql = $this->_conn->quoteIdentifier($relation->getTable()->getTableName())
. ' '
. $this->_conn->quoteIdentifier($foreignAlias);
$map = $relation->getTable()->inheritanceMap;
@ -1192,22 +1203,29 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
if ($relation->isEqual()) {
$queryPart .= '(';
}
$queryPart .= $foreignAlias . '.'
. $relation->getTable()->getIdentifier() . ' = '
. $assocAlias . '.' . $relation->getForeign();
$queryPart .= $this->_conn->quoteIdentifier($foreignAlias . '.' . $relation->getTable()->getIdentifier())
. ' = '
. $this->_conn->quoteIdentifier($assocAlias . '.' . $relation->getForeign());
if ($relation->isEqual()) {
$queryPart .= ' OR ' . $foreignAlias . '.' . $table->getIdentifier()
. ' = ' . $assocAlias . '.' . $relation->getLocal()
. ') AND ' . $foreignAlias . '.' . $table->getIdentifier()
. ' != ' . $localAlias . '.' . $table->getIdentifier();
$queryPart .= ' OR '
. $this->_conn->quoteIdentifier($foreignAlias . '.' . $table->getIdentifier())
. ' = '
. $this->_conn->quoteIdentifier($assocAlias . '.' . $relation->getLocal())
. ') AND '
. $this->_conn->quoteIdentifier($foreignAlias . '.' . $table->getIdentifier())
. ' != '
. $this->_conn->quoteIdentifier($localAlias . '.' . $table->getIdentifier());
}
} else {
$queryPart = $join . $foreignSql
. ' ON ' . $localAlias . '.'
. $relation->getLocal() . ' = ' . $foreignAlias . '.' . $relation->getForeign();
. ' ON '
. $this->_conn->quoteIdentifier($localAlias . '.' . $relation->getLocal())
. ' = '
. $this->_conn->quoteIdentifier($foreignAlias . '.' . $relation->getForeign());
}
$this->parts['from'][$componentAlias] = $queryPart;
if ( ! empty($joinCondition)) {
@ -1262,7 +1280,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$queryPart = $this->_conn->quoteIdentifier($tableName);
if ($this->type === self::SELECT) {
$queryPart .= ' ' . $tableAlias;
$queryPart .= ' ' . $this->_conn->quoteIdentifier($tableAlias);
}
$this->parts['from'][] = $queryPart;

View File

@ -42,6 +42,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
public function load($where)
{
$where = trim($where);
$conn = $this->query->getConnection();
$e = Doctrine_Tokenizer::sqlExplode($where);
@ -107,9 +108,9 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
}
$where = array();
foreach ($values as $value) {
$where[] = $alias . '.' . $relation->getLocal()
. ' IN (SELECT '.$relation->getForeign()
. ' FROM ' . $relation->getTable()->getTableName()
$where[] = $conn->quoteIdentifier($alias . '.' . $relation->getLocal())
. ' IN (SELECT ' . $conn->quoteIdentifier($relation->getForeign())
. ' FROM ' . $conn->quoteIdentifier($relation->getTable()->getTableName())
. ' WHERE ' . $field . $operator . $value . ')';
}
$where = implode(' AND ', $where);
@ -180,7 +181,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
default:
if ($this->query->getType() === Doctrine_Query::SELECT) {
$fieldname = $alias ? $alias . '.' . $field : $field;
$fieldname = $alias ? $conn->quoteIdentifier($alias . '.' . $field) : $field;
} else {
$fieldname = $field;
}

View File

@ -578,16 +578,11 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
} elseif (is_string($state)) {
$upper = strtoupper($state);
switch ($upper) {
case 'DIRTY':
case 'CLEAN':
case 'TDIRTY':
case 'TCLEAN':
case 'PROXY':
case 'DELETED':
$this->_state = constant('Doctrine_Record::STATE_' . $upper);
break;
default:
$const = 'Doctrine_Record::STATE_' . $upper;
if (defined($const)) {
$this->_state = constant($const);
} else {
$err = true;
}
}

View File

@ -33,33 +33,52 @@
* @since 1.0
* @version $Revision$
*/
class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase {
public function prepareTables() { }
public function prepareData() { }
public function testQuerySupportsIdentifierQuoting() {
class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase
{
public function prepareTables()
{ }
public function prepareData()
{ }
public function testQuerySupportsIdentifierQuoting()
{
$this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true);
$q = new Doctrine_Query();
$q->parseQuery('SELECT MAX(u.id), MIN(u.name) FROM User u');
$this->assertEqual($q->getQuery(), 'SELECT MAX(e.id) AS e__0, MIN(e.name) AS e__1 FROM "entity" e WHERE (e.type = 0)');
$this->assertEqual($q->getQuery(), 'SELECT MAX("e.id") AS "e__0", MIN("e.name") AS "e__1" FROM "entity" "e" WHERE ("e.type" = 0)');
}
public function testQuerySupportsIdentifierQuotingWithJoins() {
public function testQuerySupportsIdentifierQuotingInWherePart()
{
$q = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u WHERE u.id = 3');
$this->assertEqual($q->getQuery(), 'SELECT "e.id" AS "e__id", "e.name" AS "e__name" FROM "entity" "e" WHERE "e.id" = 3 AND ("e.type" = 0)');
}
public function testQuerySupportsIdentifierQuotingWithJoins()
{
$q = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p');
$this->assertEqual($q->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM "entity" e LEFT JOIN "phonenumber" p ON e.id = p.entity_id WHERE (e.type = 0)');
$this->assertEqual($q->getQuery(), 'SELECT "e.id" AS "e__id", "e.name" AS "e__name" FROM "entity" "e" LEFT JOIN "phonenumber" "p" ON "e.id" = "p.entity_id" WHERE ("e.type" = 0)');
}
public function testLimitSubqueryAlgorithmSupportsIdentifierQuoting() {
public function testLimitSubqueryAlgorithmSupportsIdentifierQuoting()
{
$q = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u INNER JOIN u.Phonenumber p')->limit(5);
$this->assertEqual($q->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM "entity" e INNER JOIN "phonenumber" p ON e.id = p.entity_id WHERE e.id IN (SELECT DISTINCT e2.id FROM "entity" e2 INNER JOIN "phonenumber" p2 ON e2.id = p2.entity_id WHERE (e2.type = 0) LIMIT 5) AND (e.type = 0)');
$this->assertEqual($q->getQuery(), 'SELECT "e.id" AS "e__id", "e.name" AS "e__name" FROM "entity" "e" INNER JOIN "phonenumber" "p" ON "e.id" = "p.entity_id" WHERE "e.id" IN (SELECT DISTINCT "e2.id" FROM "entity" "e2" INNER JOIN "phonenumber" "p2" ON "e2.id" = "p2.entity_id" WHERE ("e2.type" = 0) LIMIT 5) AND ("e.type" = 0)');
$this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false);
}