Scala reflection and Squeryl -
i'm working on first substantial project using scala, scalatra, , squeryl, , happened upon following problem: wanted have abstract base class daos provided simple implementation of basic crud operations (create, read, update, delete), needed way said abstract base class aware of table reference.
with squeryl, map data classes actual tables in singleton object extends squeryl.schema, , daos companion objects each class.
i came following solution using type tags:
first, excerpt of base class daos inherit (note: dbrecord sub of squeryl's keyedentity):
abstract class crudops[s <: dbrecord](implicit tt: typetag[s]) { def create(item: s)= { intransaction{ val result = atschema.recordtable.insert(item) } }
next, recordtable function in atschema:
object atschema extends schema { val users = table[user] def recordtable[t <: dbrecord](implicit tt: typetag[t]): table[t] = tt.tpe match { case t if t =:= typeof[user] => users.asinstanceof[table[t]] //...other table types go here case _ => throw new illegalargumentexception("unknown dbrecord type") } }
now, works, have several tables , crudops grabs right 1 , stuff. there's i'm not understanding (i'm still new scala): why need cast table vals in recordtable() table[t]? if remove .asinstanceof, type mismatch, users of type table[user]... seems ought unnecessary. also, has feel of complicated solution should trivial problem (maybe i'm abusing type system), , couples crudops schema (which avoid), open suggestions folks more scala and/or squeryl experience :)
it's not squeryl thing. understand it, problem pattern match testing done @ runtime, after type erasure has occurred. scala able keep type information around typetag , perform runtime check can't infer types correct @ compile time. if try like
case t: classtag[user] => users
which asking compiler static check, warning user type erased. way doing should work since should fine perform cast after you've verified type, , don't think there better way.
Comments
Post a Comment