From 0a3ac9f121c761f7c1b6cda591b5bb3cbd510bc3 Mon Sep 17 00:00:00 2001 From: eikek Date: Fri, 12 Aug 2022 16:26:20 +0200 Subject: [PATCH] Add anonymous subselects to query builder --- .../main/scala/docspell/store/qb/Select.scala | 21 ++++++++++++------- .../scala/docspell/store/qb/SelectExpr.scala | 2 ++ .../store/qb/impl/SelectBuilder.scala | 2 +- .../docspell/store/qb/QueryBuilderTest.scala | 6 ++++-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/modules/store/src/main/scala/docspell/store/qb/Select.scala b/modules/store/src/main/scala/docspell/store/qb/Select.scala index 65ec0c6e..7f2e6916 100644 --- a/modules/store/src/main/scala/docspell/store/qb/Select.scala +++ b/modules/store/src/main/scala/docspell/store/qb/Select.scala @@ -7,6 +7,7 @@ package docspell.store.qb import cats.data.{NonEmptyList => Nel} +import cats.syntax.option._ import docspell.store.qb.impl.SelectBuilder @@ -23,6 +24,9 @@ sealed trait Select { def as(alias: String): SelectExpr.SelectQuery = SelectExpr.SelectQuery(this, Some(alias)) + def asSubSelect: SelectExpr.SelectQuery = + SelectExpr.SelectQuery(this, None) + /** Adds one or more order-by definitions */ def orderBy(ob: OrderBy, obs: OrderBy*): Select @@ -71,35 +75,38 @@ sealed trait Select { } object Select { + def apply(projection: SelectExpr) = + SimpleSelect(false, Nel.of(projection), None, Condition.unit, None) + def apply(projection: Nel[SelectExpr], from: FromExpr) = - SimpleSelect(false, projection, from, Condition.unit, None) + SimpleSelect(false, projection, from.some, Condition.unit, None) def apply(projection: SelectExpr, from: FromExpr) = - SimpleSelect(false, Nel.of(projection), from, Condition.unit, None) + SimpleSelect(false, Nel.of(projection), from.some, Condition.unit, None) def apply( projection: Nel[SelectExpr], from: FromExpr, where: Condition - ) = SimpleSelect(false, projection, from, where, None) + ) = SimpleSelect(false, projection, from.some, where, None) def apply( projection: SelectExpr, from: FromExpr, where: Condition - ) = SimpleSelect(false, Nel.of(projection), from, where, None) + ) = SimpleSelect(false, Nel.of(projection), from.some, where, None) def apply( projection: Nel[SelectExpr], from: FromExpr, where: Condition, groupBy: GroupBy - ) = SimpleSelect(false, projection, from, where, Some(groupBy)) + ) = SimpleSelect(false, projection, from.some, where, Some(groupBy)) case class SimpleSelect( distinctFlag: Boolean, projection: Nel[SelectExpr], - from: FromExpr, + from: Option[FromExpr], where: Condition, groupBy: Option[GroupBy] ) extends Select { @@ -125,7 +132,7 @@ object Select { copy(projection = es) def changeFrom(f: FromExpr => FromExpr): SimpleSelect = - copy(from = f(from)) + copy(from = from.map(f)) def changeWhere(f: Condition => Condition): SimpleSelect = copy(where = f(where)) diff --git a/modules/store/src/main/scala/docspell/store/qb/SelectExpr.scala b/modules/store/src/main/scala/docspell/store/qb/SelectExpr.scala index 8c922522..1bba08ae 100644 --- a/modules/store/src/main/scala/docspell/store/qb/SelectExpr.scala +++ b/modules/store/src/main/scala/docspell/store/qb/SelectExpr.scala @@ -33,6 +33,8 @@ object SelectExpr { case class SelectLiteral(value: String, alias: Option[String]) extends SelectExpr { def as(a: String): SelectLiteral = copy(alias = Some(a)) + def as(otherCol: Column[_]): SelectExpr = + copy(alias = Some(otherCol.name)) } case class SelectQuery(query: Select, alias: Option[String]) extends SelectExpr { diff --git a/modules/store/src/main/scala/docspell/store/qb/impl/SelectBuilder.scala b/modules/store/src/main/scala/docspell/store/qb/impl/SelectBuilder.scala index e77bfe6f..2f6641dc 100644 --- a/modules/store/src/main/scala/docspell/store/qb/impl/SelectBuilder.scala +++ b/modules/store/src/main/scala/docspell/store/qb/impl/SelectBuilder.scala @@ -52,7 +52,7 @@ object SelectBuilder { def buildSimple(sq: Select.SimpleSelect): Fragment = { val f0 = sq.projection.map(selectExpr).reduceLeft(_ ++ comma ++ _) - val f1 = fromExpr(sq.from) + val f1 = sq.from.map(fromExpr).getOrElse(Fragment.empty) val f2 = cond(sq.where) val f3 = sq.groupBy.map(groupBy).getOrElse(Fragment.empty) f0 ++ f1 ++ f2 ++ f3 diff --git a/modules/store/src/test/scala/docspell/store/qb/QueryBuilderTest.scala b/modules/store/src/test/scala/docspell/store/qb/QueryBuilderTest.scala index a36afeff..69a63410 100644 --- a/modules/store/src/test/scala/docspell/store/qb/QueryBuilderTest.scala +++ b/modules/store/src/test/scala/docspell/store/qb/QueryBuilderTest.scala @@ -50,9 +50,11 @@ class QueryBuilderTest extends FunSuite with TestLoggingConfig { ) assertEquals(11, proj.size) from match { - case FromExpr.From(_) => + case None => fail("Unexpected from value") - case FromExpr.Joined(f, joins) => + case Some(FromExpr.From(_)) => + fail("Unexpected from value") + case Some(FromExpr.Joined(f, joins)) => assertEquals(f, FromExpr.From(c)) assertEquals(2, joins.size) joins.head match {