2017-06-12 24 views
0

私はSlick 3.2に新しいScala Playアプリケーションでデータレイヤーを試してみたいと思います。私はいくつかの関連するテーブルに対するクエリからそれらのエンティティのケースクラス表現に少しでも挑戦しようとしています。アプリケーションは、即座に(データがシステムで更新されるたびに)、またはあるスケジュールで任意の宛先にデータを送信します。それは、次の3つのPostgresのテーブルで表されますがありSlick結合から親子関係のあるエンティティに移動する機能的な方法は?

case class Destination(endpoint: String, protocol: Protocol, exportTriggers: Seq[ExportTrigger]) 
case class ExportTrigger(triggerType: TriggerType, schedule: Option[ExportSchedule]) 
case class ExportSchedule(description: Option[String], cron: String) 

:(私は簡潔にするためオフに残してきた列挙型であるプロトコルとTriggerType)

CREATE TABLE destinations (
    destination_id SERIAL PRIMARY KEY, 
    endpoint VARCHAR(100) NOT NULL, 
    protocol VARCHAR(100) NOT NULL 
); 

CREATE TABLE export_triggers (
    export_trigger_id SERIAL PRIMARY KEY, 
    job_id INTEGER NOT NULL REFERENCES jobs, 
    destination_id INTEGER NOT NULL REFERENCES destinations, 
    trigger_type VARCHAR(50) NOT NULL, 
    export_schedule_id INTEGER REFERENCES export_schedules 
); 

CREATE TABLE export_schedules (
    export_schedule_id SERIAL PRIMARY KEY, 
    description VARCHAR(1000), 
    cron VARCHAR(100) NOT NULL 
); 

次のケースクラスはScalaではエンティティを表します各テーブルの行を表すSlick Codegenによって生成されるケースクラスでもあります。それらはDestinationsRow,ExportTriggersRow,ExportSchedulesRowです。

宛先には多くのExportTriggersを含めることができ、ExportTriggerには0または1のExportSchedulesが含まれます。私はjobIdをとり、そのジョブのすべての宛先(トリガーとスケジュールを含む)を取得する関数getDestinations(jobId: Int)を実装しようとしています。ここでは、すべてのデータを取得する必要がありスリッククエリが(新しい行は読みやすくするために追加された)です:

ExportTriggers.filter(_.jobId === id) 
    join Destinations on (_.destinationId === _.destinationId) 
    joinLeft ExportSchedules on (_._1.exportScheduleId === _.exportScheduleId) 

この式のインナータイプはSeq[((ExportTriggersRow, DestinationsRow), Option[ExportSchedulesRow])]あるので、それは私が探していたモデルを作成する必要がありマッピングを含める必要がありますしかし、私は、フラットな列の列から機能的な方法でDestination->[ExportTrigger]->ExportSchedule構造に移行するのに苦労しています。何か案は?あなたが提供する情報と

+1

完全結合が必要なのか、それとも左結合で十分ですか?つまり、ExportTriggerRowを使用せずにExportScheduleRowを使用できますか? – thwiegan

+0

@thwiegan - 良い点。それは左結合でもよい。それを反映するために質問を更新しました。 – Jared

答えて

0

、私はこのようなものとなるだろう:

val result: Seq[((ExportTriggersRow, DestinationsRow), Option[ExportSchedulesRow])] 

val grouped: Seq[Destination] = result.groupBy { 
    case ((_, destinationRow), _) => destinationRow 
} map { 
    case (destinationRow, resultList) => 
     val triggers = resultList.map { 
      case ((triggerRow, _), optScheduleRow) => 
      val schedule = optScheduleRow.map { row => 
       ExportSchedule(row.description, row.cron) 
      } 

      ExportTrigger(TriggerType(triggerRow.triggerType), schedule) 
     } 
     Destination(destinationRow.endpoint, Protocol(destinationRow.protocol), triggers) 
} 

destinationRowによる最初のグループは、トリガーやオプションのスケジュールを変換し、最終的に目的地を作成します。

EDIT groupedの結果タイプを修正しました。もちろんDestinationsのシーケンスだけです。ExportTriggersを含んでいます。ExportSchedule

関連する問題