Hi,
I still consider keeping the Peer/Object model as we have it now. I'd
like to hear some opinions about the following stuff:
Ambler speaks of CRUD (create, retrieve, update, delete). We have for this:
BasePeer.doInsert() (Create)
BasePeer.doSelect() (Retrieve)
BasePeer.doUpdate() (Update)
BasePeer.doDelete() (Delete)
in the peer.
the torque generated objects also have save() methods (if configured).
I will write about FooPeer.<method> in this message. This will actually be a facade
class for
Torque.getPeer("Foo").<method>
with Torque.getPeer("Foo") returning a singleton object reference
representing the Peer. An object without static methods. ;-)
so when I write "v = FooPeer.select(c)", please replace in your mind
with "v = Torque.getPeer("Foo").select(c)"
I'd like to chop this down to
Vector v = Peer.select(Criteria c) => returns a Vector of objects selected by
the criteria.
[ player returns a cursor here, I might take a look at this but don't
hold your breath. I'm not sure that a cursor is the answer that we
like to have. On the other hand, having two methods, one returning a
cursor and one replacing the cursor based list with a Vector may be
nice ]
Torque returns a Vector of Village Records. I always asked myself, why.
Why doesn't it simply return a vector of "Foo" objects from the "FooPeer"?
The only real reason that I can see is the fact that there could be
more than just one table be in the "SELECT" clause so you would get
multiple objects with one select. I have no really good idea (yet) how
to manage this without Village (see below for same brain farts). I
don't even know if in the current form this is really an issue as a
peer contains only one table...
Do we have _any_ other statement where we can get potentially data
from more than just one table?
And player does this completely different:
Criteria c = pm.getRetrieveCriteria(Foo.class);
<= get a criteria which is prescheduled for "Foo objects"
pm is the "persistence manager" for this database.
c.getWhereCondition().addOrCriteria(criteria.getEqualToCriteria("name"));
java.util.Vector param = new java.util.Vector();
param.add("xxx");
--- cut ---
Cursor result = c.perform(param);
while(result.next())
{
Foo f = (Foo)result.getObject();
}
result.close();
--- cut ---
I don't see either, how to perform a select from multiple tables in
player asides from designing a new object which contains all the
columns we're interested in and then use the proxy stuff to perform
the actual accesses.
I don't like the way, Criterias are defined and used in player. It may
be more flexible than Torque but I hate all that typing. :-)
This one is IMHO much better (the more-Torque-like way):
--- cut ---
Criteria c = new Criteria();
c.and(new CriteriaPart(FooPeer.NAME, SqlEnum.EQUALS, "xxx"));
Vector v = FooPeer.select(c);
Foo f = (Foo)v.get(0);
--- cut ---
And for selecting from multiple tables:
--- cut ---
Criteria c = new Criteria();
c.and(new CriteriaPart(FooPeer.NAME, SqlEnum.EQUALS, "xxx"));
c.and(new CriteriaPart(BarPeer.NAME, SqlEnum.EQUALS, "yyy"));
Vector v = Torque.select(c);
^^^^^^
Or something else, more generic.
=> SELECT * FROM foo,bar WHERE foo.Name = 'xxx' AND bar.Name = 'yyy';
Foo f = (Foo)v.get(0).getObject(Foo.class); // or FooPeer.OBJECTNAME ? or "Foo" ?
Bar b = (Bar)v.get(0).getObject(Bar.class);
--- cut ---
Or how about
--- cut ---
Foo f = new Foo();
Foo b = new Bar();
v.get(0).mapToObject(f);
v.get(0).mapToObject(b);
--- cut ---
And just about everything else happens at the "Foo" objects:
--- cut ---
Foo f = new Foo();
f.setName("xxx");
f.setValue(20);
f.setFoo("bar");
f.save();
--- cut ---
=> INSERT with ID generated by the ID Generator method defined in
the map
--- cut ---
Foo f = new Foo();
f.setName("xxx");
f.setValue(20);
f.setFoo("bar");
f.setId(20);
f.save();
--- cut ---
=> INSERT with fixed ID.
--- cut ---
Criteria c = new Criteria();
c.and(new CriteriaPart(FooPeer.NAME, SqlEnum.EQUALS, "xxx"));
Vector v = FooPeer.select(c);
Foo f = (Foo)v.get(0);
--- cut ---
=> SELECT * FROM foo WHERE NAME = 'xxx';
--- cut ---
f.setName("yyy");
f.save();
--- cut ---
=> UPDATE foo SET name='yyy' WHERE ID=<retrieved id>
--- cut ---
f.delete();
--- cut ---
=> DELETE FROM foo WHERE ID=<retrieved id>
(May want to throw an exception if used like this:
---cut ---
Foo f = new Foo();
f.delete(); // Throws Exception? Does nothing? Dies in flames? ;-)
---cut ---
)
--- cut ---
Criteria c = new Criteria();
c.and(new CriteriaPart(FooPeer.NAME, SqlEnum.EQUALS, "xxx"));
FooPeer.delete(c);
--- cut ---
=> DELETE FROM foo where NAME='xxx';
Another thing I never really liked is the fact, that the whole
persistence business requires "SELECT * " statements. Maybe something
like "columns of interest" for the FooPeer.select() whould be
interesting (with a default of "fetch everything"). If I have really,
really expensive columns in a table (let's say some "media data" with
multi-MB object blocks), I really like to mask these out of my
selection run. Still being able to use "MediaPeer.select(c)" is nice,
though.
Main point of all this is chopping away the doInsert() and doUpdate()
stuff from the Peer and take a really, really deep look at
select(). delete() is a PoC and it is actually useful to have two
kinds of delete() (one row based, one table based).
Anyone has a really, really, really good reason to keep insert and
update in the Peer objects (Asides from "Backward compatibility" which
is not of concern for my current work. This is not scheduled to go in
for T3 or Torque current)?
Stuff to talk about.
Regards
Henning
--
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen -- Geschaeftsfuehrer
INTERMETA - Gesellschaft fuer Mehrwertdienste mbH [EMAIL PROTECTED]
Am Schwabachgrund 22 Fon.: 09131 / 50654-0 [EMAIL PROTECTED]
D-91054 Buckenhof Fax.: 09131 / 50654-20
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>