2012-06-03 18 views
13

我在將不同的查詢組件組合成單個查詢時遇到了一些麻煩。我的目標是創建一組特徵(例如SoftDeletable,HasName,SortedByName,WithTimestamps),我可以簡單地將它們混合到Table對象中以添加該行爲。如何在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和排序在SortedByName.allQueryBaseModel.allQuery

  2. 通過在*方法的子類實現添加列,元組類型參數Table沒有後者的比賽 - 是有這些特徵的方式來逐步添加新類型的列在最終的具體類元組? (我不指望會有,但如果有什麼我不知道的話會很好)。

  3. 我需要在每個特徵中重複長元組聲明,如果一個表有五列或六列,這將變得非常不便。有什麼我可以用類型成員做,以避免不得不做這樣的事情:

    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類型參數。由於案件類實現Product*,你可以通過的情況下類名稱爲表,解決了3個問題:

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

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

不是答案本身,但如果你能有從返回其列,兩個性狀的表型的功能,然後將它們結合起來(F1,F2)=>(T:table.type) =>(f1(t),f2(t)),你有一個可以傳遞給map的函數,它相當於table.map(t =>((trait1col2,trait1col2),(trait2col1,trait2col2))) 。 – nafg

+0

順便說一句我想解決這個問題的一部分在這裏:http://stackoverflow.com/questions/11408072/trouble-getting-scala-type-in​​ference-to-work – nafg

回答

1

如果您的問題只增加了排序,是不是隻是一個flatMap的事?

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