What if we put that bit of code in CayenneDataObject as a static method?
Then you could say something like:

Number count = Artist.numberOfRecordsInDatabase();

I suppose it could return an int, too.  I always get confused about
inheritance rules with static methods, though (would it know it was an
Artist instead of CayenneDataObject so it could look up the appropriate
table information?).  I'd have to go do a little test case.  (Strangely, I
know how it works in Objective-C.)

Another "interesting" thought is what about inheritance?  Could:

Number count = Manager.numberOfRecordsInDatabase();

automatically add the inheritance qualifier for the Manager object?

Thanks,

/dev/mrg


On 6/22/07, Andrus Adamchik <[EMAIL PROTECTED]> wrote:

Just added another JPA extension to Cayenne Classic - a mechanism to
return scalars from SQLTemplate. Let me demonstrate how this works.
Take a normal query execution example:

    List results = context.performQuery(query);

  * In Cayenne Classic each element in the "results" list is either a
Persistent or a DataRow.
  * In JPA each element is either a Persistent or a scalar (such as
java.lang.Integer), or an Object[] containing a mix of the previous
two types.

So the JPA difference is that (a) scalars are first-class citizens as
far as query result is concerned; (b) multiple scalar/objects per row
can be a part of the same result; [(c) no concept of DataRow, but
that's not relevant for this discussion].


So what I did now is adding support for scalars and arrays of scalars
to the "raw" queries. So now a count can be done as SQLTemplate in a
following manner:

    // a bit involved query construction procedure
    String sql = "SELECT count(1) AS C FROM ARTIST";
    SQLTemplate query = new SQLTemplate(Artist.class, sql);
    query.setColumnNamesCapitalization
(SQLTemplate.UPPERCASE_COLUMN_NAMES);

    SQLResultSetMapping rsMap = new SQLResultSetMapping();
    rsMap.addColumnResult("C");
    query.setResultSetMapping(rsMap);

    // very simple scalar result set retrieval
    Number count = (Number) DataObjectUtils.objectForQuery(context,
query);


We can hide SQLTemplate creation internals inside a CountQuery, but a
user can easily take care of result processing without extra utility
API (see the last line in the code above - no need to unwrap a Map or
anything).

Regarding the earlier concern that DataObjectUtils is dealing with
non-DataObjects, looks like a conceptual shift of "what a query
result is" solves that as well. Now we consider any
"java.lang.Object" a valid result, only some objects are persistent
and have identity, and others - do not. Comments?

Andrus


Reply via email to