Allow simple search when listing meta data

This commit is contained in:
Eike Kettner
2020-01-02 19:59:46 +01:00
parent eb6c483ef0
commit 8814de3c38
14 changed files with 163 additions and 46 deletions

View File

@ -3,9 +3,11 @@ package docspell.store.queries
import fs2._
import cats.implicits._
import doobie._
import doobie.implicits._
import docspell.common._
import docspell.store.{AddResult, Store}
import docspell.store.impl.Column
import docspell.store.impl.Implicits._
import docspell.store.records.ROrganization.{Columns => OC}
import docspell.store.records.RPerson.{Columns => PC}
import docspell.store.records._
@ -14,16 +16,75 @@ object QOrganization {
def findOrgAndContact(
coll: Ident,
query: Option[String],
order: OC.type => Column
): Stream[ConnectionIO, (ROrganization, Vector[RContact])] =
ROrganization
.findAll(coll, order)
.evalMap(ro => RContact.findAllOrg(ro.oid).map(cs => (ro, cs)))
): Stream[ConnectionIO, (ROrganization, Vector[RContact])] = {
val oColl = ROrganization.Columns.cid.prefix("o")
val oName = ROrganization.Columns.name.prefix("o")
val oNotes = ROrganization.Columns.notes.prefix("o")
val oId = ROrganization.Columns.oid.prefix("o")
val cOrg = RContact.Columns.orgId.prefix("c")
val cVal = RContact.Columns.value.prefix("c")
val cols = ROrganization.Columns.all.map(_.prefix("o")) ++ RContact.Columns.all
.map(_.prefix("c"))
val from = ROrganization.table ++ fr"o LEFT JOIN" ++
RContact.table ++ fr"c ON" ++ cOrg.is(oId)
val q = Seq(oColl.is(coll)) ++ (query match {
case Some(str) =>
val v = s"%$str%"
Seq(or(cVal.lowerLike(v), oName.lowerLike(v), oNotes.lowerLike(v)))
case None =>
Seq.empty
})
(selectSimple(cols, from, and(q)) ++ orderBy(order(OC).f))
.query[(ROrganization, Option[RContact])]
.stream
.groupAdjacentBy(_._1)
.map({
case (ro, chunk) =>
val cs = chunk.toVector.flatMap(_._2)
(ro, cs)
})
}
def findPersonAndContact(
coll: Ident,
query: Option[String],
order: PC.type => Column
): Stream[ConnectionIO, (RPerson, Vector[RContact])] =
RPerson.findAll(coll, order).evalMap(ro => RContact.findAllPerson(ro.pid).map(cs => (ro, cs)))
): Stream[ConnectionIO, (RPerson, Vector[RContact])] = {
val pColl = PC.cid.prefix("p")
val pName = RPerson.Columns.name.prefix("p")
val pNotes = RPerson.Columns.notes.prefix("p")
val pId = RPerson.Columns.pid.prefix("p")
val cPers = RContact.Columns.personId.prefix("c")
val cVal = RContact.Columns.value.prefix("c")
val cols = RPerson.Columns.all.map(_.prefix("p")) ++ RContact.Columns.all
.map(_.prefix("c"))
val from = RPerson.table ++ fr"p LEFT JOIN" ++
RContact.table ++ fr"c ON" ++ cPers.is(pId)
val q = Seq(pColl.is(coll)) ++ (query match {
case Some(str) =>
val v = s"%${str.toLowerCase}%"
Seq(or(cVal.lowerLike(v), pName.lowerLike(v), pNotes.lowerLike(v)))
case None =>
Seq.empty
})
(selectSimple(cols, from, and(q)) ++ orderBy(order(PC).f))
.query[(RPerson, Option[RContact])]
.stream
.groupAdjacentBy(_._1)
.map({
case (ro, chunk) =>
val cs = chunk.toVector.flatMap(_._2)
(ro, cs)
})
}
def addOrg[F[_]](
org: ROrganization,

View File

@ -47,8 +47,16 @@ object REquipment {
sql.query[REquipment].option
}
def findAll(coll: Ident, order: Columns.type => Column): ConnectionIO[Vector[REquipment]] = {
val sql = selectSimple(all, table, cid.is(coll)) ++ orderBy(order(Columns).f)
def findAll(
coll: Ident,
nameQ: Option[String],
order: Columns.type => Column
): ConnectionIO[Vector[REquipment]] = {
val q = Seq(cid.is(coll)) ++ (nameQ match {
case Some(str) => Seq(name.lowerLike(s"%${str.toLowerCase}%"))
case None => Seq.empty
})
val sql = selectSimple(all, table, and(q)) ++ orderBy(order(Columns).f)
sql.query[REquipment].to[Vector]
}

View File

@ -1,5 +1,6 @@
package docspell.store.records
import cats.Eq
import fs2.Stream
import doobie._
import doobie.implicits._
@ -20,6 +21,8 @@ case class ROrganization(
) {}
object ROrganization {
implicit val orgEq: Eq[ROrganization] =
Eq.by[ROrganization, Ident](_.oid)
val table = fr"organization"
@ -105,8 +108,16 @@ object ROrganization {
sql.query[ROrganization].stream
}
def findAllRef(coll: Ident, order: Columns.type => Column): ConnectionIO[Vector[IdRef]] = {
val sql = selectSimple(List(oid, name), table, cid.is(coll)) ++ orderBy(order(Columns).f)
def findAllRef(
coll: Ident,
nameQ: Option[String],
order: Columns.type => Column
): ConnectionIO[Vector[IdRef]] = {
val q = Seq(cid.is(coll)) ++ (nameQ match {
case Some(str) => Seq(name.lowerLike(s"%${str.toLowerCase}%"))
case None => Seq.empty
})
val sql = selectSimple(List(oid, name), table, and(q)) ++ orderBy(order(Columns).f)
sql.query[IdRef].to[Vector]
}

View File

@ -1,6 +1,7 @@
package docspell.store.records
import fs2.Stream
import cats.Eq
import doobie._
import doobie.implicits._
import docspell.common.{IdRef, _}
@ -21,6 +22,8 @@ case class RPerson(
) {}
object RPerson {
implicit val personEq: Eq[RPerson] =
Eq.by(_.pid)
val table = fr"person"
@ -116,8 +119,16 @@ object RPerson {
sql.query[RPerson].stream
}
def findAllRef(coll: Ident, order: Columns.type => Column): ConnectionIO[Vector[IdRef]] = {
val sql = selectSimple(List(pid, name), table, cid.is(coll)) ++ orderBy(order(Columns).f)
def findAllRef(
coll: Ident,
nameQ: Option[String],
order: Columns.type => Column
): ConnectionIO[Vector[IdRef]] = {
val q = Seq(cid.is(coll)) ++ (nameQ match {
case Some(str) => Seq(name.lowerLike(s"%${str.toLowerCase}%"))
case None => Seq.empty
})
val sql = selectSimple(List(pid, name), table, and(q)) ++ orderBy(order(Columns).f)
sql.query[IdRef].to[Vector]
}

View File

@ -65,8 +65,16 @@ object RTag {
sql.query[Int].unique.map(_ > 0)
}
def findAll(coll: Ident, order: Columns.type => Column): ConnectionIO[Vector[RTag]] = {
val sql = selectSimple(all, table, cid.is(coll)) ++ orderBy(order(Columns).f)
def findAll(
coll: Ident,
nameQ: Option[String],
order: Columns.type => Column
): ConnectionIO[Vector[RTag]] = {
val q = Seq(cid.is(coll)) ++ (nameQ match {
case Some(str) => Seq(name.lowerLike(s"%${str.toLowerCase}%"))
case None => Seq.empty
})
val sql = selectSimple(all, table, and(q)) ++ orderBy(order(Columns).f)
sql.query[RTag].to[Vector]
}