Re: performQuery generics

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Sun Jan 13 2008 - 09:32:38 EST

  • Next message: Michael Gentry: "Re: Logging changes?"

    Since there was a clear dissatisfaction with all suggested solutions,
    I kept trying other options. Here is one more attempt. I ditched both
    ideas - to subclass existing queries and to implement Query wrappers
    that are not queries themselves. Instead I combined functionality of
    the existing queries and a user-friendly wrapper in single new class
    that is itself a Query. As a result there's no backwards compatibility
    issues allowing for the tight and clean API.

    1. an example of usage... Notice that DataRows/Persistent/Generic
    objects are all handled by the same query class:

    Select<Artist> query1 = new Select<Artist>(Artist.class);
    query1.andQualifier("artistName = 'ABC'")
          .orQualifier("artistName = 'XYZ'")
          .orderAscending(Artist.ARTIST_NAME_PROPERTY);
    List<Artist> artists = context.performQuery(query1);

    Select<DataRow> query2 = new Select<DataRow>(DataRow.class, "Artist");
    query2.andQualifier("artistName = 'ABC'")
          .orQualifier("artistName = 'XYZ'")
          .orderAscending(Artist.ARTIST_NAME_PROPERTY);
    List<DataRow> dataRows = context.performQuery(query2);

    2. here is an implementation draft... Omitted are SQLSelect,
    NamedSelect, and ProcedureSelect. Also I think at the end "Select"
    will be based internally on EJBQLQuery, not SelectQuery, as it has a
    number of extra capabilities...

    interface TypedQuery<T> extends Query {

    }

    interface ObjectContext {
       List<T> performQuery(TypedQuery<T> query);
    }

    public class Select<T> implements TypedQuery<T> {

            protected SelectQuery delegateQuery;

            public Select(Class<T> rootClass) {
                    this.delegateQuery = new SelectQuery(rootClass);
            }

            public Select(Class<T> rootClass, String entityName) {

                    if (entityName == null) {
                            this.delegateQuery = new SelectQuery(rootClass);
                    } else {
                            this.delegateQuery = new SelectQuery(entityName);

                            if (rootClass.isAssignableFrom(DataRow.class)) {
                                    delegateQuery.setFetchingDataRows(true);
                            }
                    }
            }

            public Select<T> andQualifier(Expression qualifier) {
                    delegateQuery.andQualifier(qualifier);
                    return this;
            }

            public Select<T> andQualifier(String qualifier) {
                    delegateQuery.andQualifier(Expression.fromString(qualifier));
                    return this;
            }

            public Select<T> orQualifier(Expression qualifier) {
                    delegateQuery.orQualifier(qualifier);
                    return this;
            }

            public Select<T> orQualifier(String qualifier) {
                    delegateQuery.orQualifier(Expression.fromString(qualifier));
                    return this;
            }

            public Select<T> orderAscending(String ordering) {
                    delegateQuery.addOrdering(ordering, Ordering.ASC);
                    return this;
            }

            public Select<T> orderDesending(String ordering) {
                    delegateQuery.addOrdering(ordering, Ordering.DESC);
                    return this;
            }

            // other methods follow here...
    }

    3. What I haven't done yet is applying this to the new List<Object[]>
    results, as the backend is not fully ready yet, and I need a better
    understanding of all consequences myself.

    So ... does the above sound acceptable, or are there still reservations?

    Andrus



    This archive was generated by hypermail 2.0.0 : Sun Jan 13 2008 - 09:33:10 EST