Hi Andy

On Thu, Feb 3, 2011 at 9:31 AM, Andrzej Michalec <andrzej.micha...@gmail.com
> wrote:

>
> I could not reply earlier, Sergey knows I am (still) attending to my
> company's internal event ;)
>

thanks for finding the time to reply,


> Just couple first thoughts on the subject.
>
> The FIQL that we suport is quite simple and basically is about comparing
> properties of given entity with constant values and then combine these
> simple boolean results with conjuntions/disjunctions. From fluent interface
> perspective simple expression could be like this:
>
> SeachConditionBuilder.query(new Book()).is("title").matching("The
> Lord*").build();
>

nice, may be even matching("The Lord") because 'matching' probably means a
partial match, we can also have equalTo, similar to lessThan/etc.

However, I'd just do
SeachConditionBuilder.instance().is("title").matching("The Lord*").build();

because I'd consider

SeachConditionBuilder.instance().query(new Book())

is a shorter expression involving all the book properties:

SeachConditionBuilder.instance().is("title").equalTo("The
Lord").is("id").equalTo(123);

Effectively the Book captures the 'user input' so the builder would check
the name of all the properties and also get all the values...

SeachConditionBuilder.query(new Book()).is("price").lessThan(20).build();
> SeachConditionBuilder.query(new Book()).is("issueDate").before(new
> Date(...)).build();
>
> where query() method is factory producing builder instance, is() is
> property
> resolver, plus rightmost set of comparators.
>

I see. I'm not sure though about using Book.class to get a builder. The
builder is really a little helper which can let users convert a captured
query state into the FIQL/etc language...In other words,

SeachConditionBuilder.newInstance().is("price").lessThan(20).build();

can easily generate 'price=lt=20' without knowing about Book.class :-).


> Of course naming of methods is a question of further tuning.
>
> For same level junctions and()/or() methods can be mixed in a flux of
> sentence like this:
>
> SeachConditionBuilder.query(new
> Book()).is("price").lessThan(20).and().is("issueDate").before(new
> Date(...)).build();
>
> nice again, having type aware methods like 'before'


> For multiple junctions we need to apply default precedence (first ANDs then
> ORs) and we can do this similar way as in parser; it increases a bit
> complexity of builder but can be done pretty easy.
>

I also propose making and() optional, if that is feasible


> In case of non default precedence, like "(A or B or C) and D" we need
> notion
> of parenthesis. I have seen similar discussion on nesting expressions in
> flunece interfaces
> (see
>
> http://groups.google.com/group/morphia/browse_thread/thread/61d1a05ec5d0de6b?pli=1
> ).
> I would avoid in-flow parenthesis like this:
>
> query(...).openParen()...or()...closeParen().and()...
>
> and break flow of expressions into sections like this:
>
> Criteria c = SeachConditionBuilder.query(new Book());
> c.and(
>  c.is("price").lessThan(20).or().is("price").greaterThan(50),
>  c.is("issueDate").before(new Date(...))
> ).build();
>
> or equivalent:
>
> c.and(
>  c.or(
>    c.is("price").lessThan(20),
>    c.is("price").greaterThan(50) ),
>  c.is("issueDate").before(new Date(...))
> ).build();
>
>
sure, +1


>
> As you can see in opposite to Sergey's proposition on
> single-string-comparisons (i.e. "price < 20") I vote for fine-grained
> decomposition... if we want to have these kind of stringified expressions I
> guess we should go into full user-friendly parser to handle above complex
> expression as it goes: "(price<20 or price>50) and issueDate<2010-01..."
>
> I'd have no problems with dropping an idea of "price < 20". But the reason
I proposed it was that I was not quite sure
how the transition between the phase of collecting the user input to the
actual coding stage will work in practice. For example, what the the actual
user facing form would look like and how easy would it be to code such a
transition.

I really like the fine-grained decomposition idea. I think users would
especially enjoy using for testing. But in the real application one would
probably need to do :

builder.is(getNameOfTheField());

String value = getValueOfTheField();
// something like
if (theFieldOperator == '>') {
    builder.lessThan(value);
} else {
    builder.greaterThan(value);
}

So I was thinking that the user just gets the "a > b" literal value
(assuming a form lets users type them)  and just passes it to the builder
and as I was commenting, the javadocs would clearly state that only
primitive literal expressions are supported. Even I can write the code
enforcing it :-). Likewise, the idea of supporting PrimitiveExpressions is
similar, one just passes 3 values, name, op and value (scraped from the
form) to the constructor.

May be we can consider supporting both types of building ? But really like
the things like is() + matching(), before(), etc. I guess the only concern
is that I'd use Book()/etc instances as shortcuts as opposed to factory
methods :-)

thanks, Sergey

all comments are welcome
>
> cheers,
> -andy.
> --
>

Reply via email to