Перепишите этот запрос SQL, используя scala slick - PullRequest
0 голосов
/ 30 мая 2020
class ItemTable(tag: Tag) extends Table[Item](tag, _tableName = "items") {

  def id: Rep[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def authId: Rep[String] = column[String]("auth_id")
  def productId: Rep[Int] = column[Int]("product_id")
  def position: Rep[Int] = column[Int]("position")

  override def * : ProvenShape[Item] = (id, authId, productId, position) <> ((Item.apply _).tupled, Item.unapply)
}


class ItemService @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)(implicit executionContext: ExecutionContext) {

    private lazy val query = TableQuery[ItemTable]
    def updateItem(item: Item, previousPosition: Int): Future[Item] = {

        if (previousPosition < item.position) {
          // this is the sql I want to convert to slick
          db.run(sqlu""" UPDATE #${query.baseTableRow.tableName} SET position = position - 1 WHERE position >= #$previousPosition AND position <= #${item.position} AND auth_id = '#${item.authId}'""")
        }
        else if (previousPosition > item.position) {
          db.run(sqlu""" UPDATE #${query.baseTableRow.tableName} SET position = position + 1 WHERE position <= #$previousPosition AND position >= #${item.position} AND auth_id = '#${item.authId}' """)
        }
        else {
         // some other code
        }
    }
}

case class Item(id: Int, authId: String, productId: Int, position: Int){}

У меня SQL работает, вот застрял переводить на слик.

val q2 = query.filter(f=> f.authId === item.authId && f.position >= previousPosition && f.position <= item.position)

// Я не знаю, как обновить несколько или передать результат в функцию обновления

1 Ответ

1 голос
/ 30 мая 2020

Встроенный стиль Slick не поддерживает динамические c изменяющиеся пакетные обновления формы SET position = position + 1 ( Slick issue 497 ).

Это означает использование Plain SQL стиль, который у вас уже есть, является правильным подходом.

Дополнительное примечание по идиоматике c sqlu: Я заметил sqlu, который у вас есть, использует "сплайсинг" (#$ для имени таблицы). Это не позволяет Slick обрабатывать значение как строку, что соответствует тому, что вы делаете. Но более позднее использование #$previousPosition обычно записывается как простая подстановка $previousPosition. Это потому, что вы обычно хотите, чтобы параметр SQL был правильно экранирован Slick. Вероятно, это не повлияет на целые числа, но может повлиять на другие типы данных.

...