>> I think it's acceptable to use var-arg for Expr::or, but there is no such thing as "OR between 3 variables". OR is a binary operator, and the order in which conditions are evaluated is significant.
OR is a binary operator, but in "pure" functions (ones that have no
sideffects) the evaluation order is irrelevant. And when you type in
an SQL query:
A or B or C or D
You certainly aren't thinking about the evaluation order, and if you
were, pointless, because a good query optimizer will likely choose
which one to evaluate first based on function evaluation statistics
and "type simplicity".
In any case, imho it's totally wrong to force programmers to write or
(A,or(B,or(C,D))). :)
As for you "who will be responsible" question, the programmer. That
will simply turn out to be an invalid query.
On 29 May, 15:41, Eugene Janusov <esy...@gmail.com> wrote:
> > In option #1, how would you go about doing an OR between 3 variables?
> > Would Expr::or accept a variable number of arguments?
> I think it's acceptable to use var-arg for Expr::or, but there is no
> such thing as "OR between 3 variables". OR is a binary operator, and
> the order in which conditions are evaluated is significant.
> > Also, although beginBlockIf would be a good shortcut, it's not
> > necessarily a good idea to reinvent the wheel and build into the DQL
> > API the equivalent to PHP's standard control structures such as
> > complex 'if'. Still, an equivalent to what Roman Borschel suggests in
> >http://pastie.org/493835would behttp://pastebin.com/d2f414d3e
> PHP's control structures are а matter of PHP's interpreter, and who
> will be responsible for such things:
Although I think that Jorge's approach looks very nice at the first glance, I don't think it is the way to go. As far as I have understood, the core team is trying to build an alternative, _object-oriented_ approach to writing conditional queries.
All other solutions except for #1 have a very nice interface, but you can only use this interface if you are building the query in one place (i.e. a method, function etc.). You cannot at all (or not very intuitively) build different parts of the query in different parts of your application, which seems to be what this alternative approach is all about.
The object oriented approach allows you to construct your query in a very modular fashion. The only big drawback with my above sample is that you have to mix the "normal" way of writing a query (aka ->where('m.attr1 = ?', 1)) with the object oriented way within the same method. A nicer way of writing this is
Well, as someone with both a functional and imperative programming
background, I must say that it looks very natural. :) It allows you to
build complex queries without interrupting the chain. I could point a
number of very successful libraries that take this approach inspired
by functional Monads, such as jQuery (which even has a ->foreach).
Still, whether you include control elements or not is a different
discussion. The relevant aspect here is that using #1 you drop the
natural order of building a query and force the programmer to nest
operations that in an SQL query are written in a linear manner. Case
in point:
(A or B or C or D) vs or(A, or(B, or(C,D)))
This also makes it very hard adding pieces of a query inside an "or".
I'm not sure how we could defend #1 given this, and it seems somewhat
obvious that an approach based on #4 is far easier to read and write.
If after making that decision you decide to include or not if/elseif
controls, that is another issue, but it's a very natural extension of
beginBlock/endBlock, and even if you don't like it you'll certainly
agree that it's very easy to read and write. In any case, you can
still write things by resorting only to php language constructs.
Regards,
On 29 May, 16:32, Eugene Janusov <esy...@gmail.com> wrote:
But in any case, I'll be glad with any suggestion that doesn't force
you to nest or/and. As a middleground between both approaches, I'd say
maybe consider the 2nd option here http://pastebin.com/d282b4be8,
which is basically
$q->orWhere( array(
Expr::eq('attr1', $value1),
Expr::or(),
Expr::eq('attr2', $value2)
) );
Regards,
On 30 May, 11:56, Bernhard Schussek <bschus...@gmail.com> wrote:
> Although I think that Jorge's approach looks very nice at the first
> glance, I don't think it is the way to go. As far as I have
> understood, the core team is trying to build an alternative,
> _object-oriented_ approach to writing conditional queries.
> All other solutions except for #1 have a very nice interface, but you
> can only use this interface if you are building the query in one place
> (i.e. a method, function etc.). You cannot at all (or not very
> intuitively) build different parts of the query in different parts of
> your application, which seems to be what this alternative approach is
> all about.
> The object oriented approach allows you to construct your query in a
> very modular fashion. The only big drawback with my above sample is
> that you have to mix the "normal" way of writing a query (aka
> ->where('m.attr1 = ?', 1)) with the object oriented way within the
> same method. A nicer way of writing this is
> The issue imho is that you loose all sense of order with that,
> compared to a standard query. If PHP allowed you to define functions
> as operators (eg, such as in Prolog or Lisp) it wouldn't be much of a
> problem.
is possible.
But given hardly no one uses the extension (based on the fact tinkered
with code to do the above over 3 years ago), and no sign of it being
included in default install, the idea is going nowhere.
The possibilities provided via the pastebin link are interesting and
bear, as far as I can see, a great deal of resemblance to the Criteria
API provided by Propel.
Propel's Criteria API is, insofar as I have worked with it, okay but
not great. Although it's flexible it's not very elegant.
At my workplace we use a web framework called QCubed (A fork of QCodo)
which provides, among other things, an ORM layer. The ORM layer
provided by QCubed is nowhere near as powerful or as flexible as that
provided by Doctrine, but the Query Building system (QQuery) is
actually pretty damn nice, even though it does lack certain features
(Slated for addition, but the QCubed community is moving slowly in
this regard)
Basically, QCubed Queries take the following form...
The code generation system for the QCubed framework does two things
with regards to ORM codegen:
1: It builds Row entity classes for each Table.
2: It builds Query Node classes for each Table, as well as Query Node
classes for the various relationships between the Tables.
As it is, QQuery is powerful, but lacks a lot of flexibility.
Nevertheless, I think it could provide something to look at.
As I see it the pros and cons of QQuery are as follows:
Pros:
Readable, Logical Query syntax
Query syntax essentially allows for OO-based SQL queries
QQNodes document database traversal nicely (I actually contributed
code to QCubed in this regard that generates PHPDoc comments for
QQNodes)
Cons:
No WHERE handling. QQuery does not allow you to select custom columns
and late-bind entity data as Doctrine does
No custom JOIN support. You may only join along direct relationships.
Multiple joins and custom joins are not supported.
Limited support for certain features such as nested selects custom
columns (As generated by usage of SQL functions such as count(), etc)
Somewhat verbose
Not directly chainable (Allow Conditions and Clauses can be generated
Ad-Hoc and stored in arrays for use with things like QQ::AndCondition
() and QQ::Clause()
As I see it, a query building system that draws on the strengths of
QQuery while also improving upon its failings would be a good place to
look.
That said, I also realise that there are flaws with the QQuery model
that could make certain things very hard (Handling of multiple and
custom joins for one...)