2011-12-05 22 views
5

Sto imparando Squeryl e sto cercando di capire la sintassi 'using' ma non riesco a trovare la documentazione su di esso.Gestione della sessione di Squeryl con 'using'

Nell'esempio seguente vengono creati due database, A contiene la parola Ciao e B contiene Addio. L'intenzione è quella di interrogare il contenuto di A, quindi aggiungere la parola mondo e scrivere il risultato a B.

uscita della console è prevista Inserito Message (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] } 
} 

Come sta, il codice viene stampato Messaggio inserito (2, GoodbyeWorld), a meno che l'elenco sia aggiunto alla fine della riga val dei risultati val.

C'è qualche modo per legare le risultati query per utilizzare sessionA anche quando valutata all'interno del utilizzando (sessionB)? Sembra preferibile utilizzare l'elenco nell'elenco per forzare la query a valutare e archiviare il contenuto in memoria.

Aggiornamento

Grazie alla risposta di Dave Whittaker, il seguente frammento lo fissa senza ricorrere a 'toList' e corregge la mia comprensione sia 'con' e l'esecuzione di query.

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) 
    }) 
} 

risposta

3

Prima di tutto, mi scuso per la mancanza di documentazione. Il costrutto using() è una nuova funzionalità che è disponibile solo nelle build SNAPSHOT. Ieri ho parlato con Max di alcuni dei problemi di documentazione per i primi utenti e stiamo lavorando per risolverli.

Non c'è un modo che possa pensare per associare una sessione specifica a una query. Guardando il tuo esempio, sembra che un semplice intervento potrebbe essere quello di invertire le transazioni. Quando si crea una query, Squeryl non accede effettivamente al DB, ma crea semplicemente un AST che rappresenta l'SQL da eseguire, quindi non è necessario eseguire l'utilizzo (sessioneA) in quel punto. Quindi, quando si è pronti ad eseguire iterazioni sui risultati, è possibile racchiudere l'invocazione della query in un utilizzo (sessionA) nidificato all'interno dell'utente (sessioneB). Ha senso?

+0

Dave, grazie per tutti i vostri sforzi su Squeryl, che ha trasformato il modo in cui considero ORM e ha confermato il mio impegno con Scala. Sono sorpreso che l'uso di() dovrebbe essere solo nell'istantanea, poiché sono sicuro che ho appena estratto il barattolo dal sito web. Ho aggiornato la mia domanda con la tua soluzione che ha davvero chiarito le cose. – Pengin

Problemi correlati