fixed identifier quoting
This commit is contained in:
parent
7cfbd7481b
commit
56768b613f
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user