2017-08-23 7 views
0

私はSlickが初めてで、1つのトランザクションで動作するように次の2つのクエリを書き直そうとしています。1つのDBIOの結果を別のものに渡す

def createEmail(email: String): DBIO[Email] = { 
    // We create a projection of just the email column, since we're not inserting a value for the id column 
    (emails.map(p => p.email) 
     returning emails.map(_.id) 
     into ((email, id) => Email(id, email)) 
    ) += email 
    } 

    def findEmail(email: String): DBIO[Option[Email]] = 
    emails.filter(_.email === email).result.headOption 

にはどうすれば安全に、すなわち、それらをチェーンすることができます:私の目標は、要素が 2.リターン既存の要素が存在するか、それは2つの機能があるのMySQL

から自動インクリメントを取り扱う作成する場合1. にチェックです。最初に存在をチェックし、オブジェクトがすでに存在するかどうかを返します。存在しない場合は作成し、新しい要素を1つのトランザクションに返します。

答えて

3

あなたは理解のために使用することができます

def findOrCreate(email: String) = { 
    (for { 
    found <- findEmail(email) 
    em <- found match { 
     case Some(e) => DBIO.successful(e) 
     case None => createEmail(email) 
    } 
    } yield em).transactionally 
} 

val result = db.run(findOrCreate("[email protected]")) 
// Future[Email] 
+0

と 'db.run(findOrCreate( "[email protected]")トランザクション) 'を実行します。 – liosedhel

+0

@liosedhel:更新されました。 – chunjef

+0

あなたの助けにThx!サイドの質問 - 要素の下のピークに一致するパターンマッチングで 'e'にアクセスして' createEmail'に渡す方法はありますか?だから、私は例えば行うことができます。 'createEmail(e.name)' – Niemand

1

猫ライブラリの少しの助けを借りて:。

def findOrCreate(email: String): DBIO[Email] = { 
    OptionT(findEmail(email)).getOrElseF(createEmail(email)).transactionally 
} 
関連する問題