Управление преобразованиями MappedColumnType в проекте slick 3

Я пытаюсь создать собственные преобразователи столбцов базы данных для нового проекта Slick 3. Это довольно легко сделать с помощью MappedColumnType, но вы должны импортировать API-интерфейс драйвера. Для одноразового типа в одном классе DAO это просто. Но я хотел бы использовать свои настраиваемые типы столбцов во всех моих объектах DAO. Мне не удалось построить свой импорт таким образом, чтобы компилятор мог распознать неявные значения.

Вот пример типа библиотеки, которую я хотел бы построить. Он имеет единственный преобразователь, очень похожий на вездесущий преобразователь дат Joda, который можно увидеть во многих примерах Slick 2.

package dao

import java.sql.Date

import data.Timestamp
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.driver.JdbcProfile

case class StandardConversions(protected val dbConfigProvider: DatabaseConfigProvider)
  extends HasDatabaseConfigProvider[JdbcProfile] {
  import driver.api._

  implicit val timestampColumnType = MappedColumnType.base[Timestamp, Date](
    { data => new Date(data.value) },
    { sql => Timestamp(sql.getTime) }
  )

}

В классе DAO я пытаюсь выполнить импорт следующим образом:

val conversions = StandardConversions(dbConfigProvider)
import conversions._

Ошибка компилятора знакома:

could not find implicit value for parameter tt: slick.ast.TypedType[data.Timestamp]

Я в основном застрял в инъекции зависимостей, неявном аду. Кто-нибудь придумал хороший способ сохранить свои пользовательские преобразования в Slick 3? Поделись, пожалуйста.


person Chris    schedule 02.01.2016    source источник
comment
Я также предлагаю добавить теги play framework, так как вы используете slick вместе с play.   -  person Roman    schedule 04.01.2016


Ответы (2)


Здесь пригодятся черты:

package dao

import java.sql.Date
import data.Timestamp

import play.api.db.slick.HasDatabaseConfig
import slick.driver.JdbcProfile

trait StandardConversions extends HasDatabaseConfigProvider[JdbcProfile] {
  import driver.api._

  implicit val timestampColumnType = MappedColumnType.base[Timestamp, Date](
    { data => new Date(data.value) },
    { sql => Timestamp(sql.getTime) }
  )
}

А затем просто расширьте этот трейт в своих DAO:

class SomeDAO @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
  extends HasDatabaseConfigProvider[JdbcProfile]
  with StandardConversions {

  import driver.api._

  // all implicits of StandardConversions are in scope here
}
person Roman    schedule 04.01.2016
comment
Это хорошая идея, но я попробовал, и это не сработало. Проблема, похоже, в том, что неявный val не попадает в область действия with-class. Может я как-то перепутал. еще раз подтвержу.... - person Chris; 05.01.2016
comment
Подтвердил, что это не работает. Я получаю сообщение об ошибке: could not find implicit value for parameter tt: slick.ast.TypedType[data.Timestamp]. - person Chris; 05.01.2016
comment
@Chris: Хм, не уверен, в чем именно проблема ... Приведенный выше код похож на подход, который я использую в своих проектах. Работает ли неявное преобразование, если вы поместите его непосредственно в DAO? - person Roman; 05.01.2016
comment
Это работает, когда я перемещаю неявное в DAO. Интересно, связано ли это с конкретной базой данных, которую я использую, postgresql. Я попробую переключиться на H2, чтобы посмотреть, будет ли это иметь значение. - person Chris; 05.01.2016
comment
@Chris: я сомневаюсь, что это db. Не могли бы вы предоставить еще немного кода, включая определение гладкой таблицы? - person Roman; 05.01.2016

В сочетании с решением Романа вам, вероятно, следует добавить следующий импорт:

import play.api.libs.concurrent.Execution.Implicits.defaultContext
person haukeh    schedule 20.05.2016