2017-01-27 8 views
0

私は実際にテーブルに対してデータベース行を更新する以下の方法を持っています。特定の条件が存在する場合はエントリを最初にチェックし、エントリが存在する場合にのみ対応する行を更新します。したがって、データベースには2つの呼び出しが行われます。私は2つの呼び出しをデータベースに送信することを避けたいと思います。だからここのコードは次のとおりです。Slick 3.0の条件に基づいた更新行

def confirmUserRegistration(hash: String) = async { 
    val query = UserRegistrationTable.registrationForHash(hash) 
    val isRowAvailable = await(database.run(query.result.headOption)) 
    if (isRowAvailable.isDefined) { 
     // do the update 
    } else { 
    // do nothing and return 
    } 
    } 

UserRegistrationTable.registrationForHash(ハッシュ)クエリは次のようになります。

object UserRegistrationTable { 

    val all = TableQuery[UserRegistrationTable] 

    val registrationForHash = (hash: String) => { 
     all.filter(_.registrationHash === hash) 
    } 
    } 

それでは、どのように私は、データベースへの唯一のコールを発行するために私のサービスを最適化することができますか?

EDIT:以下、ポストによって与えられたフィードバックを更新:

ここでは私の方法がどのように見えるかです:

def confirmUserRegistration(hash: String) = async { 
    val query = { 
     UserRegistrationTable.registrationForHash(hash) 
     .map(_.hasUserConfirmed) 
     .update(true) 
    } 

    val isUpdated: Int = await(database.run(query)) 

    } 

答えて

1

ただ、次の更新を使用します。updateResultこと

val updateOperation: DBIO[Int] = all 
    .filter(_.registrationHash === hash) 
    .map(u => (u.field1, u.field2, u.field3)) 
    .update((newValue1, newValue2, newValue3)) 

お知らせ上記の値はDBIOであり、更新された行の数はIntです。

だから、あなたが行うことができます:

val userRegistration: UserRegistrationCaseClass = ... 

val updateOperation: DBIO[Int] = all 
    .filter(_.registrationHash === hash) 
    .update(newUserRegistration) 
+0

なしのであればそれは意味:あなたはあなたのケースクラスを使用することができ、更新行全体に望んでいたが、私はそれはあなたが望むものである疑う場合

db.run(updateOperation).map { updatedRows => if(updatedRows >= 0) { // at least one row was affected, return something here } else { // nothing got updated, return something here } } 

の行が更新された場合、Intの値は0になりますか? – sparkr

+0

それは正しいです。それは 'DBIO [Int]'であることを覚えておいてください。最初に 'db.run(...)'し、 'Future'を' map'する必要があります –

+0

私はScala非同期マクロを使用します。私は今私のポストを更新しました。 – sparkr

関連する問題