2012-06-03 13 views
13

異なるクエリコンポーネントを1つのクエリにまとめるのに問題があります。私の目標は、テーブルオブジェクトに単純にミックスインしてその動作を追加することができる一連の特性(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タイプのパラメータを使用する必要がないことに気付きました。ケースクラスはProduct*を実装しているので、あなただけの3で問題を解決して表へのケースクラス名、渡すことができます:あなたの問題は、唯一の並べ替えを追加している場合

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.mapに渡すことができる関数があります。 。 – nafg

+0

Btw私はこの問題の一部に取り組んでいます: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) 
関連する問題