From 6ea742073940d2d5809fb637d3d3a785341fc4f9 Mon Sep 17 00:00:00 2001 From: vlad Date: Thu, 17 Aug 2017 14:15:20 -0700 Subject: Moving PostgresContext to the common code (cherry picked from commit 8acbc7e) --- .../pdsuicommon/db/PostgresQueryBuilder.scala | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/main/scala/xyz/driver/pdsuicommon/db/PostgresQueryBuilder.scala (limited to 'src/main/scala/xyz/driver/pdsuicommon/db/PostgresQueryBuilder.scala') diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/PostgresQueryBuilder.scala b/src/main/scala/xyz/driver/pdsuicommon/db/PostgresQueryBuilder.scala new file mode 100644 index 0000000..8ef1829 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/db/PostgresQueryBuilder.scala @@ -0,0 +1,98 @@ +package xyz.driver.pdsuicommon.db + +import java.sql.ResultSet + +import io.getquill.{PostgresDialect, PostgresEscape} + +import scala.collection.breakOut + +object PostgresQueryBuilder { + + import xyz.driver.pdsuicommon.db.QueryBuilder._ + + type Escape = PostgresEscape + val Escape = PostgresEscape + + def apply[T](tableName: String, + lastUpdateFieldName: Option[String], + nullableFields: Set[String], + links: Set[TableLink], + runner: Runner[T], + countRunner: CountRunner): PostgresQueryBuilder[T] = { + val parameters = PostgresQueryBuilderParameters( + tableData = TableData(tableName, lastUpdateFieldName, nullableFields), + links = links.map(x => x.foreignTableName -> x)(breakOut) + ) + new PostgresQueryBuilder[T](parameters)(runner, countRunner) + } + + def apply[T](tableName: String, + lastUpdateFieldName: Option[String], + nullableFields: Set[String], + links: Set[TableLink], + extractor: ResultSet => T)(implicit sqlContext: PostgresContext): PostgresQueryBuilder[T] = { + apply(tableName, QueryBuilderParameters.AllFields, lastUpdateFieldName, nullableFields, links, extractor) + } + + def apply[T](tableName: String, + fields: Set[String], + lastUpdateFieldName: Option[String], + nullableFields: Set[String], + links: Set[TableLink], + extractor: ResultSet => T)(implicit sqlContext: PostgresContext): PostgresQueryBuilder[T] = { + + val runner: Runner[T] = { parameters => + val (sql, binder) = parameters.toSql(countQuery = false, fields = fields, namingStrategy = PostgresEscape) + sqlContext.executeQuery[T](sql, binder, { resultSet => + extractor(resultSet) + }) + } + + val countRunner: CountRunner = { parameters => + val (sql, binder) = parameters.toSql(countQuery = true, namingStrategy = PostgresEscape) + sqlContext + .executeQuery[CountResult]( + sql, + binder, { resultSet => + val count = resultSet.getInt(1) + val lastUpdate = if (parameters.tableData.lastUpdateFieldName.isDefined) { + Option(resultSet.getTimestamp(2)).map(sqlContext.timestampToLocalDateTime) + } else None + + (count, lastUpdate) + } + ) + .head + } + + apply[T]( + tableName = tableName, + lastUpdateFieldName = lastUpdateFieldName, + nullableFields = nullableFields, + links = links, + runner = runner, + countRunner = countRunner + ) + } +} + +class PostgresQueryBuilder[T](parameters: PostgresQueryBuilderParameters)(implicit runner: QueryBuilder.Runner[T], + countRunner: QueryBuilder.CountRunner) + extends QueryBuilder[T, PostgresDialect, PostgresQueryBuilder.Escape](parameters) { + + def withFilter(newFilter: SearchFilterExpr): QueryBuilder[T, PostgresDialect, PostgresEscape] = { + new PostgresQueryBuilder[T](parameters.copy(filter = newFilter)) + } + + def withSorting(newSorting: Sorting): QueryBuilder[T, PostgresDialect, PostgresEscape] = { + new PostgresQueryBuilder[T](parameters.copy(sorting = newSorting)) + } + + def withPagination(newPagination: Pagination): QueryBuilder[T, PostgresDialect, PostgresEscape] = { + new PostgresQueryBuilder[T](parameters.copy(pagination = Some(newPagination))) + } + + def resetPagination: QueryBuilder[T, PostgresDialect, PostgresEscape] = { + new PostgresQueryBuilder[T](parameters.copy(pagination = None)) + } +} -- cgit v1.2.3