2011-12-05 11 views
5

Estoy aprendiendo Squeryl y tratando de entender la sintaxis 'using' pero no puedo encontrar documentación sobre ella.Gestión de sesiones de Squeryl con 'using'

En el ejemplo siguiente se crean dos bases de datos, A contiene la palabra Hola, y B contiene adiós. La intención es consultar el contenido de A, tiene que poner la palabra Mundial y escribir el resultado a B.

salida de la consola esperado es mensaje insertado (2, HelloWorld)

object Test { 
    def main(args: Array[String]) { 
     Class.forName("org.h2.Driver"); 
     import Library._ 

     val sessionA = Session.create(DriverManager.getConnection(
       "jdbc:h2:file:data/dbA","sa","password"),new H2Adapter) 
     val sessionB = Session.create(DriverManager.getConnection(
       "jdbc:h2:file:data/dbB","sa","password"),new H2Adapter) 

     using(sessionA){ 
      drop; create 
      myTable.insert(Message(0,"Hello")) 
     } 
     using(sessionB){ 
      drop; create 
      myTable.insert(Message(0,"Goodbye")) 
     } 

     using(sessionA){ 
      val results = from(myTable)(s => select(s))//.toList 

      using(sessionB){ 
       results.foreach(m => { 
        val newMsg = m.copy(msg = (m.msg+"World")) 
        myTable.insert(newMsg) 
        println("Inserted "+newMsg) 
       }) 
      } 
     } 
    } 

    case class Message(val id: Long, val msg: String) extends KeyedEntity[Long] 
    object Library extends Schema { val myTable = table[Message] } 
} 

Como soportes, el código imprime mensaje insertado (2, GoodbyeWorld), a menos que toList se agregue al final de la línea val results.

¿Hay alguna manera de obligar a los resultados consulta para utilizar sesionesa incluso cuando se evaluó usando el interior del (sessionB)? Esto parece preferible al uso de a la lista para forzar a la consulta a evaluar y almacenar los contenidos en la memoria.

actualización

Gracias a la respuesta de Dave Whittaker, el siguiente fragmento de la fija sin tener que recurrir a 'toList' y corrige mi comprensión tanto de 'utilizar' y la gestión de consultas.

val results = from(myTable)(s => select(s)) 

using(sessionA){    
    results.foreach(m => { 
     val newMsg = m.copy(msg = (m.msg+"World")) 
     using(sessionB){myTable.insert(newMsg)} 
     println("Inserted "+newMsg) 
    }) 
} 

Respuesta

3

En primer lugar, me disculpo por la falta de documentación. La construcción using() es una nueva característica que solo está disponible en las compilaciones SNAPSHOT. De hecho, ayer hablé con Max sobre algunos de los problemas de documentación para los primeros usuarios y estamos trabajando para solucionarlos.

No hay una manera en que se me ocurra vincular una sesión específica a una consulta. En cuanto a su ejemplo, parece que un trabajo fácil sería invertir sus transacciones. Cuando crea una consulta, Squeryl no accede realmente al DB, solo crea un AST que representa el SQL que se realizará, por lo que no necesita emitir su uso (sessionA) en ese punto. Luego, cuando esté listo para iterar sobre los resultados, puede envolver la invocación de la consulta en un using (sessionA) anidado dentro de su using (sessionB). ¿Tiene sentido?

+0

Dave, gracias por todos sus esfuerzos en Squeryl, que ha transformado la forma en que considero ORM y ha confirmado mi compromiso con Scala. Me sorprende que el uso de() solo sea una instantánea, ya que estoy seguro de que saqué el contenedor del sitio web. He actualizado mi pregunta con su solución que realmente aclaró las cosas. – Pengin

Cuestiones relacionadas