Re: Type-safe qualifiers

From: Aristedes Maniatis (ar..aniatis.org)
Date: Thu Dec 31 2009 - 00:13:11 EST

  • Next message: Andrus Adamchik: "Re: Type-safe qualifiers (and queries)"

    On 31/12/09 6:59 AM, Andrus Adamchik wrote:
    > While there's lots of things we need to figure out to create generified
    > queries, here is one low-hanging fruit - type-safe qualifiers. The idea
    > is borrowed from the WebObjects EOF extensions framework called Wonder:
    >
    > http://webobjects.mdimension.com/hudson/job/Wonder53/javadoc/er/extensions/eof/ERXKey.html
    >
    >
    > The way it works, is that for each String property in a Persistent
    > object, we generate an extra parameterized "key". E.g.:
    >
    > public class _Artist extends CayenneDataObject {
    >
    > public static final String DATE_OF_BIRTH_PROPERTY = "dateOfBirth";
    > public static final Key<Date> DATE_OF_BIRTH = new Key<Date>(
    > DATE_OF_BIRTH_PROPERTY);

    What a shame String is final, so Key can't just extend String. Oh well.

    In the long term, perhaps the old property will go away, so perhaps this is a better first step:

       public static final Key<Date> DATE_OF_BIRTH = new Key<Date>("dateOfBirth");

      ..eprecated
       public static final String DATE_OF_BIRTH_PROPERTY = DATE_OF_BIRTH.toString();

    How does Key relate to Attribute and Relationship? Is it an interface that both implement?

    > 2. New API:
    >
    > Expression clause1 = Artist.NAME.eq("X");
    > Expression clause2 = Artist.PAINTINGS.dot(Painting.NAME).eq("Y");

    Would this be more in keeping with existing usage:

       Artist.PAINTINGS.join(Painting.NAME).match("Y");

    and

       Artist.PAINTINGS.outerJoin(Painting.NAME).match("Y");

    to emulate the "|" we have now.

    > Expression clause3 = Artist.PAINTINGS.dot(Painting.NAME).eq("Z");
    > Expression clause4 = Artist.PAINTINGS.dot(Painting.NAME).eq("A");
    >
    > Expression qualifier = Each.get(clause1, Any.get(clause2, clause3,
    > clause4));
    >
    > As you see the new API is much tighter, and the first part of it is
    > completely type-safe (generated "keys" ensure that we are matching
    > against the right type of value, even in a multi-step path).

    At first glance Artist.PAINTINGS looks like it should be <Collection<Painting>>. But that breaks the type-safeness. We can tell when a key represents a Relationship (<? extends PersistentObject>) rather than an Attribute. But would we ever want to know when it represents a to-many relation rather than a to-one?

    > The last
    > line uses 2 new Expression factories, "Each" and "Any", to quickly
    > organize key-value expressions into a nested expression tree. I think
    > this is as good as it can get within the constraints of the Java syntax.

    Any and Each are a bit obscure. You aren't going to find them by reading the Javadoc for Expression. What do they give over the existing orExp/andExp syntax?

       Expression qualifier = Each.get(clause1, Any.get(clause2, clause3, clause4));

       Expression qualifier = clause1.andExp(clause2.orExp(clause3).orExp(clause4));

    Intuitively I don't equate "each" as meaning "all" or "and". Or even simpler:

       Expression qualifier = clause1.and(clause2.or(clause3).or(clause4));

    Ari

    -- 
    

    --------------------------> Aristedes Maniatis GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A



    This archive was generated by hypermail 2.0.0 : Thu Dec 31 2009 - 00:13:54 EST