Commit
query object instead to each individual expression. This make unit testing easier for both the core and in userland, also simplifies some routines by making them more explicit and profits from a small performance gain.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,9 @@ | |
*/ | ||
namespace Cake\Database\Expression; | ||
|
||
use Cake\Database\ExpressionInterface; | ||
use Cake\Database\ValueBinder; | ||
|
||
class OrderByExpression extends QueryExpression { | ||
|
||
/** | ||
|
@@ -33,11 +36,15 @@ public function __construct($conditions = [], $types = [], $conjunction = '') { | |
/** | ||
* Convert the expression into a SQL fragment. | ||
* | ||
* @param Cake\Database\ValueBinder $generator Placeholder generator object | ||
* @return string | ||
*/ | ||
public function sql() { | ||
public function sql(ValueBinder $generator) { | ||
$order = []; | ||
foreach ($this->_conditions as $k => $direction) { | ||
if ($direction instanceof ExpressionInterface) { | ||
$direction = $direction->sql($generator); | ||
} | ||
$order[] = is_numeric($k) ? $direction : sprintf('%s %s', $k, $direction); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
lorenzo
Author
Member
|
||
} | ||
return sprintf('ORDER BY %s', implode(', ', $order)); | ||
|
4 comments
on commit fb3b540
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without reading all code and considerations, why drop the __toString() interface??
IMO
(string)$someObject;
Is a LOT cleaner than calling $someObject->sql(ValueBinder)
every time a string representation is required.
The additional if (InstanceOf ExpressionInterface)
checks in various parts makes the code a lot more messy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because there is no need to stringify an expression directly. Casting a query to an expression is still possible without Using a bumser. Having more type checks made the code a lot more explicit in what it is doing, but I think the other approach involved a lot of magic that was hard to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to trickle down to the not-so-strict approach in CakePHP in 'what' type of arguments and return-types are used throughout the framework (e.g. params can either be an 'array', 'string', 'bool' or 'null'). To be honest, I'm kinda hoping CakePHP 3 (being a major overhaul), will become more strict in this regard. This will save a lot of type-checking/casting during development and (hopefully) leads to cleaner, more readable code. In this example, to only accept ExpressionInterface inside '_conditions' etc.
I've been developing with CakePHP since version 1.1(? .. first non-beta release), so taking CakePHP to 'the next level' is something I hope will be realised.
I do want to help/assist/brain-storm if time is on my hand (busy job), but don't want to be like a "bull in a china shop", because I don't know what discussions/principles/considerations have been made before some code was written. What is the best location to get 'in the loop' and/or discuss things? (Google+ group, GitHub, Lighthouse?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately php does not support method overloading, so accepting multiple types in the same function implementation is the only way of providing any sort of "pattern matching". Pattern matching is good since it allows developers to be both expressive and relaxed in the way they code which is an aspect of CakePHP that I would like to keep.
Quite the contrary happens when you only accept one type of argument, you would need to cast, wrap or alter your values before they are passed to the method. One example of this is the Hash
class, in the past Set
used to accept whatever you passed to it, hence it was possible to iterate over any traversable. With the change to hash, which is stricter in its typing, is just impossible.
A very elegant way of solving such problem is to have a Maybe
type, but since functional programming is so foreign to the way we do php, I'd rather not go that way :P
In particular _conditions cannot accept ExpressionInterface as its only param type because people can write string expressions and wrapping everything inside another expression (I mean, everything!) it's in our minds a bit overkill, but we might be wrong about it.
The best place to discuss is this group: https://groups.google.com/forum/#!forum/cakephp-core
Wondering; would
is_int()
be a better approach here?is_numeric()
Also accepts, floats, hexadecimal etc, so including string starting with 0x or 0b