Hledger.Query

hledger-lib-1.41: A library providing the core functionality of hledger

Safe Haskell | None
Language | Haskell2010

Hledger.Query

Contents

- Query and QueryOpt
- parsing
- modifying
- predicates
- accessors
- matching things with queries
- tests

Description

A general query system for matching things (accounts, postings, transactions..) by various criteria, and a SimpleTextParser for query expressions.

Synopsis

- data Query
  - = Not Query
  - | And [Query]
  - | Or [Query]
  - | Any
  - | None
  - | Date DateSpan
  - | Date2 DateSpan
  - | StatusQ Status
  - | Code Regexp
  - | Desc Regexp
  - | Tag Regexp (Maybe Regexp)
  - | Acct Regexp
  - | Type [AccountType]
  - | Depth Int
  - | DepthAcct Regexp Int
  - | Real Bool
  - | Amt OrdPlus Quantity
  - | Sym Regexp
- data QueryOpt
  - = QueryOptInAcctOnly AccountName
  - | QueryOptInAcct AccountName
- data OrdPlus
  - = Lt
  - | LtEq
  - | Gt
  - | GtEq
  - | Eq
  - | AbsLt
  - | AbsLtEq
  - | AbsGt
  - | AbsGtEq
  - | AbsEq
- payeeTag :: Maybe Text -> Either RegexError Query
- noteTag :: Maybe Text -> Either RegexError Query
- generatedTransactionTag :: Query
- parseQuery :: Day -> Text -> Either String (Query, [QueryOpt])
- parseQueryList :: Day -> [Text] -> Either String (Query, [QueryOpt])
- parseQueryTerm :: Day -> Text -> Either String (Query, [QueryOpt])
- parseAccountType :: Bool -> Text -> Either String AccountType
- parseDepthSpec :: Text -> Either RegexError DepthSpec
- simplifyQuery :: Query -> Query
- filterQuery :: (Query -> Bool) -> Query -> Query
- filterQueryOrNotQuery :: (Query -> Bool) -> Query -> Query
- matchesQuery :: (Query -> Bool) -> Query -> Bool
- queryIsNull :: Query -> Bool
- queryIsDate :: Query -> Bool
- queryIsDate2 :: Query -> Bool
- queryIsDateOrDate2 :: Query -> Bool
- queryIsStatus :: Query -> Bool
- queryIsCode :: Query -> Bool
- queryIsDesc :: Query -> Bool
- queryIsTag :: Query -> Bool
- queryIsAcct :: Query -> Bool
- queryIsType :: Query -> Bool
- queryIsDepth :: Query -> Bool
- queryIsReal :: Query -> Bool
- queryIsAmt :: Query -> Bool
- queryIsSym :: Query -> Bool
- queryIsStartDateOnly :: Bool -> Query -> Bool
- queryIsTransactionRelated :: Query -> Bool
- queryStartDate :: Bool -> Query -> Maybe Day
- queryEndDate :: Bool -> Query -> Maybe Day
- queryDateSpan :: Bool -> Query -> DateSpan
- queryDateSpan' :: Query -> DateSpan
- queryDepth :: Query -> DepthSpec
- inAccount :: [QueryOpt] -> Maybe (AccountName, Bool)
- inAccountQuery :: [QueryOpt] -> Maybe Query
- matchesTransaction :: Query -> Transaction -> Bool
- matchesTransactionExtra :: (AccountName -> Maybe AccountType) -> Query -> Transaction -> Bool
- matchesDescription :: Query -> Text -> Bool
- matchesPayeeWIP :: Query -> Payee -> Bool
- matchesPosting :: Query -> Posting -> Bool
- matchesPostingExtra :: (AccountName -> Maybe AccountType) -> Query -> Posting -> Bool
- matchesAccount :: Query -> AccountName -> Bool
- matchesAccountExtra :: (AccountName -> Maybe AccountType) -> (AccountName -> [Tag]) -> Query -> AccountName -> Bool
- matchesMixedAmount :: Query -> MixedAmount -> Bool
- matchesAmount :: Query -> Amount -> Bool
- matchesCommodity :: Query -> CommoditySymbol -> Bool
- matchesTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool
- matchesPriceDirective :: Query -> PriceDirective -> Bool
- words'' :: [Text] -> Text -> [Text]
- queryprefixes :: [Text]
- tests_Query :: TestTree

# Query and QueryOpt

data Query #

A query is a composition of search criteria, which can be used to match postings, transactions, accounts and more.

Constructors

Not Query | negate this match
And [Query] | match if all of these match
Or [Query] | match if any of these match no-op queries
Any | always match
None | never match data queries (in "standard" order, roughly as they appear in a transaction)
Date DateSpan | match primary dates in this date span
Date2 DateSpan | match secondary dates in this date span
StatusQ Status | match this txn/posting status
Code Regexp | match txn codes infix-matched by this regexp
Desc Regexp | match txn descriptions infix-matched by this regexp
Tag Regexp (Maybe Regexp) | match if a tag's name, and optionally its value, is infix-matched by the respective regexps
Acct Regexp | match account names infix-matched by this regexp
Type [AccountType] | match accounts whose type is one of these (or with no types, any account)
Depth Int | match if account depth is less than or equal to this value (or, sometimes used as a display option)
DepthAcct Regexp Int | match if the account matches and account depth is less than or equal to this value (usually used as a display option)
Real Bool | match postings with this "realness" value
Amt OrdPlus Quantity | match if the amount's numeric quantity is less thangreater thanequal to/unsignedly equal to some value
Sym Regexp | match if the commodity symbol is fully-matched by this regexp

