Search the web
Sign In
New User? Sign Up
SimpleORM
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Hear how Yahoo! Groups has changed the lives of others. Take me there.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
The Big Split -- SimpleOrm.records and SimpleOrm.database.   Message List  
Reply | Forward Message #1549 of 1851 |
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.


Mon Jun 30, 2008 5:56 am

aberglas
Offline Offline
Send Email Send Email

package simpleorm.data.test;

import simpleorm.data.*;
import simpleorm.data.ddlutilsaddaptor.DDdlUtlisConnection;
import simpleorm.data.dynabeanadaptor.DDynaConnection;
import simpleorm.data.dynabeanadaptor.DDynaDatabase;

import java.util.Iterator;

import org.hsqldb.jdbc.jdbcDataSource;

/**
* Basic sample and example of Data Interface.<p>
*
* Three providers: DdlUtilsConnection, DDynaCollection and custom MyConnection.
* The latter also provides an example of writing a manual provider, should that
be desired.
*/
public class DBasicTest {

/** Could subtype DRecordInstance etc. if necessary. */
static public class MyRecord extends DRecordInstance {
static public final DRecordMeta MY_RECORD = new
DRecordMeta(MyRecord.class, "MY_RECORD");
static final DFieldMeta ID = MY_RECORD.addField(new DFieldMeta("ID",
DType.INTEGER))
.setPrimaryKey(true);
static final DFieldMeta NAME = MY_RECORD.addField(new DFieldMeta("NAME",
DType.STRING));
static final DFieldMeta DESCRIPTION = MY_RECORD.addField(new
DFieldMeta("DESCRIPTION", DType.STRING));
//static final DFieldMeta KEY = MY_RECORD.addField(new DFieldMeta("KEY",
DType.BYTES));
static final DFieldMeta UNQUERIED = MY_RECORD.addField(new
DFieldMeta("UNQUERIED", DType.STRING));
static final DFieldMeta PARENT = MY_RECORD.addField(new
DFieldMeta("PARENT", DType.INTEGER));

static final DForeignKeyMeta PARENT_FK =
MY_RECORD.addRefingFKey(PARENT);

String getName() {return getString(NAME);} // get/seters optional and
not recommended, just an example.

public MyRecord() {super(MY_RECORD); }

public @Override void onPreUpSert(DConnection connection, QueryMode
mode) {
System.err.println("onPreUpSert " + mode + this);
}

}

static class MySubRecord extends MyRecord {
// static final DRecordMeta MY_RECORD = new DRecordMeta("MY_RECORD");
// static final DFieldMeta ID = MY_RECORD.addField(new DFieldMeta("ID",
DType.INTEGER))
// .setPrimaryKey(true);
// static final DFieldMeta NAME = MY_RECORD.addField(new
DFieldMeta("NAME", DType.STRING));
// static final DFieldMeta KEY = MY_RECORD.addField(new DFieldMeta("KEY",
DType.BYTES));
//
// public MySubRecord() {
// super(MY_RECORD);
// }
}

public static void main(String[] args) throws Exception {

//todo enable simple commons logging so that ddlutils error messages are
displayed! (eg. no primary key).

/// Example of manual bean, not normally used.
testAdaptor(new MyConnection());

/// Example of an automated dyna bean / hash map database
testAdaptor(new DDynaConnection(new DDynaDatabase()));

/// Main example using Ddl Utils.
testAdaptor(newDdlUtilConnection());
}

private static DDdlUtlisConnection newDdlUtilConnection() {
DDdlUtlisConnection dcon = new DDdlUtlisConnection();

jdbcDataSource dataSource = new jdbcDataSource();
dataSource.setUser("sa");
dataSource.setDatabase("jdbc:hsqldb:file:testdb/ddlutils_hsqldb");

dcon.addTableToSchema(MyRecord.MY_RECORD);
dcon.setDataSource(dataSource);

dcon.createModel();
return dcon;
}

