Скверил сессионное управление с использованием
Я изучаю Squeryl и пытаюсь понять синтаксис "using", но не могу найти документацию по нему.
В следующем примере создаются две базы данных: A содержит слово Hello, а B содержит Goodbye. Намерение состоит в том, чтобы запросить содержимое A, затем добавить слово World и записать результат в B.
Ожидаемый вывод на консоль - вставленное сообщение (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] }
}
В нынешнем виде код печатает Inserted Message (2, GoodbyeWorld), если toList не добавлен в конец строки результатов val.
Есть ли какой-нибудь способ привязать запрос результатов к использованию sessionA, даже если он оценивается внутри using (sessionB)? Это кажется более предпочтительным, чем использование toList, чтобы заставить запрос оценивать и хранить содержимое в памяти.
Обновить
Благодаря ответу Дейва Уиттекера следующий фрагмент исправляет его, не прибегая к "списку", и исправляет мое понимание как "использования", так и выполнения запросов.
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)
})
}
1 ответ
Прежде всего, я прошу прощения за отсутствие документации. Конструкция using() - это новая функция, которая доступна только в сборках SNAPSHOT. На самом деле я вчера говорил с Максом о некоторых проблемах с документацией для первых пользователей, и мы работаем над их устранением.
Я не могу придумать, как связать конкретную сессию с запросом. Глядя на ваш пример, кажется, что можно легко обойти ваши транзакции. Когда вы создаете запрос, Squeryl на самом деле не обращается к БД, он просто создает AST, представляющий SQL, который нужно выполнить, поэтому вам не нужно выдавать свое использование (sessionA) на этом этапе. Затем, когда вы будете готовы перебрать результаты, вы можете заключить вызов запроса в использование (sessionA), вложенное в ваше использование (sessionB). Имеет ли это смысл?