Skip to content
Permalink
Browse files

Ghetto automatic identifier quoting, lots of broken tests but the idea

works :)
  • Loading branch information...
lorenzo committed Nov 4, 2013
1 parent 578add2 commit d1c3f57287d98c5e0b7458694b6ebb3c31ed8b9b
@@ -17,6 +17,7 @@
namespace Cake\Database\Dialect;
use Cake\Database\Expression\FunctionExpression;
use Cake\Database\Expression\Comparison;
use Cake\Database\Expression\OrderByExpression;
use Cake\Database\Expression\UnaryExpression;
use Cake\Database\Query;
@@ -45,13 +46,12 @@ trait PostgresDialectTrait {
protected $_endQuote = '"';
/**
* Returns a query that has been transformed to the specific SQL dialect
* by changing or re-arranging SQL clauses as required.
* Distinct clause needs no transformation
*
* @param Cake\Database\Query $query
* @return Cake\Database\Query
* @param Query $query The query to be transformed
* @return Query
*/
protected function _selectQueryTranslator($query) {
protected function _transformDistinct($query) {
return $query;
}
@@ -78,10 +78,27 @@ protected function _insertQueryTranslator($query) {
protected function _expressionTranslators() {
$namespace = 'Cake\Database\Expression';
return [
$namespace . '\Comparison' => '_transformComparison',
$namespace . '\UnaryExpression' => '_transformUnary',
$namespace . '\FunctionExpression' => '_transformFunctionExpression'
];
}
protected function _transformComparison(Comparison $expression) {
$field = $expression->getField();
if (is_string($field)) {
$expression->field($this->quoteIdentifier($field));
}
}
protected function _transformUnary(UnaryExpression $expression) {
$expression->iterateParts(function($part) {
if (is_string($part)) {
return $this->quoteIdentifier($part);
}
});
}
/**
* Receives a FunctionExpression and changes it so that it conforms to this
* SQL dialect.
@@ -54,7 +54,7 @@ class Comparison extends QueryExpression {
* @param string $field the field name to compare to a value
* @param mixed $value the value to be used in comparison
* @param string $type the type name used to cast the value
* @param string $conjuntion the operator used for comparing field and value
* @param string $conjunction the operator used for comparing field and value
* @return void
*/
public function __construct($field, $value, $type, $conjuntion) {
@@ -359,7 +359,7 @@ public function traverse(callable $callable) {
*/
public function iterateParts(callable $callable) {
$parts = [];
foreach ($this->_conditions as $c) {
foreach ($this->_conditions as $k => $c) {
$part = $callable($c);
if ($part !== null) {
$parts[] = $part;
@@ -515,7 +515,7 @@ protected function _buildFromPart($parts, $generator) {
$parts = $this->_stringifyExpressions($parts, $generator);
foreach ($parts as $k => $p) {
if (!is_numeric($k)) {
$p = $p . ' AS ' . $driver->quoteIdentifier($k);
$p = $p . ' AS ' . $k;
}
$normalized[] = $p;
}
@@ -107,11 +107,47 @@ protected function _expressionTranslators() {
* @return Query The modified query
*/
protected function _selectQueryTranslator($query) {
$query = $this->_transformDistinct($query);
$part = $query->clause('select');
$result = [];
foreach ((array)$part as $alias => $value) {
$value = !is_string($value) ? $value : $this->quoteIdentifier($value);
$result[$alias] = $value;
}
$query->select($result, true);
$part = $query->clause('from');
$result = [];
foreach ((array)$part as $alias => $value) {
$alias = is_numeric($alias) ? $alias : $this->quoteIdentifier($alias);
$result[$alias] = $value;
}
$query->from($result, true);
$part = $query->clause('join');
$result = [];
foreach ((array)$part as $value) {
$alias = empty($value['alias']) ? null : $this->quoteIdentifier($value['alias']);
$value['alias'] = $alias;
$result[$alias] = $value;
}
$query->join($result, [], true);
return $query;
}
/**
* Returns the passed query after rewriting the DISTINCT clause, so that drivers
* that do not support the "ON" part can provide the actual way it should be done
*
* @param Query $query The query to be transformed
* @return Query
*/
protected function _transformDistinct($query) {
if (is_array($query->clause('distinct'))) {
$query->group($query->clause('distinct'), true);
$query->distinct(false);
}
return $query;
}
@@ -16,6 +16,8 @@
*/
namespace Cake\ORM\Association;
use Cake\Database\Expression\Comparison;
use Cake\Database\Expression\UnaryExpression;
use Cake\ORM\Association;
use Cake\ORM\Entity;
use Cake\ORM\Query;
@@ -71,15 +73,20 @@ public function cascadeDelete(Entity $entity, $options = []) {
* clause for getting the results on the target table.
*
* @param array $options list of options passed to attachTo method
* @return string|array
* @return boolean|QueryExpression
*/
protected function _joinCondition(array $options) {
return sprintf('%s.%s = %s.%s',
$this->target()->alias(),
$this->_targetTable->primaryKey(),
$this->_sourceTable->alias(),
$options['foreignKey']
);
$field = sprintf(
'%s.%s',
$this->target()->alias(),
$this->_targetTable->primaryKey()
);
$value = new UnaryExpression(sprintf(
'%s.%s',
$this->_sourceTable->alias(),
$options['foreignKey']
), [], '');
return new Comparison($field, $value, 'string', '=');
}
}
@@ -16,6 +16,8 @@
*/
namespace Cake\ORM\Association;
use Cake\Database\Expression\Comparison;
use Cake\Database\Expression\UnaryExpression;
use Cake\ORM\Query;
use Cake\Utility\Inflector;
@@ -121,12 +123,17 @@ public function transformRow($row) {
* @return string|array
*/
protected function _joinCondition(array $options) {
return sprintf('%s.%s = %s.%s',
$this->_sourceTable->alias(),
$this->_sourceTable->primaryKey(),
$this->_targetTable->alias(),
$options['foreignKey']
);
$field = sprintf(
'%s.%s',
$this->_sourceTable->alias(),
$this->_sourceTable->primaryKey()
);
$value = new UnaryExpression(sprintf(
'%s.%s',
$this->_targetTable->alias(),
$options['foreignKey']
), [], '');
return new Comparison($field, $value, 'string', '=');
}
/**
@@ -18,6 +18,7 @@
use Cake\Core\Configure;
use Cake\Database\ConnectionManager;
use Cake\Database\Expression\QueryExpression;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
@@ -580,7 +581,7 @@ public function testFindListNoHydration() {
$this->assertSame($expected, $query->toArray());
$query = $table->find('list', ['groupField' => 'odd'])
->select(['id', 'username', 'odd' => 'id % 2 = 0'])
->select(['id', 'username', 'odd' => new QueryExpression('id % 2 = 0')])
->hydrate(false)
->order('id');
$expected = [
@@ -763,7 +764,7 @@ public function testFindListHydrated() {
$this->assertSame($expected, $query->toArray());
$query = $table->find('list', ['groupField' => 'odd'])
->select(['id', 'username', 'odd' => 'id % 2 = 0'])
->select(['id', 'username', 'odd' => new QueryExpression('id % 2 = 0')])
->hydrate(true)
->order('id');
$expected = [

0 comments on commit d1c3f57

Please sign in to comment.
You can’t perform that action at this time.