Hi, I just opened this issue :https://github.com/max-l/Squeryl/issues#issue/70
implementing callbacks for lifecycle events, i.e. :(pre|post)insert,(pre|post)update(post)select(pre|post)deleteis what you need, I'm thinking that callbacks could be methods in the Schema like this one :
def afterSelect(o: ATraitOrClass) = {...}in this case all Query[]s returning objects from a Table[T] where T <: ATraitOrClasswill cause the callback to be called.In your case, you would declare :def beforeInsert(t: YourCommonAncestorTrait) = {t.sessionStartTime = Session.currentSession.startTime // note that Session doesn't have a startTime, but it could....}The callback could also be on a per table basis :yourTable.beforeInsert(t=>t.sessionStartTime = Session.currentSession.startTime)In the meantime, you can do this hack, by overriding DatabasAdapter.writeInsert :class YourDatabaseAdapter(...) extends MySqlAdapter (...) {def writeInsert[T](o: T, t: Table[T], sw: StatementWriter):Unit = {super.writeInsert(o,t,sw)t.asInstanceOf[YourTrait].sessionStartTime = Session.currentSession.asInstanceOf[YourCustomSession].startTime}}and :class YourCustomSession extends Session {val startTime = new Date}but of course this is a hack... The real solution is to have a callback mechanism,they should be pretty easy to write, stay tuned for issue #70, if you want to tryimplementing it you can fork the repo.CheersOn Tue, Nov 23, 2010 at 2:02 AM, Kristian Domagala <kristian...@gmail.com> wrote:
Thanks for the reply.
Yes, current_timestamp is the same as now(). I tried your suggestion, and regardless of whether createdDate is set to new Date or null, it does not cause the date to be set from the database using the now() function (instead, it sets it to the current client date and null respectively).
In my case, I could possibly work around the issue of the generated date not being returned by the insert statement (although that would be nice), but it is a show-stopper if I can't somehow get the date to be generated from the database itself, set to the start time of the current transaction.
Are there any plans for this sort of thing in future releases of Squeryl? Is there an existing part of the library that would be amenable to adding this functionality in the form of a patch?
I've had a bit of a look, and I wonder if it would be possible to have a special type for database-generated values that could be assigned as a default value or even set as an explicit value on the entity. At query execution time, it's expanded to 'now()', and the generated value is included in the RETURNING statement and returned with the result. Alternatively, I noticed the '&' function for "evaluating arbitrary expressions on the database side", so maybe something could be worked in to that.
I can imagine other functions (even if they're custom or db-specific) that this kind of functionality could be useful for. If you can think of anything else I can try with the current (or upcoming) library, or can suggest anywhere I can look to possibly add something, that would be appreciated.
Cheers,
Kristian.2010/11/22 Maxime Lévesque <maxime....@gmail.com>You are right, defaultsTo only affects the DDL generation,in your example is current_timestamp a synonym of a now() function on the DB side ?If yes, I am assuming you want the value retrieved from the DB after the insert and assigned to yourobject on created_date, is that correct ?Could you live with this solution :class YourClass(val z: Int,...) {val createdDate = new Date}?you can then choose to kep the defaultsTo declaration or not, if you do, it will only servefor inserts done with createdDate set to null. The only down side I can see is that youhave the createdDate created on the client when using Squeryl, and by the DB otherwise,so the two clocks must be reasonably in sync.CheersOn Mon, Nov 22, 2010 at 1:28 AM, Kristian Domagala <kristian...@gmail.com> wrote:
Hi,
Is it possible to define a schema in a way such that when records are inserted into the database, columns that have a default value expression specified in the database schema are initialised to those values, and not the values that are set on the corresponding entity?
For example, if there was an existing table with a created_date column that defaults to current_timestamp (ie, start of current transaction), would it be possible to use Squeryl and have the corresponding insert statement to be generated without the created_date column specification so that it uses the current_timestamp value instead?
I've had a look at the defaultsTo column declaration, but it only seems to affect how the DDL is generated, and from what I tell so far, is not used when constructing the insert query.
I hope I haven't missed any previous discussion about this, but I've only just started looking into Squeryl and couldn't find any relevant search results on the topic.
Cheers,
Kristian.