1

次のようなエンティティ クラスがあるとします。

case class MyEntity(some_flag: Boolean) extends KeyedEntity[Long]

Squeryl を使用して次の SQL 更新を実行したいと考えています。

update table_name set some_flag = not some_flag where id = 1

これを行うための関連する Squeryl ステートメントは何ですか? 私はすでに試しました

def toggleFlag(id: Long) = inTransaction {
    update(table)(entity =>
        where(entity.id === id)
        set(entity.some_flag := !entity.some_flag)
    )
}

ただし、これはデータベースには影響しません。

更新 2: Squerylのドキュメントでは、整数値を 1 ずつ増やす部分的な更新の例を示しています。

update(songs)(s =>
  where(s.title === "Watermelon Man")
  set(s.title := "The Watermelon Man",
      s.year  := s.year.~ + 1)
)  

アップデート:

Scala 2.10 と Play! で Squeryl 0.9.5-6 を使用しています。2.1

4

1 に答える 1

1

あなたの例から小さなコードプロジェクトを作成しました。問題は、squeryl が更新をシリアル化することですが、(!) を「飲み込み」、次の SQL を生成することです。

 update MyEntity set
 some_flag = (some_flag)

基本的に、squeryl は操作で構成されるツリーを内部で構築し、それを SQL アダプターに送信される文字列にシリアル化します。

一般に、更新ステートメントを分離して印刷することを確認します(squerylのように):

    // From __update, Table.scala
    val dba = Session.currentSession.databaseAdapter
    val sw = new StatementWriter(dba)
    val o0 = _callbacks.beforeUpdate(o.asInstanceOf[AnyRef]).asInstanceOf[T]
    dba.writeUpdate(o0, this, sw, checkOCC)

クラスでコードを複製する (デバッグ目的で) か、Table.scala で直接ブレークポイントを設定する

ステートメントを分離するには、単純に update の 2 番目の部分を除外します。

val s = ((entity: InsertTypeHere) =>
      where(entity.id === id)
      set(entity.some_flag := not entity.some_flag))

この「トリック」のおかげで、some_flag への参照は java.lang.Boolean 型の SelectElementReference に正しく変換されますが、(!) は PrefixOperator に変換されないことがわかりました。私にはスクエリルのバグのように思えますが、コードから「修正」できるかどうか見てみましょう。

アップデート:

squeryl コードを掘り下げると、「not」演算子が欠落しているように見えます。幸いなことに、自分で簡単に元に戻すことができます!

     class NotExpression(val ast: ExpressionNode)(implicit val mapper: OutMapper[BooleanType])
        extends PrefixOperatorNode(ast, "not ", false)
                with LogicalBoolean with NestedExpression with TypedExpressionNode[BooleanType]

     def mynot(b: BooleanExpression[BooleanType]) = new NotExpression(b)

     transaction {
          update(table)(t => where(t.id === 3) set (t.some_flag := mynot(t.some_flag)))
     }

これにより、少なくともあなたの場合は正しい SQL が生成されます。squeryl にパッチを提出し、コメントを求めます。

于 2013-03-06T09:34:08.163 に答える