Hello Frank,
Moving SQuery out is possible. One would have to
store the built query as a structure rather than
a query string, and then translate to string in .database. eg.
eq(this, that) {
operationsList.add(new Eq(this, that));
}
A little bit of extra overhead, but doable. Much
better to have query SQL built in SDriver.
What would the API look like? Maybe
SQuery<Employee> qry = new SQuery(Employee.meta).eq(EMPEE_ID, "123");
SResultSet<Employee> rs = new SResultSet(qry).execute();
and maybe
Employee[] emps = new SFinder(qry).execute();
(Cannot have qry.execute() because that crosses the boundary.)
Having SQuery in the record part would also mean
that one could later apply simple queries to a
DataSet (ie.list) of records, outside a database which would be cool.
We could also choose to keep the existing API if
we have a database accessor interface written in
.record but implemented in .database. But we
then need to keep a pointer to the
implementation, either in a static or another
thread local. This produces a slightly neater
API but is much less transparent.
What do you think? Please propose an API style that would suit you.
Going forward, do you have time this week? I
would like to start by cutting out the finder
code in SRecordMeta, which is an internal change.
Sorry about the non-public method. If we split
this then all the meta data will need to be
public so that the .database part can access it!
Regards,
Anthony
At 07:24 PM 30/06/2008, Franck Routier wrote:
>Hello Anthony,
>
>I totally second this separation. This makes things much cleaner, and
>opens the possibility for future evolutions.
>
>However, I am not sure I want SQuery to be in the database part...
>Right now, I build a lot of queries in my business layer, depending on
>business rules, and then execute them in Dao's.
>Would it be possible to keep SQuery quite conceptual, and let
>SConnection/SDriver implement the DB specific part. This would also make
>possible to have some different SConnection implementation, say towards
>a ldap repository, etc. (well, I know SQuery join and so on are pretty
>RDBMS oriented...)
>
>This would make SQuery kind of a custom query language, which you would
>rather avoid, as said in the whitepaper. But we could keep it as it is
>now, that is a 'tiny' layer over jdbc AND potentialy other stuffs :)
>Would you consider this option ?
>
>By the way, introducing references to SConnection.getDriver() in SQuery
>(for quoting) broke my app. As said before, I tend to build my queries
>outside connections. So I temporay commented it out. The option I would
>go for is to translate SQuery into sql latter on, in SPreparedStatement
>for example. What is your opinion on this ?
>
>Also be careful to preserve API visibility, at least for read-only
>getters. Restricting it to package visibility also breaks a lot of my
>code for dynamically building queries.
>
>
>That said, I really like your idea.
>
>Franck
>
>
>Le lundi 30 juin 2008 à 15:56 +1000, Anthony Berglas a écrit :
> > Hello Franck,
> >
> > I think that as part of 3.0 we should consider splitting SimpleOrm
> > into two pieces, each in their own Jars.
> >
> > simpleorm.records that contains SRecordMeta, SRecordInstance, SField*
> >
> > simpleorm.database that contains SQuery, SDriver*, SConnection.
> >
> > The record part should have zero dependency on the database part, and
> > should be compiled and built into its own jar, with some test cases of
> > its own.
> >
> > The database part should depend on the records part, obviously.
> >
> > When working detached, one should only need the .records jar.
> >
> > This is actually not that hard to do. I have already decoupled
> > SQuery from SRecordMeta. A similar trick can be used to decouple
> > findOrCreate and friends. And the only other substantial connection
> > is where SReferenceField.getRawValue can do a lazy read.
> >
> > For findOrCreate, the API becomes slightly messier:-
> >
> > SFinder empf<Employee> = new SFinder(Employee.meta);
> > Employee e = empf.findOrCreate("123");
> >
> > or simply but slightly less efficiently
> >
> > Employee e = new SFinder(Employee.meta).findOrCreate("123");
> >
> > (The finder would cache the sets of different types of fields etc.)
> >
> > vs old
> >
> > Employee e = Employee.meta.findOrCreate("123");
> >
> > For the SFieldReference.get the call would become
> >
> > SFinder deptf<Department> = new SFinder(Department.meta);
> > Department dept = deptf.getReference(myEmp, DEPT);(
> >
> > (For the detached case, no query:-)
> > Department dept = myEmp.getUnqueriedReference(DEPT);
> >
> > One could, of course, give SRecordMeta a default finder, defined
> > through an interface in .SRecord, and then keep the existing
> > API. But being explicit makes the structure clear.
> >
> > I have also attached some other prototyping that I was doing in
> > SimpleData (it is checked in). But I now think that splitting
> > SimpleOrm is a much better idea, and SimpeData should be
> > abandoned. I think that this change is actually very good, and would
> > lead naturally to DataSets if we wanted to go there later.
> >
> > My current task is to work on the white paper etc. I would not want
> > to start any split until you have caught up with the current changes
> > and your application works 100%. (Although I might be tempted to do
> > some of the internal rearrangement, moving code from SRecordMeta to
> > SFinder.)
> >
> > One way or the other I am hoping to make your branch the trunk this
> > week.
> >
> > What do you think?
> >
> > Anthony
> >
> > Dr Anthony Berglas, anthony@... 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: berglas@...
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?"