2013-03-06 1 views
1

Предположим, что у меня есть класс сущностей так:Squeryl: как переключить булево столбец с помощью частичного обновления

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

Я хочу выполнить следующее обновление SQL с помощью Squeryl:

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 documentation дает этот пример частичного обновления для увеличения целого значения от 1:

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

Обновление:

Я использую Squeryl 0.9.5-6 с Scala 2.10 и Play! 2.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) 

Либо тиражирование код в моем классе (для отладки) или установив точку останова непосредственно в таблице .scala

Чтобы выделить заявление, просто вынесем вторую часть обновления:

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

Благодаря этому «трюк», я обнаружил, что реф свойство some_flag корректно преобразуется в SelectElementReference типа java.lang.Boolean, но (!) не перераспределяется в PrefixOperator. Мне кажется, что это ошибка squeryl, но позвольте мне посмотреть, можно ли «исправить» ее из вашего кода.

UPDATE:

Покопавшись в squeryl коде, это действительно кажется, что "не" оператор отсутствует. К счастью, его легко добавить обратно!

 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 и попрошу комментарии.

+0

Я уже пробовал это, он не компилирует –

+0

@ErichSchreiner ops .. извините, моя ошибка: я вспоминал, что это было решением старой проблемы, которая у меня была, но она была в предложении where (я уверен, это жалуется, что он не хочет LogicalBoolean ..) Позвольте мне выкопать какой-то старый код и посмотреть, что я сделал с набором –

+0

@ErichSchreiner Я обновил ответ своими выводами –

Смежные вопросы