setParam("FROM") and setPram("TO") for paging - do those actually get injected directly into sql? or are they some internal vars you set?
ORMapping should probably support a dialect system like hibernate. it really sucks that it is part of the hierarchy now, because i like to develop on a different database then the one in prod, and it should be simple to swap. seems shades doesnt abstract as much of the db layer as hibernate/ejb3/whatever - i need to code to shades not to my underlying db imho.
the dictionary can be improved by providing builders. new OneToManyBuilder(some params) that will build the string. less chances of typos.
there needs to be a tool that will validate the dictionary against the current schema - prob by retrieving jdbc metadata. because a lot of things in the dict are defined by strings it would be great to know you didnt fat finger something on application startup rather then at some distant runtime.
this definetely gives me the feeling of being much closer to the bare metal, which i think is nice if you want more control - and my favorite part is that you have to explicitly call update() to have your changes persisted :)
on some high high level this reminds me of ibatis, but much more code centric.
i really wish i had a project i could use this on right now to give you more valuable feedback, but i dont :(
You are right that shades queries are less portable than a JDOQL or dialect query, but the reason for that is flexibility. In shades, you can do absolutely anything that the underlying database supports.
Good suggestion on the tool to check the schema. I have a schema generation tool, but what you suggested would be great.
tell me more about your builder idea.
Glad you like the explicit update method. This was a very intentional piece of the design.
i understand the added flexibility for not making queries portable - but for me this would be a deal breaker. maybe build a system on top of shades that adds portability - but it would be much uglier and much more work for the end user.
things that need to be portable are usually just identity generation and paging. i mean look here:
for multi column fks you can do ManyToOne.byPair("FK1","PK1","FK2","PK2") and that would translate to ${this.alias}.FK1 = ${that.alias}.PK1 AND ${this.alias}.FK2 = ${that.alias}.PK2, just make it easier for 80% cases
I appreciate the feedback. Just so you know, the ORMapping does have all the capability to do initialization of columns on insert, identity generation, etc. For example DefaultHsqlORMapping extends DefaultORMapping and provides the proper identity generation for HSQLDB.
But it very much is an intentional design choice to bring it a little closer to the metal. I appreciate the feedback.
It looks interesting, but I'd be afraid that it would only be useful for DB's that support a 'standard' SQL. Not that I know of any, though...! Specifically, for me, I'd want to know about Oracle support, as for paging, for instance, I needed to use the SQL format shown here... (http://www.wicket-wiki.org.uk/wiki/index.php/IBATIS#Oracle_paging).
As Igor said, it's appears to be not too dissimilar in places to iBATIS, especially when using iBATIS's Abator tool to generate the QueryByExample code (e.g. http://ibatis.apache.org/docs/tools/abator/generatedobjects/exampleClassUsage.html#java2). I'm not suggesting you stop if it works for you but I am suggesting it might be an acceptable alternative for others to consider if the more esoteric DB behaviours do need too much special-coding...
Yeah, most paging SQL is not standard. I was considering adding an immutable query, that you could fully specify all the SQL for. Seems like I now have a good use case for that. Here is an example of using an immutable query for sorted pagination on Oracle. "immutable" just means that no alteration, aside from variable substitution, is made to the SQL you provide.
String sql = "SELECT * FROM( SELECT a.*, ROWNUM r FROM ( SELECT "+columns+" FROM "+table+" ORDER BY ${order-column}) a ) WHERE r BETWEEN ${start} AND ${end}";
setParam("FROM") and setPram("TO") for paging - do those actually get
ReplyDeleteinjected directly into sql? or are they some internal vars you set?
ORMapping should probably support a dialect system like hibernate. it
really
sucks that it is part of the hierarchy now, because i like to develop
on a
different database then the one in prod, and it should be simple to
swap.
seems shades doesnt abstract as much of the db layer as
hibernate/ejb3/whatever - i need to code to shades not to my underlying
db
imho.
the dictionary can be improved by providing builders. new
OneToManyBuilder(some params) that will build the string. less chances
of
typos.
there needs to be a tool that will validate the dictionary against the
current schema - prob by retrieving jdbc metadata. because a lot of
things
in the dict are defined by strings it would be great to know you didnt
fat
finger something on application startup rather then at some distant
runtime.
this definetely gives me the feeling of being much closer to the bare
metal,
which i think is nice if you want more control - and my favorite part
is
that you have to explicitly call update() to have your changes
persisted :)
on some high high level this reminds me of ibatis, but much more code
centric.
i really wish i had a project i could use this on right now to give you
more
valuable feedback, but i dont :(
"from" and "to" are just user-defined substitution variables in the query. SO the query was created like this, for example:
ReplyDeleteRecordCandidate author = query.newCandidate(authorORM, "anAuthor");
author.where("LIMIT ${from} OFFSET ${to}");
You are right that shades queries are less portable than a JDOQL or dialect query, but the reason for that is flexibility. In shades, you can do absolutely anything that the underlying database supports.
Good suggestion on the tool to check the schema. I have a schema generation tool, but what you suggested would be great.
tell me more about your builder idea.
Glad you like the explicit update method. This was a very intentional piece of the design.
i understand the added flexibility for not making queries portable - but for me this would be a deal breaker. maybe build a system on top of shades that adds portability - but it would be much uglier and much more work for the end user.
ReplyDeletethings that need to be portable are usually just identity generation and paging. i mean look here:
http://josephlindsay.com/archives/2005/05/27/paging-results-in-ms-sql-server/
users shouldnt have to build hacks like these themselves, and paging is different in almost every database.
the builder i was talking about was for simple cases, so replace this
dict.defineRelationship("student->teacher", "${this.alias}.FK = ${that.alias}.PK");
with
dict.defineRelations("student->teacher", FKBuilder.byPair("FK","PK"))
for multi column fks you can do ManyToOne.byPair("FK1","PK1","FK2","PK2") and that would translate to ${this.alias}.FK1 = ${that.alias}.PK1 AND ${this.alias}.FK2 = ${that.alias}.PK2, just make it easier for 80% cases
Cool cool.
ReplyDeleteI appreciate the feedback. Just so you know, the ORMapping does have all the capability to do initialization of columns on insert, identity generation, etc. For example DefaultHsqlORMapping extends DefaultORMapping and provides the proper identity generation for HSQLDB.
But it very much is an intentional design choice to bring it a little closer to the metal. I appreciate the feedback.
It looks interesting, but I'd be afraid that it would only be useful for DB's that support a 'standard' SQL. Not that I know of any, though...! Specifically, for me, I'd want to know about Oracle support, as for paging, for instance, I needed to use the SQL format shown here... (http://www.wicket-wiki.org.uk/wiki/index.php/IBATIS#Oracle_paging).
ReplyDeleteAs Igor said, it's appears to be not too dissimilar in places to iBATIS, especially when using iBATIS's Abator tool to generate the QueryByExample code (e.g. http://ibatis.apache.org/docs/tools/abator/generatedobjects/exampleClassUsage.html#java2). I'm not suggesting you stop if it works for you but I am suggesting it might be an acceptable alternative for others to consider if the more esoteric DB behaviours do need too much special-coding...
Yeah, most paging SQL is not standard. I was considering adding an immutable query, that you could fully specify all the SQL for. Seems like I now have a good use case for that. Here is an example of using an immutable query for sorted pagination on Oracle. "immutable" just means that no alteration, aside from variable substitution, is made to the SQL you provide.
ReplyDeleteString columns = myOrm.getColumns("STUDENT");
String table = myORM.getTable();
String sql = "SELECT * FROM( SELECT a.*, ROWNUM r FROM ( SELECT "+columns+" FROM "+table+" ORDER BY ${order-column}) a ) WHERE r BETWEEN ${start} AND ${end}";
Query q = QueryFactory.newImmutableQuery(sql);
q.candidate(studentORM);
dbSess.setParameter("start","40");
dbSess.setParameter("end","50");
dbSess.setParameter("order-column", "LNAME");
RecordSet rs = dbSess.executeQuery(conn,q)