Add more ways to query for attachments

- find items with a specified attachment count
- find items by attachment id
This commit is contained in:
Eike Kettner
2021-03-08 09:30:47 +01:00
parent 2b2f913e85
commit 30c901ddf1
9 changed files with 89 additions and 25 deletions

View File

@ -94,6 +94,10 @@ object ItemQueryGenerator {
val noLikeOp = if (op == Operator.Like) Operator.Eq else op
Condition.CompareVal(col, makeOp(noLikeOp), dt)
case Expr.SimpleExpr(op, Property.IntProperty(attr, value)) =>
val col = intColumn(tables)(attr)
Condition.CompareVal(col, makeOp(op), value)
case Expr.InExpr(attr, values) =>
val col = stringColumn(tables)(attr)
if (values.tail.isEmpty) col === values.head
@ -157,6 +161,15 @@ object ItemQueryGenerator {
val select = QItem.findByChecksumQuery(checksum, coll, Set.empty)
tables.item.id.in(select.withSelect(Nel.of(RItem.as("i").id.s)))
case Expr.AttachId(id) =>
tables.item.id.in(
Select(
select(RAttachment.T.itemId),
from(RAttachment.T),
RAttachment.T.id.cast[String] === id
).distinct
)
case Expr.Fulltext(_) =>
// not supported here
Condition.unit
@ -196,6 +209,8 @@ object ItemQueryGenerator {
stringColumn(tables)(s)
case t: Attr.DateAttr =>
timestampColumn(tables)(t)
case n: Attr.IntAttr =>
intColumn(tables)(n)
}
private def timestampColumn(tables: Tables)(attr: Attr.DateAttr) =
@ -224,6 +239,11 @@ object ItemQueryGenerator {
case Attr.Folder.FolderName => tables.folder.name
}
private def intColumn(tables: Tables)(attr: Attr.IntAttr): Column[Int] =
attr match {
case Attr.AttachCount => tables.attachCount.num
}
private def makeOp(operator: Operator): QOp =
operator match {
case Operator.Eq =>

View File

@ -1,5 +1,6 @@
package docspell.store.qb.generator
import docspell.store.queries.AttachCountTable
import docspell.store.records._
final case class Tables(
@ -10,5 +11,6 @@ final case class Tables(
concEquip: REquipment.Table,
folder: RFolder.Table,
attach: RAttachment.Table,
meta: RAttachmentMeta.Table
meta: RAttachmentMeta.Table,
attachCount: AttachCountTable
)

View File

@ -0,0 +1,16 @@
package docspell.store.queries
import docspell.common.Ident
import docspell.store.qb.Column
import docspell.store.qb.TableDef
final case class AttachCountTable(aliasName: String) extends TableDef {
val tableName = "attachs"
val alias: Option[String] = Some(aliasName)
val num = Column[Int]("num", this)
val itemId = Column[Ident]("item_id", this)
def as(alias: String): AttachCountTable =
copy(aliasName = alias)
}

View File

@ -122,15 +122,8 @@ object QItem {
}
private def findItemsBase(q: Query.Fix, noteMaxLen: Int): Select = {
object Attachs extends TableDef {
val tableName = "attachs"
val aliasName = "cta"
val alias = Some(aliasName)
val num = Column[Int]("num", this)
val itemId = Column[Ident]("item_id", this)
}
val coll = q.account.collective
val attachs = AttachCountTable("cta")
val coll = q.account.collective
Select(
select(
@ -142,7 +135,7 @@ object QItem {
i.source.s,
i.incoming.s,
i.created.s,
coalesce(Attachs.num.s, const(0)).s,
coalesce(attachs.num.s, const(0)).s,
org.oid.s,
org.name.s,
pers0.pid.s,
@ -162,14 +155,14 @@ object QItem {
.leftJoin(f, f.id === i.folder && f.collective === coll)
.leftJoin(
Select(
select(countAll.as(Attachs.num), a.itemId.as(Attachs.itemId)),
select(countAll.as(attachs.num), a.itemId.as(attachs.itemId)),
from(a)
.innerJoin(i, i.id === a.itemId),
i.cid === q.account.collective,
GroupBy(a.itemId)
),
Attachs.aliasName,
Attachs.itemId === i.id
attachs.aliasName,
attachs.itemId === i.id
)
.leftJoin(pers0, pers0.pid === i.corrPerson && pers0.cid === coll)
.leftJoin(org, org.oid === i.corrOrg && org.cid === coll)
@ -229,7 +222,7 @@ object QItem {
.map(itemIds => i.id.in(itemIds))
def queryCondFromExpr(today: LocalDate, coll: Ident, q: ItemQuery): Condition = {
val tables = Tables(i, org, pers0, pers1, equip, f, a, m)
val tables = Tables(i, org, pers0, pers1, equip, f, a, m, AttachCountTable("cta"))
ItemQueryGenerator.fromExpr(today, tables, coll)(q.expr)
}

View File

@ -6,6 +6,7 @@ import docspell.store.records._
import minitest._
import docspell.common._
import docspell.query.ItemQueryParser
import docspell.store.queries.AttachCountTable
import docspell.store.qb.DSL._
import docspell.store.qb.generator.{ItemQueryGenerator, Tables}
@ -20,7 +21,8 @@ object ItemQueryGeneratorTest extends SimpleTestSuite {
REquipment.as("ne"),
RFolder.as("f"),
RAttachment.as("a"),
RAttachmentMeta.as("m")
RAttachmentMeta.as("m"),
AttachCountTable("cta")
)
val now: LocalDate = LocalDate.of(2021, 2, 25)