Suppose I have an entity class like that:
case class MyEntity(some_flag: Boolean) extends KeyedEntity[Long]
I want to perform the following SQL update using Squeryl:
update table_name set some_flag = not some_flag where id = 1
What is the related Squeryl statement to do this? I have tried already
def toggleFlag(id: Long) = inTransaction {
update(table)(entity =>
where(entity.id === id)
set(entity.some_flag := !entity.some_flag)
)
}
but this does not have any effect in the database.
Update 2: The Squeryl documentation gives this example of a partial update to increase an integer value by 1:
update(songs)(s =>
where(s.title === "Watermelon Man")
set(s.title := "The Watermelon Man",
s.year := s.year.~ + 1)
)
Update:
I am using Squeryl 0.9.5-6 with Scala 2.10 and Play! 2.1
I made a little code project out of your example. The problem is that squeryl serializes the update, but it "swallows" the (!), producing the following SQL:
update MyEntity set
some_flag = (some_flag)
Basically, squeryl builds under the hood a tree made of operations, and then serializes it to a string that will be sent to the SQL adapter.
In general, I check it out isolating the update statement and printing it (like squeryl does):
// 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)
Either replicating the code in my class (for debugging purposes) or setting a breakpoint directly in Table.scala
To isolate the statement, simply factor out the second part of update:
val s = ((entity: InsertTypeHere) =>
where(entity.id === id)
set(entity.some_flag := not entity.some_flag))
Thanks to this "trick", I discovered that the reference to some_flag is correctly transformed into a SelectElementReference of type java.lang.Boolean, but the (!) is not traslated into a PrefixOperator. It seems like a squeryl bug to me, but let me see if it is possible to "fix" it from your code.
UPDATE:
Digging in squeryl code, it really seems that the "not" operator is missing. Fortunately, it is easy to add it back by yourself!
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)))
}
This produces the right SQL, at least in your case. I will submit a patch to squeryl and ask for comments.