?

Log in

No account? Create an account
Нестандартные запросы в Slick. - Язык программирования Scala

> Recent Entries
> Archive
> Friends
> Profile
> Официальный сайт Scala

December 25th, 2017


Previous Entry Share
potan
07:33 pm - Нестандартные запросы в Slick.
Можно ли в Slick сформировать запрос, аналогичный такому?
select * from jr
       where (id1, id2) in (
         ('000002e4-6b99-45ac-9187-4d00b7b457fc', 'a1c4fa6f-370c-11e6-bb37-f832e4bd9ad8'),
         ('00011eaf-f65d-42a7-ae54-3b16dff65f22','4834f6b6-af4a-4cc5-88d6-924a84f0ef31'));

Стардарт SQL такое не поддерживает, но и MySQL, и Postgres его выполняют. Но в Slick как сделать из двух slick.lifted.Rep[String] одну slick.lifted.Rep[(String,String)] я не нашел. Это вообще возможно?

(8 comments | Leave a comment)

Comments:


[User Picture]
From:_xacid_
Date:December 26th, 2017 02:10 am (UTC)
(Link)
а чем такой запрос отличается от такого?
select * from jr
       where id1 in ('000002e4-6b99-45ac-9187-4d00b7b457fc', 'a1c4fa6f-370c-11e6-bb37-f832e4bd9ad8')
          and id2 in ('00011eaf-f65d-42a7-ae54-3b16dff65f22','4834f6b6-af4a-4cc5-88d6-924a84f0ef31');

т.е. например
 for { c <- coffees if
        c.name.inSet(Seq("Colombian", "Espresso")) &&
        c.price.inSet(Seq(7.99, 9.99))
    } yield c.*


Edited at 2017-12-26 02:26 am (UTC)
[User Picture]
From:potan
Date:December 26th, 2017 10:30 am (UTC)
(Link)
Тем, что второй найдет и name='Colombian',price=7.99 и name='Colombian',price=9.99.
[User Picture]
From:_xacid_
Date:December 26th, 2017 01:39 pm (UTC)
(Link)
  def qzip[T <: Table[_], A: BaseTypedType, B: BaseTypedType](q: TableQuery[T])(
    fa: T => Rep[A], fb: T => Rep[B])(as: Seq[A], bs: Seq[B]) = {

    def zipr(a: Rep[A], b: Rep[B]) = as.map(a === _).zip(bs.map(b === _))
      .map(ab => ab._1 && ab._2).reduce(_ || _)

    q.filter(t => zipr(fa(t), fb(t)))
  }

  qzip(coffees)(_.name, _.price)(Seq("Colombian", "Espresso"), Seq(7.99, 9.99))



Edited at 2017-12-26 01:45 pm (UTC)
[User Picture]
From:potan
Date:December 26th, 2017 02:04 pm (UTC)
(Link)
Это все-таки генерируемый запрос усложняет. А время на компиляцию запроса Slick и так тратит много.
Хотя работать, конечно, будет.
[User Picture]
From:_xacid_
Date:December 26th, 2017 02:24 pm (UTC)
(Link)
зато это будет работать с любой sql базой
[User Picture]
From:_xacid_
Date:December 26th, 2017 06:53 pm (UTC)
(Link)
можно еще вот так
    def qzip[A:GetResult, B:GetResult](table: String,
                              a: String, b: String, abs: (A, B)*) =
      sql"""select #$a, #$b from #$table
        where (#$a,#$b) in (#${abs.mkString(",")})
        """.as[(A, B)]

      qzip("coffees", "cof_name", "price",
        "'Colombian'" -> 7.99,
        "'Espresso'" -> 9.99)
[User Picture]
From:_xacid_
Date:December 26th, 2017 09:45 pm (UTC)
(Link)
Вобщем оказалось что из двух Rep сделать один Rep "не сложно":
object MyProfile extends H2Profile {
  import java.sql.{PreparedStatement, ResultSet}

  import slick.ast.{BaseTypedType, ProductNode, ScalaBaseType, Type}
  import slick.lifted.{BaseColumnExtensionMethods, Rep}
  import slick.util.ConstArray

  object implicits {
    implicit def prodType[A: Ordering, B: Ordering] = new ScalaBaseType[(A, B)]

    implicit def prodRep[A: Ordering, B: Ordering](p: (Rep[A], Rep[B])): Rep[(A, B)] =
      Rep.forNode(ProductNode(ConstArray(p._1.toNode, p._2.toNode)))

    implicit def prodExt[A: Ordering, B: Ordering](c: (Rep[A], Rep[B])): BaseColumnExtensionMethods[(A, B)] =
      new BaseColumnExtensionMethods[(A, B)](c)
  }

  object ProdJdbcType extends DriverJdbcType[Any] {
    def sqlType = ???
    def setValue(v: Any, p: PreparedStatement, idx: Int) = ???
    def getValue(r: ResultSet, idx: Int) = ???
    def updateValue(v: Any, r: ResultSet, idx: Int) = ???
  }

  override def jdbcTypeFor(t: Type) =
    if (t.classTag.runtimeClass == classOf[Tuple2[_, _]])
      ProdJdbcType else super.jdbcTypeFor(t)

}

  import MyProfile.api._
  import MyProfile.implicits._

  val q2 = for {
      c <- coffees if (c.name, c.price).inSet(
        Seq("'Colombian'" -> 7.99, "'Espresso'" -> 9.99))
    } yield c.*



Edited at 2017-12-26 09:53 pm (UTC)
[User Picture]
From:potan
Date:December 27th, 2017 11:01 am (UTC)
(Link)
Спасибо, это то, что надо!

> Go to Top
LiveJournal.com