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

@ -388,7 +388,7 @@ final class Doctrine
*/ */
public static function getPath() public static function getPath()
{ {
if (! self::$path) { if ( ! self::$path) {
self::$path = dirname(__FILE__); self::$path = dirname(__FILE__);
} }
return self::$path; return self::$path;

View File

@ -62,6 +62,16 @@ abstract class Doctrine_Configurable extends Doctrine_Object
*/ */
public function setAttribute($attribute,$value) 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) { switch ($attribute) {
case Doctrine::ATTR_FETCHMODE: case Doctrine::ATTR_FETCHMODE:
if ($value < 0) { if ($value < 0) {

View File

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

View File

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

View File

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

View File

@ -33,34 +33,53 @@
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
*/ */
class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase { class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase
public function prepareTables() { } {
public function prepareData() { } public function prepareTables()
public function testQuerySupportsIdentifierQuoting() { { }
public function prepareData()
{ }
public function testQuerySupportsIdentifierQuoting()
{
$this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true);
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->parseQuery('SELECT MAX(u.id), MIN(u.name) FROM User u'); $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 = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); $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 = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u INNER JOIN u.Phonenumber p')->limit(5); $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); $this->conn->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, false);
} }
} }