mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-21 18:08:25 +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:
@ -2,7 +2,7 @@ package docspell.query
|
||||
|
||||
import cats.data.{NonEmptyList => Nel}
|
||||
|
||||
import docspell.query.ItemQuery.Attr.{DateAttr, StringAttr}
|
||||
import docspell.query.ItemQuery.Attr.{DateAttr, IntAttr, StringAttr}
|
||||
|
||||
/** A query evaluates to `true` or `false` given enough details about
|
||||
* an item.
|
||||
@ -40,13 +40,15 @@ object ItemQuery {
|
||||
object Attr {
|
||||
sealed trait StringAttr extends Attr
|
||||
sealed trait DateAttr extends Attr
|
||||
sealed trait IntAttr extends Attr
|
||||
|
||||
case object ItemName extends StringAttr
|
||||
case object ItemSource extends StringAttr
|
||||
case object ItemNotes extends StringAttr
|
||||
case object ItemId extends StringAttr
|
||||
case object Date extends DateAttr
|
||||
case object DueDate extends DateAttr
|
||||
case object ItemName extends StringAttr
|
||||
case object ItemSource extends StringAttr
|
||||
case object ItemNotes extends StringAttr
|
||||
case object ItemId extends StringAttr
|
||||
case object Date extends DateAttr
|
||||
case object DueDate extends DateAttr
|
||||
case object AttachCount extends IntAttr
|
||||
|
||||
object Correspondent {
|
||||
case object OrgId extends StringAttr
|
||||
@ -72,12 +74,16 @@ object ItemQuery {
|
||||
object Property {
|
||||
final case class StringProperty(attr: StringAttr, value: String) extends Property
|
||||
final case class DateProperty(attr: DateAttr, value: Date) extends Property
|
||||
final case class IntProperty(attr: IntAttr, value: Int) extends Property
|
||||
|
||||
def apply(sa: StringAttr, value: String): Property =
|
||||
StringProperty(sa, value)
|
||||
|
||||
def apply(da: DateAttr, value: Date): Property =
|
||||
DateProperty(da, value)
|
||||
|
||||
def apply(na: IntAttr, value: Int): Property =
|
||||
IntProperty(na, value)
|
||||
}
|
||||
|
||||
sealed trait Expr {
|
||||
@ -111,6 +117,7 @@ object ItemQuery {
|
||||
|
||||
final case class Fulltext(query: String) extends Expr
|
||||
final case class ChecksumMatch(checksum: String) extends Expr
|
||||
final case class AttachId(id: String) extends Expr
|
||||
|
||||
// things that can be expressed with terms above
|
||||
sealed trait MacroExpr extends Expr {
|
||||
|
@ -62,6 +62,14 @@ object AttrParser {
|
||||
val folderName: P[Attr.StringAttr] =
|
||||
P.ignoreCase("folder").as(Attr.Folder.FolderName)
|
||||
|
||||
val attachCountAttr: P[Attr.IntAttr] =
|
||||
P.ignoreCase("attach.count").as(Attr.AttachCount)
|
||||
|
||||
// combining grouped by type
|
||||
|
||||
val intAttr: P[Attr.IntAttr] =
|
||||
attachCountAttr
|
||||
|
||||
val dateAttr: P[Attr.DateAttr] =
|
||||
P.oneOf(List(date, dueDate))
|
||||
|
||||
@ -86,5 +94,5 @@ object AttrParser {
|
||||
)
|
||||
|
||||
val anyAttr: P[Attr] =
|
||||
P.oneOf(List(dateAttr, stringAttr))
|
||||
P.oneOf(List(dateAttr, stringAttr, intAttr))
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ object ExprUtil {
|
||||
expr
|
||||
case ChecksumMatch(_) =>
|
||||
expr
|
||||
case AttachId(_) =>
|
||||
expr
|
||||
}
|
||||
|
||||
private def spliceAnd(nodes: Nel[Expr]): Nel[Expr] =
|
||||
|
@ -1,5 +1,6 @@
|
||||
package docspell.query.internal
|
||||
|
||||
import cats.parse.Numbers
|
||||
import cats.parse.{Parser => P}
|
||||
|
||||
import docspell.query.ItemQuery._
|
||||
@ -18,6 +19,9 @@ object SimpleExprParser {
|
||||
private[this] val inOrOpDate =
|
||||
P.eitherOr(op ~ DateParser.date, inOp *> DateParser.dateOrMore)
|
||||
|
||||
private[this] val opInt =
|
||||
op ~ Numbers.digits.map(_.toInt)
|
||||
|
||||
val stringExpr: P[Expr] =
|
||||
(AttrParser.stringAttr ~ inOrOpStr).map {
|
||||
case (attr, Right((op, value))) =>
|
||||
@ -34,6 +38,11 @@ object SimpleExprParser {
|
||||
Expr.InDateExpr(attr, values)
|
||||
}
|
||||
|
||||
val intExpr: P[Expr] =
|
||||
(AttrParser.intAttr ~ opInt).map { case (attr, (op, value)) =>
|
||||
Expr.SimpleExpr(op, Property(attr, value))
|
||||
}
|
||||
|
||||
val existsExpr: P[Expr.Exists] =
|
||||
(P.ignoreCase("exists:") *> AttrParser.anyAttr).map(attr => Expr.Exists(attr))
|
||||
|
||||
@ -79,11 +88,15 @@ object SimpleExprParser {
|
||||
val checksumExpr: P[Expr.ChecksumMatch] =
|
||||
(P.string("checksum:") *> BasicParser.singleString).map(Expr.ChecksumMatch.apply)
|
||||
|
||||
val attachIdExpr: P[Expr.AttachId] =
|
||||
(P.ignoreCase("attach.id:") *> BasicParser.singleString).map(Expr.AttachId.apply)
|
||||
|
||||
val simpleExpr: P[Expr] =
|
||||
P.oneOf(
|
||||
List(
|
||||
dateExpr,
|
||||
stringExpr,
|
||||
intExpr,
|
||||
existsExpr,
|
||||
fulltextExpr,
|
||||
tagIdExpr,
|
||||
@ -93,7 +106,8 @@ object SimpleExprParser {
|
||||
customFieldExpr,
|
||||
inboxExpr,
|
||||
dirExpr,
|
||||
checksumExpr
|
||||
checksumExpr,
|
||||
attachIdExpr
|
||||
)
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user