Add checksum query expr

This commit is contained in:
Eike Kettner 2021-03-08 01:53:21 +01:00
parent 7b1ec97c97
commit 2b2f913e85
5 changed files with 45 additions and 26 deletions

View File

@ -110,6 +110,7 @@ object ItemQuery {
extends Expr extends Expr
final case class Fulltext(query: String) extends Expr final case class Fulltext(query: String) extends Expr
final case class ChecksumMatch(checksum: String) extends Expr
// things that can be expressed with terms above // things that can be expressed with terms above
sealed trait MacroExpr extends Expr { sealed trait MacroExpr extends Expr {

View File

@ -65,6 +65,8 @@ object ExprUtil {
expr expr
case CustomFieldIdMatch(_, _, _) => case CustomFieldIdMatch(_, _, _) =>
expr expr
case ChecksumMatch(_) =>
expr
} }
private def spliceAnd(nodes: Nel[Expr]): Nel[Expr] = private def spliceAnd(nodes: Nel[Expr]): Nel[Expr] =

View File

@ -76,6 +76,9 @@ object SimpleExprParser {
val dirExpr: P[Expr.DirectionExpr] = val dirExpr: P[Expr.DirectionExpr] =
(P.string("incoming:") *> BasicParser.bool).map(Expr.DirectionExpr.apply) (P.string("incoming:") *> BasicParser.bool).map(Expr.DirectionExpr.apply)
val checksumExpr: P[Expr.ChecksumMatch] =
(P.string("checksum:") *> BasicParser.singleString).map(Expr.ChecksumMatch.apply)
val simpleExpr: P[Expr] = val simpleExpr: P[Expr] =
P.oneOf( P.oneOf(
List( List(
@ -89,7 +92,8 @@ object SimpleExprParser {
customFieldIdExpr, customFieldIdExpr,
customFieldExpr, customFieldExpr,
inboxExpr, inboxExpr,
dirExpr dirExpr,
checksumExpr
) )
) )
} }

View File

@ -3,15 +3,16 @@ package docspell.store.qb.generator
import java.time.Instant import java.time.Instant
import java.time.LocalDate import java.time.LocalDate
import cats.data.NonEmptyList import cats.data.{NonEmptyList => Nel}
import docspell.common._ import docspell.common._
import docspell.query.ItemQuery._ import docspell.query.ItemQuery._
import docspell.query.{Date, ItemQuery} import docspell.query.{Date, ItemQuery}
import docspell.store.qb.DSL._ import docspell.store.qb.DSL._
import docspell.store.qb.{Operator => QOp, _} import docspell.store.qb.{Operator => QOp, _}
import docspell.store.queries.QItem
import docspell.store.queries.QueryWildcard import docspell.store.queries.QueryWildcard
import docspell.store.records.{RCustomField, RCustomFieldValue, TagItemName} import docspell.store.records._
import doobie.util.Put import doobie.util.Put
@ -39,7 +40,7 @@ object ItemQueryGenerator {
case Expr.TagIdsMatch(op, tags) => case Expr.TagIdsMatch(op, tags) =>
val ids = tags.toList.flatMap(s => Ident.fromString(s).toOption) val ids = tags.toList.flatMap(s => Ident.fromString(s).toOption)
NonEmptyList Nel
.fromList(ids) .fromList(ids)
.map { nel => .map { nel =>
op match { op match {
@ -114,7 +115,7 @@ object ItemQueryGenerator {
case Expr.TagIdsMatch(op, tags) => case Expr.TagIdsMatch(op, tags) =>
val ids = tags.toList.flatMap(s => Ident.fromString(s).toOption) val ids = tags.toList.flatMap(s => Ident.fromString(s).toOption)
NonEmptyList Nel
.fromList(ids) .fromList(ids)
.map { nel => .map { nel =>
op match { op match {
@ -152,6 +153,10 @@ object ItemQueryGenerator {
case Expr.CustomFieldIdMatch(field, op, value) => case Expr.CustomFieldIdMatch(field, op, value) =>
tables.item.id.in(itemsWithCustomField(_.id ==== field)(coll, makeOp(op), value)) tables.item.id.in(itemsWithCustomField(_.id ==== field)(coll, makeOp(op), value))
case Expr.ChecksumMatch(checksum) =>
val select = QItem.findByChecksumQuery(checksum, coll, Set.empty)
tables.item.id.in(select.withSelect(Nel.of(RItem.as("i").id.s)))
case Expr.Fulltext(_) => case Expr.Fulltext(_) =>
// not supported here // not supported here
Condition.unit Condition.unit

View File

@ -509,6 +509,16 @@ object QItem {
collective: Ident, collective: Ident,
excludeFileMeta: Set[Ident] excludeFileMeta: Set[Ident]
): ConnectionIO[Vector[RItem]] = { ): ConnectionIO[Vector[RItem]] = {
val qq = findByChecksumQuery(checksum, collective, excludeFileMeta).build
logger.debug(s"FindByChecksum: $qq")
qq.query[RItem].to[Vector]
}
def findByChecksumQuery(
checksum: String,
collective: Ident,
excludeFileMeta: Set[Ident]
): Select = {
val m1 = RFileMeta.as("m1") val m1 = RFileMeta.as("m1")
val m2 = RFileMeta.as("m2") val m2 = RFileMeta.as("m2")
val m3 = RFileMeta.as("m3") val m3 = RFileMeta.as("m3")
@ -517,7 +527,6 @@ object QItem {
val s = RAttachmentSource.as("s") val s = RAttachmentSource.as("s")
val r = RAttachmentArchive.as("r") val r = RAttachmentArchive.as("r")
val fms = Nel.of(m1, m2, m3) val fms = Nel.of(m1, m2, m3)
val qq =
Select( Select(
select(i.all), select(i.all),
from(i) from(i)
@ -534,9 +543,7 @@ object QItem {
.fromList(excludeFileMeta.toList) .fromList(excludeFileMeta.toList)
.map(excl => Condition.And(fms.map(m => m.id.isNull || m.id.notIn(excl)))) .map(excl => Condition.And(fms.map(m => m.id.isNull || m.id.notIn(excl))))
) )
).distinct.build ).distinct
logger.debug(s"FindByChecksum: $qq")
qq.query[RItem].to[Vector]
} }
final case class NameAndNotes( final case class NameAndNotes(