mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Add more ways to query for attachments
- find items with a specified attachment count - find items by attachment id
This commit is contained in:
@ -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 =>
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user