2017-01-22 12 views
1

У меня есть модель языка, таблица и репозиторий. Пока это работает:Борьба с универсальными методами репозитория

package repositories 

import javax.inject.Inject 

import Helper 
import model.{Language, LanguageModel} 
import play.api.Logger 
import play.api.cache.SyncCacheApi 
import slick.jdbc.JdbcProfile 

import scala.concurrent.{ExecutionContext, Future} 
import scala.util.{Failure, Success} 

class LanguageRepository @Inject()(cache: SyncCacheApi, jdbcProfile: JdbcProfile, implicit val executionContext: ExecutionContext) 
{ 
    private val model = new LanguageModel(jdbcProfile) 

    import jdbcProfile.api._ 

    def all(userName: String): Future[Seq[Language]] = 
    { 
    cache.get[Future[Seq[Language]]](buildCacheKey(userName)) match 
    { 
     case Some(x) => {Logger.info("[LanguageRepository](all) Found something in cache"); x} 
     case None => { 
     Logger.info("[LanguageRepository](all) Nothing useful to be found in cache, calling database now") 
     val result = retrieve(userName) 
     result.onComplete{ 
      case Success(value) => if(!value.isEmpty) cache.set(buildCacheKey(userName), result) 
      case Failure(e) =>() 
     } 

     result 
     } 
    } 
    } 

    private def retrieve(userName: String): Future[Seq[Language]] = 
    { 
    // TODO extract this to a repositoryTrait and implement fallbacks etc 
    val db = Database.forURL(Helper.getDbUrl(), driver = Helper.getDbDriver()) 

    db.run(model.all.result) 
    } 

    private def buildCacheKey(userName: String): String = s"$userName.languages" 
} 

Теперь я борюсь с сегодняшним прошлым мимо меня, оставив меня.

Итак, я создал эту черту и хотел, чтобы она была расширена LanguageRepository, чтобы избавиться от этого общего метода извлечения, который должен быть одинаковым для всех репозиториев/моделей. Но, к сожалению, не повезло до сих пор:

trait Repository 
{ 
    type Entity 
    val model: Base 
    val profile: JdbcProfile 

    import profile.api._ 

    protected def retrieve(userName: String): Future[Seq[Entity]] = 
    { 
    val db = Database.forURL(Helper.getDbUrl(), driver = Helper.getDbDriver())  
    db.run(model.all.result) 
    } 
} 

Это является базой:

trait Base 
{ 
    val dbProfile: JdbcProfile 
    import dbProfile.api._ 

    type Entity 
    type EntityTable <: Table[Entity] 
    lazy val all = TableQuery[EntityTable] 
} 

Здесь я получаю требуется одна ошибка >> тип класса, но Base.this.EntityTable нашел

class LanguageModel(databaseProfile: JdbcProfile) extends Base 
    { 
    override val dbProfile: JdbcProfile = databaseProfile 
    import dbProfile.api._ 

    ... 

    override type EntityTable = LanguageTable 
    } 

Repository сам не компилируется, потому что типы не совпадают. Есть несколько проблем, и я не уверен, с чего начать их решать.

ответ

1

Определение базовой таблицы не будет работать так. Вам нужны типы классов, возможно, вам нужны дженерики. Кроме того, вместо создания нескольких абстракций начинайте с одной абстракции и развивайтесь оттуда. Попробуйте что-нибудь в этом направлении:

class Repository[A, B <: Table[A]](t: TableQuery[B]) { 
    val model = t 
    //protected def retrieve .. 
} 

class LanguageModel(databaseProfile: JdbcProfile) extends Repository[Language, LanguageTable](TableQuery[LanguageTable]) { 
    //... 
} 

Получить все, чтобы скомпилировать сначала, а затем начать добавлять абстракцию по одному классу за раз.

+0

Модель не является хранилищем, хотя – Sorona

 Смежные вопросы

  • Нет связанных вопросов^_^