#### Instances

Instances details

Default Query # |
Instance details Defined in Hledger.Query Methods def :: Query #
Show Query # |
Instance details Defined in Hledger.Query Methods showsPrec :: Int -> Query -> ShowS # show :: Query -> String # showList :: [Query] -> ShowS #
Eq Query # |
Instance details Defined in Hledger.Query Methods (==) :: Query -> Query -> Bool # (/=) :: Query -> Query -> Bool #

data QueryOpt #

A query option changes a query's/report's behaviour and output in some way.

Constructors

QueryOptInAcctOnly AccountName | show an account register focussed on this account
QueryOptInAcct AccountName | as above but include sub-accounts in the account register | QueryOptCostBasis -- ^ show amounts converted to cost where possible | QueryOptDate2 -- ^ show secondary dates instead of primary dates

#### Instances

Instances details

Show QueryOpt # |
Instance details Defined in Hledger.Query Methods showsPrec :: Int -> QueryOpt -> ShowS # show :: QueryOpt -> String # showList :: [QueryOpt] -> ShowS #
Eq QueryOpt # |
Instance details Defined in Hledger.Query Methods (==) :: QueryOpt -> QueryOpt -> Bool # (/=) :: QueryOpt -> QueryOpt -> Bool #

data OrdPlus #

A more expressive Ord, used for amt: queries. The Abs* variants compare with the absolute value of a number, ignoring sign.

Constructors

Lt |
LtEq |
Gt |
GtEq |
Eq |
AbsLt |
AbsLtEq |
AbsGt |
AbsGtEq |
AbsEq |

#### Instances

Instances details

Show OrdPlus # |
Instance details Defined in Hledger.Query Methods showsPrec :: Int -> OrdPlus -> ShowS # show :: OrdPlus -> String # showList :: [OrdPlus] -> ShowS #
Eq OrdPlus # |
Instance details Defined in Hledger.Query Methods (==) :: OrdPlus -> OrdPlus -> Bool # (/=) :: OrdPlus -> OrdPlus -> Bool #

payeeTag :: Maybe Text -> Either RegexError Query #

Construct a query for the payee: tag

noteTag :: Maybe Text -> Either RegexError Query #

Construct a query for the note: tag

generatedTransactionTag :: Query #

Construct a query for the generated-transaction: tag

# parsing

parseQuery :: Day -> Text -> Either String (Query, [QueryOpt]) #

A version of parseQueryList which acts on a single Text of space-separated terms.

The usual shell quoting rules are assumed. When a pattern contains whitespace, it (or the whole term including prefix) should be enclosed in single or double quotes.

A query term is either:

1. a search pattern, which matches on one or more fields, eg:

   acct:REGEXP - match the account name with a regular expression desc:REGEXP - match the transaction description date:PERIODEXP - match the date with a period expression

The prefix indicates the field to match, or if there is no prefix account name is assumed.

1. a query option, which modifies the reporting behaviour in some way. There is currently one of these, which may appear only once:

   inacct:FULLACCTNAME

Period expressions may contain relative dates, so a reference date is required to fully parse these.

    >>> parseQuery nulldate "expenses:dining out"
    Right (Or [Acct (RegexpCI "expenses:dining"),Acct (RegexpCI "out")],[])

    >>> parseQuery nulldate "\"expenses:dining out\""
    Right (Acct (RegexpCI "expenses:dining out"),[])

parseQueryList :: Day -> [Text] -> Either String (Query, [QueryOpt]) #

Convert a list of space-separated queries to a single query

Multiple terms are combined as follows: 1. multiple account patterns are OR'd together 2. multiple description patterns are OR'd together 3. multiple status patterns are OR'd together 4. then all terms are AND'd together

parseQueryTerm :: Day -> Text -> Either String (Query, [QueryOpt]) #

Parse a single query term as either a query or a query option, or return an error message if parsing fails.

parseAccountType :: Bool -> Text -> Either String AccountType #

Case-insensitively parse one single-letter code, or one long-form word if permitted, to an account type. On failure, returns the unparseable text.

parseDepthSpec :: Text -> Either RegexError DepthSpec #

# modifying

simplifyQuery :: Query -> Query #

filterQuery :: (Query -> Bool) -> Query -> Query #

Remove query terms (or whole sub-expressions) from this query which do not match the given predicate. XXX Semantics not completely clear. Also calls simplifyQuery on the result.

filterQueryOrNotQuery :: (Query -> Bool) -> Query -> Query #

