2016-07-25 26 views
1

いくつかの行を選択して更新し、更新された値を返したいのですが、どのように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

ありがとうございますが、正確には思いません。進行中のすべてのタスクではなく、ステータスが変更されたタスクだけを選択する必要があります。だから私は実行を待つタスクを選択し、それらをロックし、状態を更新してクライアントに返す必要があると思う。選択された行をロックせずに別のプロセスが同じことを行うと、ここでトランザクションが発生しますが、同時に2回選択されたタスクで終了する可能性があるため、ロックが重要です。だから私は、私が下書きとして3.2で利用可能なアップデートのためにselectを使用する必要があります。* –

+0

まだ準備が整っていないので、私はSlick 3.2を使用していません。私は私の答えを更新しましたが、うまくいけば今あなたの問題を解決します。更新前と更新後のすべてのタスクが実行され、その2つの間の差異が計算されます(実際には、そのトランザクションで更新されたタスクのみが返されます)。 –

関連する問題