如何重用Slick查询

时间:2015-04-25 05:43:44

标签: scala slick

我的表格定义是

class Ipv4ToCountries(tag: Tag) extends Table[(Long, String)](tag, "IP2COUNTRIES") {
  def ip = column[Long]("IP")
  def country = column[String]("COUNTRY")

  def * = (ip, country)
}

class Ipv6ToCountries(tag: Tag) extends Table[(BigDecimal, String)](tag, "IPV6_2COUNTRIES") {
  def ip = column[BigDecimal]("IP")
  def country = column[String]("COUNTRY")

  def * = (ip, country)
}

class Country2Languages(tag: Tag) extends Table[(String, String, String)](tag, "COUNTRY2LANGUAGES") {
  def code = column[String]("CODE")
  def lang_code = column[String]("LANG_CODE")
  def iso_country = column[String]("ISO_COUNTRY")

  def * = (code, lang_code, iso_country)
}

请注意,Ipv4ToCountriesIpv6ToCountries之间的唯一区别是ip列的类型。这是我的查询功能:

  def getLangCode(ip: String): Future[String] = {
    InetAddress.getByName(ip) match {
      case ipv4: Inet4Address =>
        val q = (for {
          i <- ipv4s.sortBy(_.ip.desc) if i.ip < ipv4ToLong(ipv4)
          c <- ip2nationCountries if i.country === c.code
        } yield c.lang_code).take(1)
        db.run(q.result.head)
      case ipv6: Inet6Address =>
        val q = (for {
          i <- ipv6s.sortBy(_.ip.desc) if i.ip < ipv6ToDecimal(ipv6)
          c <- ip2nationCountries if i.country === c.code
        } yield c.lang_code).take(1)
        db.run(q.result.head)
    }
  }

IPv4和IPv6的查询几乎相同,但条件为if i.ip < addrToNumeric

有没有办法重用查询?

1 个答案:

答案 0 :(得分:1)

您可以拥有一个通用的参数化类,如

class IpToContries[A: TypeMapper](t: Tag, s: String) extends Table[(A, String)](t, s) {
  def ip = column[A]("IP")
  def country = column[String]("COUNTRY")

  def * = (ip, country)
}

然后像

一样使用它
class Ipv4Countries(tag: Tag) extends IpToContries[Long](tag, "IP2COUNTRIES")
class Ipv6Countries(tag: Tag) extends IpToContries[BigDecimal](tag, "IPV6_2COUNTRIES")

我还没有对它进行过测试,但是TypeMapper上的A上下文应该指定足以以这种方式使用的泛型类型。