2016-07-25 3 views
1

Я хочу выбрать некоторые строки, обновить их и вернуть обновленные значения, но я не понимаю, как это сделать с помощью Slick. Вот пример. Я хочу, чтобы выбрать все задачи, которые ожидающие выполнения, блокировать их, изменение статусов в ходе и вернуться обновленные задачи:Slick. Выберите и затем обновите выбранные строки.

object Test { 

    case class Task(id: Int, status: String) 

    class TaskTable(tag: Tag) extends Table[Task](tag, "tasks") { 
    def id = column[Int]("id") 
    def status = column[String]("status") 

    def * = (id, status) <>(Task.tupled, Task.unapply) 
    } 

    val tasks = TableQuery[TaskTable] 

    def selectWaitingTasksAndChangeStatus(): Seq[Task] = { 
    tasks.filter(_.status === "awaitingExecution").forUpdate 
    // Here I want to change status to "inProgress" and 
    // return tasks to client code with "inProgress" status 
    } 

} 
+0

Какую версию Slick вы используете? –

+0

@ Paweł Jurczenko 3.2.0-M1 –

ответ

0

ли это, что вы ищете?

import scala.concurrent.Await 
import scala.concurrent.duration.Duration 

def selectWaitingTasksAndChangeStatus(): Seq[Task] = { 
    val selectAction = tasks.filter(_.status === "inProgress").result 
    val updateAction = tasks.filter(_.status === "awaitingExecution").map(_.status).update("inProgress") 
    val combinedAction = for { 
    tasksBeforeUpdate <- selectAction 
    _     <- updateAction 
    tasksAfterUpdate <- selectAction 
    } yield tasksAfterUpdate.diff(tasksBeforeUpdate) 

    Await.result(db.run(combinedAction.transactionally), Duration.Inf) 
} 

Так как вы хотели бы получить Seq[Task] от этого метода, вы должны синхронно ждать результата из базы данных. Для асинхронного решения в качестве возвращаемого типа потребуется Future[Seq[Task]].

+0

Спасибо, но не совсем я думаю. Мне нужно выбрать только те задачи, статус которых был изменен, а не все выполняемые задачи. Поэтому я думаю, что мне нужно выбрать задачи, ожидающие выполнения, заблокировать их, обновить статус и вернуть их клиенту. И блокировка важна, потому что я предполагаю, что у нас есть транзакция здесь, если мы не блокируем выбранные строки, а другой процесс делает то же самое, в то же время я мог бы выполнить задачи, выбранные дважды. Поэтому мне нужно использовать select for update, который, как я понимаю, доступен только в 3.2. * –

+0

Я не использовал Slick 3.2, так как он еще не готов. Я обновил свой ответ, хотя, надеюсь, решает вашу проблему сейчас. Он выполняет все задачи до и после обновления и вычисляет разницу между этими двумя (которая эффективно возвращает только те задачи, которые были обновлены в этой транзакции). –

Смежные вопросы