2015-04-25 45 views
1

我的表定義如何重新油滑查詢

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

你可以有一個像

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") 

我沒有測試過,但勢必對ATypeMapper方面應指定泛型類型足以以這種方式使用。

+0

我確認這工作正常。您也可以在類中定義泛型查詢,如下所示:'class IpToContriesQueries [E <:IpToContries](val table:TableQuery [E]){}' – OlivierBlanvillain