2012-06-03 2 views
13

다른 쿼리 구성 요소를 하나의 쿼리로 구성하는 데 문제가 있습니다. 필자의 목표는 표 객체에 믹스 인하여 해당 동작을 추가 할 수있는 특성 집합 (예 : SoftDeletable, HasName, SortedByName, WithTimestamps)을 만드는 것입니다.재사용 가능한 특성을 만들기 위해 ScalaQuery에서 쿼리를 작성하려면 어떻게해야합니까?

이상은 같을 것이다 :

abstract class BaseModel[Tuple <: Product,CaseClass](tableName: String) 
    extends Table[Tuple](tableName) { 
    def id = column[Int]("id", O.AutoInc, O.PrimaryKey) 

    def mapped: MappedProjection[CaseClass, TupleClass] 

    def allQuery = this.map(_.mapped) 
    final def all = database.withSession { implicit session: Session => 
    allQuery.list() 
    } 

    ... 
} 

trait SoftDeletable[Tuple <: Product, CaseClass] 
    extends BaseModel[Tuple,CaseClass] { 
    def isActive = column[String]("is_active") 

    def * = super.* ~ isActive 
    def allQuery = /* here, I'd like to compose super.allQuery 
        with a filter that returns rows where isActive is true */ 
} 

trait HasName[Tuple <: Product] extends Table[Tuple] { 
    def name = column[String]("name") 

    def * = super.* ~ name 
} 

trait SortedByName[Tuple <: Product] extends HasName[Tuple { 
    override def allQuery = super.allQuery /* compose somehow 
              with (_ <- Query orderBy name */ 
} 

내가 ScalaQuery 물건 이러한 종류의 할 수 있습니까? 주요 고집 포인트는

  1. 어떻게 깨끗하게 SoftDeletable.allQuery에 필터를 작성하고 BaseModel.allQuerySortedByName.allQuery에 정렬합니까? * 방법의 서브 클래스 구현에 열을 추가함으로써

  2. , Table없는 후자의 경기에 튜플 형식 매개 변수 - 열이 궁극적 인 구상 클래스에서 튜플에 점진적으로 새로운 유형을 추가하려면 다음 특성에 대한 방법은 무엇입니까? (나는있을 것이라고는 기대하지 않지만, 내가 놓친 것이 있다면 좋을 것이다.)

  3. 모든 특성에서 긴 튜플 선언을 반복해야하는데 테이블에 5 개 또는 6 개의 열이 있으면 매우 다루기 힘들어집니다.

    case class Foo 
    
    class Foos[(Int,Int,Boolean,String), Foo] extends 
        Table[(Int,Int,Boolean,String)] with 
        SoftDeletable[(Int,Int,Boolean,String), Foo] with 
        SortedByName[(Int,Int,Boolean,String), Foo] with 
        HasName[(Int,Int,Boolean,String)] { 
    } 
    

내가이 모든 반복을 피할 수 있습니다 : 내가 좋아하는 일을하는 것을 피하기 위해 형의 회원들과 함께 할 수있는 뭔가가 있나요? IRC에 jesnor에서 제안을 바탕으로, 내가 지금처럼이 중 일부를 피할 수 있었다 : 즉

abstract class SoftDeletableBaseModel[TupleClass <: Product, CaseClass](tableName: String) 
     extends BaseModel[TupleClass, CaseClass](tableName) 
     with SoftDeletable[TupleClass,CaseClass] 

함께 특정 특성을 결합하여, 나는 전체 튜플 선언을 반복 할 필요가 없습니다; 물론, 단점은 다양한 형질의 혼합이 더 이상 가능하지 않다는 것입니다.이 반복을 피하기 위해 많은 특정 서브 클래스를 생성해야합니다. 다른 방법이 있습니까?

업데이트 : 그렇기 때문에 별도의 CaseClass 및 TupleClass 유형 매개 변수를 사용할 필요가 없음을 알았습니다. 문제는 정렬을 추가

trait SoftDeletable[CaseClass] extends BaseModel[CaseClass] { ... } 

class Models extends BaseModel[Model]("models") with SoftDeletable[Model] { ... } 
+0

되지 않음 대답 자체,하지만 당신은 두 형질, 그 열을 반환하는 테이블 형식에서 함수를 한 다음 전원을 결합 할 수있는 경우 (F1, F2) => (t : table.type) = ((trait1col2, trait1col2), (trait2col1, trait2col2))))와 같을 map에 전달할 수있는 함수가있다. (f1 (t), f2 . – nafg

+0

Btw 나는이 문제의 일부를 여기에서 다루려고 노력하고있다 : http://stackoverflow.com/questions/11408072/trouble-getting-scala-type-inference-to-work – nafg

답변

1

경우, flatMap의 문제되지 않습니다 : 경우 클래스 Product*을 구현하기 때문에, 당신은 단지 3 문제가 해결 표에 경우 클래스 이름을 전달할 수 있습니다?

def sortBy[T,U,C](q: Query[T,U], col: NamedColumn[C]) = q.flatMap(_ => Query orderBy col)