Remove query terms (or whole sub-expressions) from this query which match neither the given predicate nor that predicate negated (eg, if predicate is queryIsAcct, this will keep both "acct:" and "not:acct:" terms). Also calls simplifyQuery on the result. (Since 1.24.1, might be merged into filterQuery in future.) XXX Semantics not completely clear.

matchesQuery :: (Query -> Bool) -> Query -> Bool #

Does this simple query predicate match any part of this possibly compound query ?

# predicates

queryIsNull :: Query -> Bool #

Does this query match everything ?

queryIsDate :: Query -> Bool #

Is this a simple query of this type (date:) ? Does not match a compound query involving andornot. Likewise for the following functions.

queryIsDate2 :: Query -> Bool #

queryIsDateOrDate2 :: Query -> Bool #

queryIsStatus :: Query -> Bool #

queryIsCode :: Query -> Bool #

queryIsDesc :: Query -> Bool #

queryIsTag :: Query -> Bool #

queryIsAcct :: Query -> Bool #

queryIsType :: Query -> Bool #

queryIsDepth :: Query -> Bool #

queryIsReal :: Query -> Bool #

queryIsAmt :: Query -> Bool #

queryIsSym :: Query -> Bool #

queryIsStartDateOnly :: Bool -> Query -> Bool #

Does this query specify a start date and nothing else (that would filter postings prior to the date) ? When the flag is true, look for a starting secondary date instead.

queryIsTransactionRelated :: Query -> Bool #

Does this query involve a property of transactions (or their postings), making it inapplicable to account declarations ?

# accessors

queryStartDate :: Bool -> Query -> Maybe Day #

What start date (or secondary date) does this query specify, if any ? For OR expressions, use the earliest of the dates. NOT is ignored.

queryEndDate :: Bool -> Query -> Maybe Day #

What end date (or secondary date) does this query specify, if any ? For OR expressions, use the latest of the dates. NOT is ignored.

queryDateSpan :: Bool -> Query -> DateSpan #

What date span (or with a true argument, what secondary date span) does this query specify ? OR clauses specifying multiple spans return their union (the span enclosing all of them). AND clauses specifying multiple spans return their intersection. NOT clauses are ignored.

queryDateSpan' :: Query -> DateSpan #

What date span does this query specify, treating primary and secondary dates as equivalent ? OR clauses specifying multiple spans return their union (the span enclosing all of them). AND clauses specifying multiple spans return their intersection. NOT clauses are ignored.

queryDepth :: Query -> DepthSpec #

The depth limit this query specifies, if it has one

inAccount :: [QueryOpt] -> Maybe (AccountName, Bool) #

The account we are currently focussed on, if any, and whether subaccounts are included. Just looks at the first query option.

inAccountQuery :: [QueryOpt] -> Maybe Query #

A query for the account(s) we are currently focussed on, if any. Just looks at the first query option.

# matching things with queries

matchesTransaction :: Query -> Transaction -> Bool #

Does the match expression match this transaction ?

matchesTransactionExtra :: (AccountName -> Maybe AccountType) -> Query -> Transaction -> Bool #

Like matchesTransaction, but if the journal's account types are provided, any type: terms in the query must match at least one posting's account type (and any negated type: terms must match none).

matchesDescription :: Query -> Text -> Bool #

Does the query match this transaction description ? Tests desc: terms, any other terms are ignored.

matchesPayeeWIP :: Query -> Payee -> Bool #

Does the query match this transaction payee ? Tests desc: (and payee: ?) terms, any other terms are ignored. XXX Currently an alias for matchDescription. I'm not sure if more is needed, There's some shenanigan with payee: and "payeeTag" to figure out.

matchesPosting :: Query -> Posting -> Bool #

Does the match expression match this posting ? When matching account name, and the posting has been transformed in some way, we will match either the original or transformed name.

matchesPostingExtra :: (AccountName -> Maybe AccountType) -> Query -> Posting -> Bool #

Like matchesPosting, but if the posting's account's type is provided, any type: terms in the query must match it (and any negated type: terms must not match it).

matchesAccount :: Query -> AccountName -> Bool #

Does the query match this account name ? A matching in: clause is also considered a match.

matchesAccountExtra :: (AccountName -> Maybe AccountType) -> (AccountName -> [Tag]) -> Query -> AccountName -> Bool #

Like matchesAccount, but with optional extra matching features:

- If the account's type is provided, any type: terms in the query must match it (and any negated type: terms must not match it).
- If the account's tags are provided, any tag: terms must match at least one of them (and any negated tag: terms must match none).

matchesMixedAmount :: Query -> MixedAmount -> Bool #

matchesAmount :: Query -> Amount -> Bool #

Does the match expression match this (simple) amount ?

matchesCommodity :: Query -> CommoditySymbol -> Bool #

matchesTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool #

Does the query match the name and optionally the value of any of these tags ?

matchesPriceDirective :: Query -> PriceDirective -> Bool #

Does the query match this market price ?

words'' :: [Text] -> Text -> [Text] #

Quote-and-prefix-aware version of words - don't split on spaces which are inside quotes, including quotes which may have one of the specified prefixes in front, and maybe an additional not: prefix in front of that.

queryprefixes :: [Text] #

# tests

tests_Query :: TestTree #