13

さまざまなクエリ コンポーネントを 1 つのクエリに構成するのに問題があります。私の目標は、一連の特性 (SoftDeletable、HasName、SortedByName、WithTimestamps など) を作成して、Table オブジェクトに簡単に組み合わせてその動作を追加できるようにすることです。

理想は次のようになります。

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.allQueryどうすればよいBaseModel.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*しているため、ケース クラス名を Table に渡すだけで、3 の問題は解決します。

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

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

1 に答える 1

1

あなたの問題が並べ替えを追加するだけの場合、それは flatMap だけの問題ではありませんか?

def sortBy[T,U,C](q: Query[T,U], col: NamedColumn[C]) = q.flatMap(_ => Query orderBy col)
于 2012-07-10T07:14:54.117 に答える