Squeryl управление сессиями с использованием - PullRequest
5 голосов
/ 06 декабря 2011

Я изучаю Squeryl и пытаюсь понять синтаксис «using», но не могу найти документацию по нему.

В следующем примере создаются две базы данных, A содержит слово Hello , а B содержит До свидания .Намерение состоит в том, чтобы запросить содержимое 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] }
}

В текущем виде код печатает Вставленное сообщение (2, GoodbyeWorld) , если только toList не добавлен в конце val results line.

Есть ли способ связать запрос results для использования sessionA даже при оценке внутри с использованием (sessionB) ?Это кажется предпочтительным, если использовать toList , чтобы запрос оценивал и сохранял содержимое в памяти.

Обновление

Благодаря ответу Дейва Уиттакера,следующий фрагмент исправляет его, не прибегая к «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 Ответ

3 голосов
/ 06 декабря 2011

Прежде всего, я прошу прощения за отсутствие документации. Конструкция using () - это новая функция, которая доступна только в сборках SNAPSHOT. Я вчера говорил с Максом о некоторых проблемах с документацией для первых пользователей, и мы работаем над их устранением.

Нет способа связать конкретную сессию с запросом. Глядя на ваш пример, кажется, что можно легко обойти ваши транзакции. Когда вы создаете запрос, Squeryl на самом деле не обращается к БД, он просто создает AST, представляющий SQL для выполнения, поэтому вам не нужно выдавать свое использование (sessionA) на этом этапе. Затем, когда вы будете готовы перебрать результаты, вы можете заключить вызов запроса в использование (sessionA), вложенное в ваше использование (sessionB). Имеет ли это смысл?

...