Re: Shipping a build

[email protected] Sat, 01 Aug 2009 18:49:33 +1000
Newsgroups gmane.comp.java.orm.simpleorm
Message-ID <[email protected]>
Hello Franck,

You have been busy.  

You even implemented EntrySet for the Map, which I was not suggesting but it is good.  Should have a comment that it is inefficient -- creates the map each time (OK, just a documentation issue).  Likewise KeySet.  

get(Object x) -- if x is not String I would throw an exception rather than returning Null.  I am more interested in usage patterns than the strict definition of Map.  What do you think?

You are right to throw exceptions for put to new values, and remove etc.  It is just a view onto our data structure.

I would not have bothered with removing InvalidValues from the values().  But if you do so then should probably do it everywhere -- entrySet(), keySet().  size() is now inconsistent.  Common usage would be to display all valid field values in a table.  (But probably OK just to return fieldValues asList and forget about InvalidValues.   Size is just fieldValues.length.  But should be consistent.  size() should also be reasonably efficient.)

Is there a test case for the Map interface?

getDouble(field.getFieldName()) is a bit less efficient than I had in mind, string to array and back, but probably OK in practice.  Good to see the code uncopied.  (I would have created a private method convertDouble, and then called it from both getDouble methods.  Field level methods such as get* should be efficient.)

(You could have made SRecordGeneric an interface.  Then SRecordTransient could extend LinkedHashMap and implement SRecordGeneric.  convertDouble etc. just become package local static methods somewhere.  No matter.)

One test I would like to do is use the new map structure from a JSP.  Given that you have implemented entrySet() etc. it should work pretty well.  Later.

The final outstanding thing is to update the white paper.  My job.

Thanks very much for the work.  SimpleOrm is becoming quite elegant.

Anthony

