2017-03-03 2 views
2
슬릭

에 LOCALDATE 및 옵션 [지능]의 합을 기준으로 및 각각 Option[Int].필터 쿼리 내가 DB의 두 개의 열이있는 테이블이

이제 날짜가 givenDate 인 쿼리를 작성하여 duration이 정의되고 startDate + duration < givenDate 인 모든 행을 다시 돌려줍니다.

나는 그런 식으로 뭔가를 기다리고 있었다 :

db.run(table.filter(t => { 
    t.duration.isDefined && 
    t.startDate < givenDate.minusDays(t.duration.getOrElse(0)) 
})) 

를 불행하게도, t.duration.getOrElse(0) 정말 정수,하지만 Rep[Int]하지 않기 때문에 작동하지 않습니다.

어떻게하면됩니까? 내가 사용

기술 : 스칼라, 귀하의 질문에 대한 슬릭 3.1, Joda 시간, 매끄러운 joda - 매퍼

+0

http://stackoverflow.com/questions/21349547/compare-2-dates-in-a-slick-query- 이 질문에 어려워 보이면 도움이 될 것입니다. –

+0

@KamilBanaszczyk 불행히도 이것은 도움이되지 않습니다. 나는 날짜를 비교할 수있다. (나는 '매끄러운 - 조다 - 매퍼'를 사용하고있다.) 내가 할 수없는 일은 쿼리에서 날짜를 수정 한 다음 비교하는 것입니다. – Alex

+0

나는 매끄러운 joda 매퍼가 어떻게 작동하는지 모르지만 Rep에 givenDate 랩을 시도 했습니까? 어쩌면 Rep [Int]에서 연산을 수행 할 수 있습니까? –

답변

0

OK, 내가 찾은 답. 따라서 기본적으로 데이터베이스 유형 안전성 때문에 Rep를 처리 할 수 ​​없습니다. 추가적으로 당신은 어떤 식 으로든 minusDays(t.duration.getOrElse(0))을 사용할 수없는 이유 인 데이터베이스 엔진 내에 scala 함수 을 호출 할 기회가 없습니다. Slick은 또한 을 모든 데이터 형식에서 구현하기위한 목적이 없으므로 데이터베이스 엔진이 다르기 때문에 마찬가지입니다. 그러나 데이터베이스에서 날짜 연산을 호출하려면 날짜 연산을 지원하는지 확인해야합니다. 내 예는 우리가 갈 여기, H2 데이터베이스에 :

정의 데이터

case class DateTest(id: Option[Int] = None, date: LocalDate, duration: Int) extends BaseEntity 

    class DateTestTable(tag: Tag) extends BaseTable[DateTest](tag, None, "DateTest") { 

    override val id: Rep[Option[Int]] = column[Option[Int]]("id", O.PrimaryKey, O.AutoInc) 

    def date: Rep[LocalDate] = column[LocalDate]("date") 

    def duration = column[Int]("duration") 

    def * = (id, date, duration) <>(DateTest.tupled, DateTest.unapply) 

    } 

    val dateTests: TableQuery[DateTestTable] = TableQuery[DateTestTable] 

삽입 된 데이터

H2Connector.dateTests ++= Seq(
    DateTest(Some(1), new LocalDate(2017,3,4),15), 
    DateTest(Some(2), new LocalDate(2017,2,17),15) 
) 

저장소

val addDays: (Rep[String], Rep[Int], Rep[LocalDate]) => Rep[LocalDate] = SimpleFunction.ternary[String,Int,LocalDate,LocalDate]("DATEADD") 

    def dateWithDuration(givenDate: LocalDate): Future[Seq[DateTest]] ={ 
    filter(auth => auth.date < addDays("DAY",auth.duration*(-1),givenDate)) 
    } 

코드의 마지막 부분에서 이것이 어떻게 구현되는지 볼 수 있습니다. 우선 H2는 DATEADD에이 작업을 지원하고 Slick은 데이터베이스 기능을 사용할 사용자 정의 함수를 구현할 수 있습니다. 이런 식으로 REP 랩핑 된 값을 사용할 수 있으며 유형 보증 구현을 통해 매끄러운 상태를 유지할 수 있습니다. 이러한 테스트를

:

"TestDate " should { 
    "return date with small duration " in { 
     println(waitForResult(testDate.dateWithDuration(new LocalDate(2017,3,15)))) 
    } 
    "return every date " in { 
     println(waitForResult(testDate.getAll)) 
    } 
    } 

결과는 :

Vector(DateTest(Some(2),2017-02-17,15)) 
Vector(DateTest(Some(1),2017-03-04,15), DateTest(Some(2),2017-02-17,15)) 
관련 문제