static void testAdaptor(DConnection connection) throws Exception {

System.err.println("\n======================================= " +
connection.getClass().getSimpleName());

MyRecord rec1 = addRec(connection, 1, "Fred", "First");
MyRecord rec2 = addRec(connection, 2, "Nerk", "Second");
MyRecord rec3 = addRec(connection, 3, "Bert", "Thrid");
MyRecord rec4 = addRec(connection, 4, "Fred", "Fourth");
System.err.println("Record " + rec1);
assertEquals("Fred", rec1.getObject(rec1.NAME));
rec4.setObject(rec4.DESCRIPTION, "FourthX");
connection.update(rec4);

DQuery qry = new DQuery(MyRecord.MY_RECORD)

.addSelect(rec1.ID).addSelect(rec1.NAME).addSelect(rec1.DESCRIPTION)
.eq(rec1.NAME, "Fred").addOrderBy(rec1.NAME)
.setOffset(0).setLockRecords(false);
// assertEquals(qry.compare(rec1, rec3), 1); // > ## returns 4?
// assertEquals(qry.compare(rec3, rec4), -1); // <
assertEquals(qry.compare(rec3, rec3), 0);
assertEquals(!rec1.equals(rec2), true);
assertEquals(rec1.hashCode() != rec2.hashCode(), true);

Iterator recI = qry.execute(connection);
MyRecord lrec = null;
int count=0;
while (recI.hasNext()) {
lrec = (MyRecord)recI.next();
System.err.println("Queried " + ++count + " :" +
lrec.toLongString());
}
assertEquals(2, count);
assertEquals(lrec, rec4);
assertEquals(lrec == rec4, false);
String descr4 = lrec.getString(lrec.DESCRIPTION);
assertEquals(descr4, "FourthX");

DQuery qry2 = new DQuery(MyRecord.MY_RECORD)
.addSelect(rec1.ID).addSelect(rec1.NAME)
.eq(rec1.ID, 2);
MyRecord q2r2 = (MyRecord)qry2.executeOnlyRecord(connection);
assertEquals(q2r2, rec2);

MyRecord q3r3 = (MyRecord)new DQuery(MyRecord.MY_RECORD)
.queryPrimaryKey(connection, 3);
assertEquals(q3r3, rec3);

}

static MyRecord addRec(DConnection connection, int id, String name, String
description) {
MyRecord rec1 = (MyRecord)connection.newInstance(MyRecord.MY_RECORD); //
## MESSY
rec1.setObject(rec1.ID, id);
rec1.setObject(rec1.NAME, name);
rec1.setObject(rec1.DESCRIPTION, description);
rec1.setObject(rec1.UNQUERIED, "UnQueried" + id);
connection.insert(rec1);
return rec1;
}


static void assertEquals(Object expected, Object actual) {
System.err.println("Asserting " + expected);
if ( expected==null ? actual!=null : !expected.equals(actual) )
throw new DException("assertEquals Failed " + expected + " != " +
actual);
}

}


Forward
Message #1549 of 1851 |
Expand Messages Author Sort by Date

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...
Anthony Berglas
aberglas
Offline Send Email
Jun 30, 2008
5:57 am

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...
Anthony & Melissa Ber...
berglas@...
Send Email
Jun 30, 2008
10:45 am

Anthony, maybe we should consider introducing SDataSet (or SDataSetManager ?) right now. First it would be equivalent to SConnection's transaction cache and ...
Franck Routier
routier_franck
Offline Send Email
Jun 30, 2008
2:24 pm

Hello Franck, Hmm. The design gets ever more ambitious. I am concerned that if we take on too much we will not finish. But it would be good to get this...
Anthony Berglas
aberglas
Offline Send Email
Jul 1, 2008
11:18 am

Hi Anthony, that seems fine to me, except for one point that is not that clear :) shouldn't "myDS.create(new Employee().set(Employee.ID, "123").set.....);"...
Franck Routier
routier_franck
Offline Send Email
Jul 1, 2008
2:46 pm

Anthony, I've done some work, namely steps 1 to 6, execpt for the 'flush before query part'. Lot of thinks are now public, including some fields. Bad. Also...
Franck Routier
routier_franck
Offline Send Email
Jul 1, 2008
7:59 pm

Hello Franck, Wow, you have been busy. I agree that we need to be careful about our vocabulary, I had been a bit sloppy. SCon."attach/detach" had referred to ...
Anthony Berglas
aberglas
Offline Send Email
Jul 2, 2008
10:18 am

Hello Anthony, I agree with everything you say here. Regarding naming, maybe we should consider JPA terminology ? Then Session would be EntityManager. And...
Franck Routier
routier_franck
Offline Send Email
Jul 2, 2008
10:52 am

Hello Franck, You've been busy again. ... I'm not sure that joinTranction a good description for SSession.open. Maybe ...
Anthony Berglas
aberglas
Offline Send Email
Jul 3, 2008
5:11 am

Hi, ok, I really like SSession.newSessionAndAssociateWithCurrentThreadAndOpenJdbcConnection(), which really says what it does..... :) I agree with the fact...
Franck Routier
routier_franck
Offline Send Email
Jul 3, 2008
7:50 am

Anthony, I was wondering, why must have so many static methods in SSession, that most of the time end up finding the current scon in threadlocal, instead of...
Franck Routier
routier_franck
Offline Send Email
Jul 3, 2008
12:35 pm

Hmm. The motivations for attaching the session to a thread local were:- 1. It avoids having to pass a connection variable everywhere. In a database...
Anthony Berglas
aberglas
Offline Send Email
Jul 4, 2008
2:11 am

Hello Franck To keep it simple, the semantics of attaching a data set to a session could be exactly the same as attaching each record in it, one by one. As ...
Anthony Berglas
aberglas
Offline Send Email
Jul 4, 2008
12:47 am
Advanced

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help