At 05:18 AM 1/08/2009, you wrote:
>  
>
>On a second thought, it seemed much cleaner to throw
>UnsupportedOperationException on remove(), just like for clear(), and
>this is allowed by the spec. So I just did it.
>
>Franck
>
>Le vendredi 31 juillet 2009 à 21:05 +0200, Franck Routier a écrit :
>> 
>> Hello Anthony,
>> 
>> I finally commited my changes right now.
>> 
>> So, I created a new SRecordGeneric, an abstract class that implements
>> Map and has all the code related to casting fields values into
>> different
>> types.
>> There was a first problem here, because SRecordInstance and
>> (old)SRecordGeneric getLong methods where different: one was returning
>> long (and 0 for null), and the other one Long (and null for null).
>> Same
>> for getInt, etc.
>> I decided to stick to the SRecordInstance getLong (ie returning long
>> and
>> 0) as it was done to be consistent with jdbc, and is probably the most
>> used part of Simpleorm (SAggregateQuery is quite new).
>> Also I added a isNull() abstract method to (new) SRecordGeneric, to
>> make
>> the difference between 0 and null, etc.
>> 
>> A new class, SRecordTransient extends SRecordGeneric and is backed by
>> a
>> Map (through comosition). It replaces the (old) SRecordGeneric.
>> 
>> SRecordInstance extends SRecordGeneric and implements Map in its own
>> way, which was the trickiest part, since the semantics are quite
>> different:
>> - SRecordInstance has a predefined number of fields, which can be
>> already set or not.
>> - In a Map, either the key has a value, and then it exists, or it has
>> no
>> value and it doesn't exist.
>> 
>> So I made the choice to consider unquieried/unset fields has non
>> existing in the Map implementation of a SRecordInstance, especially
>> regarding the size(), containsKey(), isEmpty and values() methods.
>> 
>> This means that ri.size() will return the number of fields that are
>> valid, not getMeta().getAllFields().size().
>> ri.containsKey(key) will return true only if the field whose name is
>> key
>> has been set/queried (ie is valid).
>> 
>> Clear() is an UnsupportedOperation (as pk cannot be cleared).
>> 
>> Also the choice was made to implement the remove method as setNull(),
>> which is a bit weird, as it would be more coherent to implement it as
>> set to Invalid. But this has no meaning for a SRecordInstance...
>> (maybe
>> we should just throw UnsupportedOperationException...)
>> 
>> Also notice that values() return read-only data, although the Map API
>> assumes that they are directly backed by the Map and that changes on
>> one
>> side should be reflected on the other side, which is at least uneasy.
>> This is the only part where we don't fully adhere to the spec.
>> 
>> That said, I really think SRecordInstance is a pretty API compliant
>> implementation of java.util.Map :)
>> 
>> Of course I also renamed SAggregateQuery to SQueryTransient, copied
>> the
>> jar into my project, recompiled, renamed calls to queryAggregate into
>> queryTransient, SAggreagteQuery into SQueryTransient and it was about
>> all...
>> 
>> So the commit breaks a few things, but essentially renaming, and more
>> subtly the return type of SRecordGeneric.getLong, getInt, ... But this
>> should be manageable.
>> 
>> Hope this makes sense,
>> 
>> Franck
>> 
>> Le vendredi 31 juillet 2009 Ã  13:56 +1000, <mailto:anthony%40berglas.org>[email protected] a
>> écrit :
>> > 
>> > Hello Franck,
>> > 
>> > Sounds good.
>> > 
>> > I would like the copied code pushed up into SRecordGeneric as
>> private
>> > methods.
>> > 
>> > Pushing getString(String) up as abstracts should also be pretty easy
>> > -- for SRecordInstance it is something like
>> > getString(findField(String)). That makes the common super type more
>> > real.
>> > 
>> > I would also prefer to implement the easy and most useful methods in
>> > the Map interface, ie. get(), put(), containsKey() and size() and
>> > isEmpty(). I think that they would also be very easy. Other methods
>> > can just throw UnsupportedOperation.
>> > 
>> > <rant>
>> > The full Map interface is a bit painful because Java defines it
>> badly.
>> > It exposes the Entry object within the Map implementation, which is
>> > unnecessary and expensive if the maps are implemented differently
>> from
>> > HashMap. (They should be -- use odd and even entries of the array
>> for
>> > key and value, and then save an object per entry. New is expensive
>> at
>> > this level.) Who designed this stuff? I suppose I should be grateful
>> > that we can write map.get(key) instead of
>> > map.getEntries.get(key).getValue()!
>> > </rant>
>> > 
>> > And please implement rawSelect(String) (or similar name) to just
>> poke
>> > raw SQL as a select list. That makes it complete and is easy.
>> > 
>> > Regards,
>> > 
>> > Anthony
>> > 
>> > At 12:18 AM 31/07/2009, you wrote:
>> > > 
>> > >
>> > >Hello,
>> > >
>> > >so, I would go:
>> > >
>> > >SRecordGeneric as the base abstract class
>> > >SRecordInstance...
>> > >SRecordTransient for what is called SRecordGeneric now...
>> > >
>> > >I would also rename SAggregateQuery to SQueryTransient (to have a
>> > >consistent naming).
>> > >
>> > >And I would stop here for now, release, and see later.
>> > >
>> > >Do you agree with that ? If so, I could do the work tomorow.
>> > >
>> > >Franck
>> > >
>> > >Le jeudi 30 juillet 2009 Ã 20:57 +1000, <mailto:berglas%
>> > 40SpreadsheetDetective.com><mailto:berglas%40SpreadsheetDetective.com>[email protected]
>> > >a écrit :
>> > >> 
>> > >> Hello Franck,
>> > >> 
>> > >> Yes, I was thinking along similar lines after I posted. The
>> primary
>> > >> key is the big issue. (And having multiple queries with different
>> > >> select functions return the records with the same keys.)
>> > >> 
>> > >> Things I am now sure of are:-
>> > >> 
>> > >> 1. Doing the full job like I had proposed is too hard in the
>> short
>> > >> term. Things like optimistic values would require SFieldInstance
>> > >> objects -- we are going down a slippery path.
>> > >> 
>> > >> 2. SRecordInstance and SRecordGeneric (say) should share a common
>> > >> super type, and should implement Map. (The data conversion code
>> > should
>> > >> be uncopied.) One should be able to print a list of records (say)
>> > >> regardless of their type. (Incidentally, if you extend
>> > LinkedHashMap
>> > >> you do not also need to implement Map.) 
>> > >> 
>> > >> 3. I still think SRecordAggregate is not about aggregates. It is
>> > about
>> > >> arbitrary SQL queries that produce results that do not have
>> primary
>> > >> keys and cannot be added to a DataSet. It should have a method
>> > >> rawSelect(String clause). And later other methods to poke
>> arbitrary
>> > >> bits of SQL in. Maybe even Unions etc. And may want a rawSelect
>> and
>> > an
>> > >> aggregate function in the same query.
>> > >> 
>> > >> So I think maybe work along the lines that I had said were the
>> > wrong
>> > >> way.
>> > >> 
>> > >> Rename SQueryAggregate to SQuerySpecial (or maybe
>> > SQueryTransient?),
>> > >> which returns SRecordSpecial (or SRecordTransient...), which
>> extend
>> > >> SRecordSuper (or SRecordGeneric). 
>> > >> 
>> > >> It would be good if SRecordInstance also extended SRecordGeneric
>> > and
>> > >> implement the Map get methods, but by just looking up SFieldMetas
>> > and
>> > >> thence the values from the array. (No real map.) Easy and safe. I
>> > >> would prefer not to introduce SRecordSuper without
>> SRecordInstance
>> > >> extending it, makes SimpleOrm look clumsy.
>> > >> 
>> > >> Later, we should probably be able to specify an SFieldScaler as
>> an
>> > >> extra parameter to the query, so that we use JDBC to do type
>> > >> conversions consistently with SQuery.
>> > >> 
>> > >> (Hibernate just returns arrays of objects for ad hoc queries, or
>> > you
>> > >> can poke them in to a non-persisted class. Maps of objects are
>> much
>> > >> neater and easier.)
>> > >> 
>> > >> An outstanding issue is what if we want to query Departments +
>> > >> AVG(salary) later. Now we have aggregations in the SQuery. Would
>> > >> suggest that SQuery and SQueryAggregate should be combined, and
>> > maybe
>> > >> just having a null record type makes the difference. But I think
>> it
>> > is
>> > >> probably OK not to worry about this for now.
>> > >> 
>> > >> What do you think?
>> > >> 
>> > >> Regards,
>> > >> 
>> > >> Anthony
>> > >> 
>> > >> At 07:15 PM 29/07/2009, you wrote:
>> > >> > 
>> > >> >
>> > >> >Hi,
>> > >> >
>> > >> >there is a point I don't get... there are big differences
>> between
>> > >> >SRecordGeneric and SRecordInstance, that make me think it would
>> be
>> > >> hard
>> > >> >to unify them:
>> > >> >
>> > >> >SRecordInstance can be persisted,
>> > >> >SRecordInstance have a primary key and are guaranteed to be
>> unique
>> > >> >within a session/dataset,
>> > >> >SRecordInstance can have optimistic values, etc.
>> > >> >
>> > >> >On the other hand, SRecordGeneric are really read-only,
>> > >> >SRecordGeneric cannot be updated,
>> > >> >SRecordGeneric will be unique only per query result, not on a
>> > >> >transaction/dataset basis (they have no primary key).
>> > >> >
>> > >> >So I understand how it would be interesting to be able to add
>> > >> arbitrary
>> > >> >read-only fields to SRecordInstance as in you example (and make
>> it
>> > >> >implement Map or even backed by a Map), but I don't get how we
>> > could
>> > >> >pretend SRecordInstance and SRecordGeneric are the same beast...
>> > >> >
>> > >> >What do you think of it ?
>> > >> >
>> > >> >Franck
>> > >> >
>> > >> >Le mercredi 29 juillet 2009 Ã 13:09 +1000, <mailto:anthony%
>> > >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony%40berglas.org>[email protected] a
>> > écrit :
>> > >> >> 
>> > >> >> Hello Franck,
>> > >> >> 
>> > >> >> Good to hear that you are back on this. Producing a new
>> release
>> > is
>> > >> way
>> > >> >> over due. I have also been busy.
>> > >> >> 
>> > >> >> The reasoning is that aggregates is only one thing that it can
>> > do.
>> > >> The
>> > >> >> thing that is special about it is that it returns
>> > SRecordGenerics
>> > >> >> rather than SRecordInstances, with select list specified. It
>> can
>> > do
>> > >> >> much more than simple aggregates, even though that was the
>> > initial
>> > >> >> motivation.
>> > >> >> 
>> > >> >> While in this space I would love to unify SRecordGeneric,
>> > >> >> SRecordInstance and Maps. It is a messy at the moment. A lazy
>> > >> >> incremental approach is as follows.
>> > >> >> 
>> > >> >> WRONG WAY?
>> > >> >> 
>> > >> >> SRecordGeneric becomes an abstract class with stubs for
>> > >> >> getDouble(String) etc.
>> > >> >> 
>> > >> >> SRecordInstance and a new SRecordMap both extend
>> SRecordGeneric.
>> > >> >> 
>> > >> >> SQuerySelect returns lists of SRecordMap. SRecordMap is not a
>> > >> public
>> > >> >> class, just package local.
>> > >> >> 
>> > >> >> SRecordGeneric implements Map. For SRecordInstance that means
>> > >> >> implementing the map methods to call Instance methods. This
>> > makes
>> > >> it
>> > >> >> much more compatible with JSP, JSF etc.
>> > >> >> 
>> > >> >> The copied code in SRecordMap from SRecordInstance that does
>> > type
>> > >> >> conversion is pushed into SRecordGeneric. (I really hate
>> copied
>> > >> code.
>> > >> >> It invariably drifts apart. At the very least create common
>> > static
>> > >> >> methods.)
>> > >> >> 
>> > >> >> Ideally, and probably later, SDataSets can contain
>> > SRecordGenerics
>> > >> >> rather than SRecordInstances. 
>> > >> >> 
>> > >> >> Also, SRecordInstances should implement a Map of fields rather
>> > than
>> > >> an
>> > >> >> Array of fields. Then SRecordInstances can have additional,
>> > >> undeclared
>> > >> >> fields, and so SRecordMap disappears. I have done some
>> > experiments
>> > >> and
>> > >> >> the overhead is negligible even given Map's unfortunate
>> > >> implementation
>> > >> >> (an extra object for every key/value pair -- exactly what I
>> was
>> > >> >> avoiding with not having SFieldInstance).
>> > >> >> 
>> > >> >> CLEANER ALTERNATIVE
>> > >> >> 
>> > >> >> The above is really a bit back to front. I wonder how hard it
>> > would
>> > >> >> really be to take the array out of SRecordInstance and just
>> > replace
>> > >> it
>> > >> >> with a Map that it implements, indexed by field name. As
>> stated
>> > >> >> before, the overhead is minimal. Then your SQuerySelect could
>> > just
>> > >> >> return SRecordInstances, and there would be no need for
>> > >> >> SRecordGeneric. SQuerySelect should be unified with SQuery, so
>> > that
>> > >> ad
>> > >> >> hoc columns can be combined with known fields. 
>> > >> >> 
>> > >> >> For example, Select Department Name, Manager, AVG(employee
>> > Sallary)
>> > >> as
>> > >> >> Department record instances. Could then do
>> > dept.getString(MANAGER),
>> > >> >> dept.getString("avgSal"). (Given that "avgSal" is an ad hoc
>> > field
>> > >> not
>> > >> >> declared for Department.
>> > >> >> 
>> > >> >> Much neater. And demonstrates the advantage of not using rigid
>> > >> POJOs.
>> > >> >> (Will also behave better if there are deserialization issues.)
>> > >> >> 
>> > >> >> The more I think of this the more I do not like adding
>> > >> SRecordGeneric.
>> > >> >> It forks the concept of Record.
>> > >> >> 
>> > >> >> The Alternative is probably less work in the medium turn. Just
>> > >> making
>> > >> >> the field index a map should be fairly trivial -- we just
>> remove
>> > >> >> SFieldMeta.index as it is no longer needed and replace
>> > >> >> 
>> > >> >> public Object getRawArrayValue(SFieldMeta fmeta) {
>> > >> >> return fieldValues[fmeta.index];
>> > >> >> }
>> > >> >> 
>> > >> >> with
>> > >> >> 
>> > >> >> public Object getRawArrayValue(SFieldMeta fmeta) {
>> > >> >> return this.get(fmeta.fieldName);
>> > >> >> }
>> > >> >> 
>> > >> >> I'll do the latter if you will remove SRecordGeneric and unify
>> > the
>> > >> >> SQueries. 
>> > >> >> 
>> > >> >> (SQueryAggregate just becomes additional methods to SQuery. Or
>> > >> maybe
>> > >> >> delegated from SQuery as SQuery is getting too large.)
>> > >> >> 
>> > >> >> What do you think?
>> > >> >> 
>> > >> >> Regards,
>> > >> >> 
>> > >> >> Anthony
>> > >> >> 
>> > >> >> At 02:44 AM 29/07/2009, you wrote:
>> > >> >> > 
>> > >> >> >
>> > >> >> >Hi Anthony,
>> > >> >> >
>> > >> >> >it's been a long time since I said I would rename
>> > SAggregateQuery
>> > >> to
>> > >> >> >SQuerySelect, as soon as... well. I'm ready now :)
>> > >> >> >
>> > >> >> >I just come back to make sure I understand you:
>> > >> >> >
>> > >> >> >We want to rename SAggregateQuery to SQuerySelect to make the
>> > name
>> > >> >> more
>> > >> >> >generic, right ?
>> > >> >> >
>> > >> >> >But right now, SAggregateQuery is really only capable of
>> > returning
>> > >> >> >aggregates, that is SRecordGeneric whose fields are sums,
>> > >> averages,
>> > >> >> etc.
>> > >> >> >The specific methods of SAggregateQuery require that you do
>> > >> >> aggregates
>> > >> >> >and won't allow you to query arbitrary fields out of joined
>> > tables
>> > >> >> for
>> > >> >> >example.
>> > >> >> >
>> > >> >> >SO, do you want to rename SAggregateQuery in order to make it
>> > more
>> > >> >> >generic afterwards, or do you mean SAggreagateQuery and
>> SQuery
>> > >> should
>> > >> >> >share a common interface or a common base (abstract ?) class
>> > that
>> > >> >> would
>> > >> >> >be called SQuerySelect ?
>> > >> >> >
>> > >> >> >Regards,
>> > >> >> >
>> > >> >> >Franck
>> > >> >> >
>> > >> >> >Le dimanche 24 mai 2009 Ã 17:52 +1000, <mailto:berglas%
>> > >> >> 40SpreadsheetDetective.com><mailto:berglas%
>> > >> 40SpreadsheetDetective.com><mailto:berglas%
>> > 40SpreadsheetDetective.com><mailto:berglas%40SpreadsheetDetective.com>[email protected]
>> > >> >> >a écrit :
>> > >> >> >> 
>> > >> >> >> 
>> > >> >> >> Sounds good. I'll have some time over the next few weeks.
>> > >> >> >> 
>> > >> >> >> Anthony
>> > >> >> >> 
>> > >> >> >> At 08:19 PM 18/05/2009, you wrote:
>> > >> >> >> 
>> > >> >> >> >Hello,
>> > >> >> >> >
>> > >> >> >> >I have a few other commits waiting here that I would like
>> to
>> > go
>> > >> in
>> > >> >> >> the
>> > >> >> >> >build.
>> > >> >> >> >
>> > >> >> >> >Mainly, it allows to do:
>> > >> >> >> >
>> > >> >> >> >aggQuery.sum("some arbitrary sql here")
>> > >> >> >> >
>> > >> >> >> >(or groupBy, avg, max, min, count)
>> > >> >> >> >
>> > >> >> >> >For example sum("case where myfield = "TRUE" then 1 when
>> > >> >> >> myfield="FALSE"
>> > >> >> >> >then 0 end")
>> > >> >> >> >or
>> > >> >> >> >sum("(exract(epoch from myEndTimestamp) - extract(epoch
>> from
>> > >> >> >> >myBeginTimestamp")) / 3600") as durationindays
>> > >> >> >> >
>> > >> >> >> >I also added a hasTable(alias) method to SQuery to ease
>> > >> building
>> > >> >> of
>> > >> >> >> >conditionnal quieries.
>> > >> >> >> >
>> > >> >> >> >I'll commit it to let you have a look if you want.
>> > >> >> >> >
>> > >> >> >> >Then I'll rename SAggregateQuery to SQuerySelect...
>> > >> >> >> >
>> > >> >> >> >Regards,
>> > >> >> >> >Franck
>> > >> >> >> >
>> > >> >> >> >Le lundi 18 mai 2009 Ã 14:02 +1000, <mailto:anthony
>> %
>> > >> >> >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony
>> %
>> > >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony%40berglas.org>[email protected] a
>> > >> >> écrit :
>> > >> >> >> >> 
>> > >> >> >> >> 
>> > >> >> >> >> Hello Franck,
>> > >> >> >> >> 
>> > >> >> >> >> I would like to package up the current subversion state
>> > >> fairly
>> > >> >> soon
>> > >> >> >> >> and make it the next build. There are a few tweak I
>> would
>> > >> add.
>> > >> >> >> >> 
>> > >> >> >> >> Could you have a bit of a think about what needs to be
>> > >> cleaned
>> > >> >> up
>> > >> >> >> etc.
>> > >> >> >> >> for this to happen. Rename SQueryAggregate to something
>> > like
>> > >> >> >> >> SQuerySelect is one.
>> > >> >> >> >> 
>> > >> >> >> >> I'd prefer that you made changes related to your
>> > application
>> > >> so
>> > >> >> >> that
>> > >> >> >> >> you do not break compatibility.
>> > >> >> >> >> 
>> > >> >> >> >> Regards,
>> > >> >> >> >> 
>> > >> >> >> >> Anthony
>> > >> >> >> >> 
>> > >> >> >> >> >Hello Franck,
>> > >> >> >> >> >
>> > >> >> >> >> >I see your point about SQueryGeneric. How about
>> > >> SQuerySelect,
>> > >> >> >> because
>> > >> >> >> >> it lets you explicitly specify a select list? 
>> > >> >> >> >> >
>> > >> >> >> >> >I realize that you are busy but it would be good to at
>> > least
>> > >> do
>> > >> >> >> just
>> > >> >> >> >> the rename plus comment as soon as possible. (I won't do
>> > it
>> > >> >> because
>> > >> >> >> it
>> > >> >> >> >> will break your code.)
>> > >> >> >> >> >
>> > >> >> >> >> >I am a little concerned about getting too clever in
>> > SDriver
>> > >> >> about
>> > >> >> >> >> portability. Supporting this type of thing for multiple
>> > >> >> databases
>> > >> >> >> is
>> > >> >> >> >> very hard. I think that I would prefer that you just do
>> > this
>> > >> at
>> > >> >> the
>> > >> >> >> >> application layer. You just have little methods that
>> > provide
>> > >> the
>> > >> >> >> right
>> > >> >> >> >> query for different DBs. Could just return strings, or
>> > >> possibly
>> > >> >> >> >> SQuerySelect (given an SQuerySelect parameter). I prefer
>> > >> >> strings,
>> > >> >> >> it
>> > >> >> >> >> is simpler.
>> > >> >> >> >> >
>> > >> >> >> >> >Regards,
>> > >> >> >> >> >
>> > >> >> >> >> >Anthony
>> > >> >> >> >> >
>> > >> >> >> >> >At 04:49 PM 19/04/2009, you wrote:
>> > >> >> >> >> >>Hello Anthony,
>> > >> >> >> >> >>
>> > >> >> >> >> >>I've not be changing anything recently, except adding
>> a
>> > >> >> >> rawInnerJoin
>> > >> >> >> >> >>method to SQuery, that truly adds an arbitrary table
>> to
>> > a
>> > >> >> query
>> > >> >> >> (a
>> > >> >> >> >> table
>> > >> >> >> >> >>that has no explicit SFieldReference to the query).
>> > >> >> >> >> >>
>> > >> >> >> >> >>But I have also found I would need rawSelect(), so it
>> is
>> > >> >> >> definitely
>> > >> >> >> >> a
>> > >> >> >> >> >>good idea :-)
>> > >> >> >> >> >>
>> > >> >> >> >> >>The point is we are also releasing a new version of
>> our
>> > >> >> flgship
>> > >> >> >> >> product
>> > >> >> >> >> >>by the end of the month, so I'll be quite busy right
>> > until
>> > >> >> >> then...
>> > >> >> >> >> >>
>> > >> >> >> >> >>Just a few more comments:
>> > >> >> >> >> >>
>> > >> >> >> >> >>> I think that specifically SQueryAggregate and
>> friends
>> > >> should
>> > >> >> be
>> > >> >> >> >> renamed into something like SQueryGeneric. That is
>> because
>> > >> the
>> > >> >> >> thing
>> > >> >> >> >> that is special about it is that it returns
>> > SRecordGenerics
>> > >> >> rather
>> > >> >> >> >> than SRecordInstances. One use of SQueryGeneric is to do
>> > >> >> >> aggregates,
>> > >> >> >> >> but it is more general than that.
>> > >> >> >> >> >>
>> > >> >> >> >> >>Yes, but then, when SRecordInstance will extend
>> > >> >> SRecordGeneric,
>> > >> >> >> >> SQuery
>> > >> >> >> >> >>will also return SRecordGeneric... So, are we going to
>> > have
>> > >> an
>> > >> >> >> >> abstract
>> > >> >> >> >> >>SQueryGeneric, with SQuery and SAggregateQuery
>> extending
>> > >> it,
>> > >> >> or
>> > >> >> >> do
>> > >> >> >> >> you
>> > >> >> >> >> >>think both should be merged in the long term ? (right
>> > now I
>> > >> >> >> wouldn't
>> > >> >> >> >> say
>> > >> >> >> >> >>so, but I'm not sure)
>> > >> >> >> >> >>> 
>> > >> >> >> >> >>> Thus we should also add the easy 
>> > >> >> >> >> >>> .rawSelect(String rawSqlExpression, Object[]...
>> > >> parameters) 
>> > >> >> >> >> >>> which adds an arbitrary an arbitrary expression,
>> > >> >> >> plus .rawClause
>> > >> >> >> >> for completeness.
>> > >> >> >> >> >>
>> > >> >> >> >> >>Yes, that would be interesting...
>> > >> >> >> >> >>Another thing I found I'm missing is doing arbitray
>> > >> >> calculation
>> > >> >> >> and
>> > >> >> >> >> then
>> > >> >> >> >> >>doing an aggregate on it, but rawSelect wouldn't solve
>> > my
>> > >> >> problem
>> > >> >> >> >> >>altogether, as calculation might include database
>> > functions
>> > >> >> that
>> > >> >> >> are
>> > >> >> >> >> not
>> > >> >> >> >> >>standard.
>> > >> >> >> >> >>Typical example is I want to make a sum of durations
>> for
>> > my
>> > >> >> >> records,
>> > >> >> >> >> >>grouped by whatever. Duration is defined by the
>> > difference
>> > >> >> >> between
>> > >> >> >> >> two
>> > >> >> >> >> >>timestamps... and this is something that in not
>> standard
>> > in
>> > >> >> sql.
>> > >> >> >> So
>> > >> >> >> >> >>having portable code is not easy.
>> > >> >> >> >> >>
>> > >> >> >> >> >>eg. select sum( extract(epoch from endts) -
>> > extract(epoch
>> > >> from
>> > >> >> >> >> begints))
>> > >> >> >> >> >>will work for postgresql, but not for oracle etc.
>> > >> >> >> >> >>
>> > >> >> >> >> >>So another idea I had was to be able to augment
>> SDriver
>> > >> (and
>> > >> >> >> >> >>SQueryGeneric) with specific functions (like
>> > duration(ts1,
>> > >> >> ts1))
>> > >> >> >> >> that
>> > >> >> >> >> >>could be used in queries to allow to generate sql that
>> > will
>> > >> >> work
>> > >> >> >> in
>> > >> >> >> >> each
>> > >> >> >> >> >>database... I didn't do anything for now, as I'm not
>> > sure
>> > >> >> about
>> > >> >> >> the
>> > >> >> >> >> >>right way to do this (just add the functions I need,
>> or
>> > >> think
>> > >> >> >> about
>> > >> >> >> >> a
>> > >> >> >> >> >>more clever pluggable functions system, ...)
>> > >> >> >> >> >>
>> > >> >> >> >> >>> 
>> > >> >> >> >> >>> The simple unification of SRecordInstance with
>> > >> >> SRecordGeneric
>> > >> >> >> >> would complete the process, but that can be done later.
>> I
>> > >> might
>> > >> >> >> make
>> > >> >> >> >> time do it myself because it will not affect your code.
>> > (It
>> > >> is
>> > >> >> >> easy,
>> > >> >> >> >> just have SRecordInstance implement map, with 
>> > >> >> >> >> >>> 
>> > >> >> >> >> >>Fine.
>> > >> >> >> >> >>As I said, I won't have much time for the next two or
>> > hree
>> > >> >> weeks,
>> > >> >> >> >> but it
>> > >> >> >> >> >>should be better after that.
>> > >> >> >> >> >>
>> > >> >> >> >> >>Best regards,
>> > >> >> >> >> >>Franck
>> > >> >> >> >> >
>> > >> >> >> >> >Dr Anthony Berglas, <mailto:anthony%
>> > >> >> 40berglas.org><mailto:anthony%
>> > >> >> >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony
>> %
>> > >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony%40berglas.org>[email protected]
>> > >> >> >> >> Mobile: +61 4 4838 8874
>> > >> >> >> >> >Just because it is possible to push twigs along the
>> > ground
>> > >> with
>> > >> >> >> ones
>> > >> >> >> >> nose
>> > >> >> >> >> >does not necessarily mean that is the best way to
>> collect
>> > >> >> >> firewood.
>> > >> >> >> >> >
>> > >> >> >> >> >
>> > >> >> >> >> 
>> > >> >> >> >> Dr Anthony Berglas, <mailto:anthony%
>> > >> >> >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony
>> %
>> > >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony%40berglas.org>[email protected]
>> > >> >> Mobile: +61 4 4838 8874
>> > >> >> >> >> Just because it is possible to push twigs along the
>> ground
>> > >> with
>> > >> >> >> ones
>> > >> >> >> >> nose
>> > >> >> >> >> does not necessarily mean that is the best way to
>> collect
>> > >> >> firewood.
>> > >> >> >> >> 
>> > >> >> >> >> 
>> > >> >> >> >> 
>> > >> >> >> >> 
>> > >> >> >> >> 
>> > >> >> >> >
>> > >> >> >> >
>> > >> >> >> 
>> > >> >> >> Spreadsheet Detective,
>> > >> >> >> Southern Cross Software Queensland Pty Limited
>> > >> >> >> 54 Gerler Street
>> > >> >> >> Bardon, Queensland 4065, Australia.
>> > >> >> >> 
>> > >> >> >> Email: <mailto:berglas%
>> > >> >> 40spreadsheetdetective.com><mailto:berglas%
>> > >> 40spreadsheetdetective.com><mailto:berglas%
>> > 40spreadsheetdetective.com><mailto:berglas%40spreadsheetdetective.com>[email protected]
>> > >> >> >> www.SpreadsheetDetective.com
>> > >> >> >> Ph: +61 427 830248 (Australian Eastern Standard Time)
>> > >> >> >> 
>> > >> >> >> "If the model seems correct only because the numbers look
>> > >> right, 
>> > >> >> >> then why build the model in the first place?"
>> > >> >> >> 
>> > >> >> >> 
>> > >> >> >> 
>> > >> >> >> 
>> > >> >> >> 
>> > >> >> >
>> > >> >> >
>> > >> >> 
>> > >> >> Dr Anthony Berglas, <mailto:anthony%
>> > >> 40berglas.org><mailto:anthony%40berglas.org><mailto:anthony%40berglas.org>[email protected]
>> > Mobile: +61 4 4838 8874
>> > >> >> Just because it is possible to push twigs along the ground
>> with
>> > >> ones
>> > >> >> nose
>> > >> >> does not necessarily mean that is the best way to collect
>> > firewood.
>> > >> >> 
>> > >> >> 
>> > >> >> 
>> > >> >> 
>> > >> >> 
>> > >> >
>> > >> >
>> > >> 
>> > >> Spreadsheet Detective,
>> > >> Southern Cross Software Queensland Pty Limited
>> > >> 54 Gerler Street
>> > >> Bardon, Queensland 4065, Australia.
>> > >> 
>> > >> Email: <mailto:berglas%
>> > 40spreadsheetdetective.com><mailto:berglas%40spreadsheetdetective.com>[email protected]
>> > >> www.SpreadsheetDetective.com
>> > >> Ph: +61 427 830248 (Australian Eastern Standard Time)
>> > >> 
>> > >> "If the model seems correct only because the numbers look right, 
>> > >> then why build the model in the first place?"
>> > >> 
>> > >> 
>> > >> 
>> > >> 
>> > >> 
>> > >
>> > >
>> > 
>> > Dr Anthony Berglas, <mailto:anthony%40berglas.org>[email protected] Mobile: +61 4 4838 8874
>> > Just because it is possible to push twigs along the ground with ones
>> > nose
>> > does not necessarily mean that is the best way to collect firewood.
>> > 
>> > 
>> > 
>> > 
>> > 
>> 
>> 
>> 
>> 
>> 
>
>

Dr Anthony Berglas, [email protected]       Mobile: +61 4 4838 8874
Just because it is possible to push twigs along the ground with ones nose
does not necessarily mean that is the best way to collect firewood.



------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/SimpleORM/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/SimpleORM/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:[email protected] 
    mailto:[email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/