mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-29 13:22:27 +03:00
fix: tags: also match accounts declared but not used (#1857)
By default, all account declarations and all transactions are searched; but when there's a query involving transaction fields, account declarations unrelated to the matched transactions are not searched. added: queryIsCode queryIsTransactionRelated
This commit is contained in:
parent
4f26309328
commit
5af224d534
@ -29,20 +29,21 @@ module Hledger.Query (
|
||||
matchesQuery,
|
||||
-- * predicates
|
||||
queryIsNull,
|
||||
queryIsAcct,
|
||||
queryIsAmt,
|
||||
queryIsDepth,
|
||||
queryIsDate,
|
||||
queryIsDate2,
|
||||
queryIsDateOrDate2,
|
||||
queryIsStartDateOnly,
|
||||
queryIsSym,
|
||||
queryIsReal,
|
||||
queryIsStatus,
|
||||
queryIsType,
|
||||
queryIsCode,
|
||||
queryIsDesc,
|
||||
queryIsTag,
|
||||
queryIsAccountRelated,
|
||||
queryIsTransactionOrPostingRelated,
|
||||
queryIsAcct,
|
||||
queryIsType,
|
||||
queryIsDepth,
|
||||
queryIsReal,
|
||||
queryIsAmt,
|
||||
queryIsSym,
|
||||
queryIsStartDateOnly,
|
||||
queryIsTransactionRelated,
|
||||
-- * accessors
|
||||
queryStartDate,
|
||||
queryEndDate,
|
||||
@ -478,13 +479,9 @@ queryIsNull (And []) = True
|
||||
queryIsNull (Not (Or [])) = True
|
||||
queryIsNull _ = False
|
||||
|
||||
-- | Is this a simple query of this type ("depth:D") ?
|
||||
-- Note, does not match a compound query like "not:depth:D" or "depth:D acct:A".
|
||||
-- | Is this a simple query of this type (date:) ?
|
||||
-- Does not match a compound query involving and/or/not.
|
||||
-- Likewise for the following functions.
|
||||
queryIsDepth :: Query -> Bool
|
||||
queryIsDepth (Depth _) = True
|
||||
queryIsDepth _ = False
|
||||
|
||||
queryIsDate :: Query -> Bool
|
||||
queryIsDate (Date _) = True
|
||||
queryIsDate _ = False
|
||||
@ -498,14 +495,38 @@ queryIsDateOrDate2 (Date _) = True
|
||||
queryIsDateOrDate2 (Date2 _) = True
|
||||
queryIsDateOrDate2 _ = False
|
||||
|
||||
queryIsStatus :: Query -> Bool
|
||||
queryIsStatus (StatusQ _) = True
|
||||
queryIsStatus _ = False
|
||||
|
||||
queryIsCode :: Query -> Bool
|
||||
queryIsCode (Code _) = True
|
||||
queryIsCode _ = False
|
||||
|
||||
queryIsDesc :: Query -> Bool
|
||||
queryIsDesc (Desc _) = True
|
||||
queryIsDesc _ = False
|
||||
|
||||
queryIsTag :: Query -> Bool
|
||||
queryIsTag (Tag _ _) = True
|
||||
queryIsTag _ = False
|
||||
|
||||
queryIsAcct :: Query -> Bool
|
||||
queryIsAcct (Acct _) = True
|
||||
queryIsAcct _ = False
|
||||
|
||||
queryIsType :: Query -> Bool
|
||||
queryIsType (Type _) = True
|
||||
queryIsType _ = False
|
||||
|
||||
queryIsDepth :: Query -> Bool
|
||||
queryIsDepth (Depth _) = True
|
||||
queryIsDepth _ = False
|
||||
|
||||
queryIsReal :: Query -> Bool
|
||||
queryIsReal (Real _) = True
|
||||
queryIsReal _ = False
|
||||
|
||||
queryIsAmt :: Query -> Bool
|
||||
queryIsAmt (Amt _ _) = True
|
||||
queryIsAmt _ = False
|
||||
@ -514,22 +535,6 @@ queryIsSym :: Query -> Bool
|
||||
queryIsSym (Sym _) = True
|
||||
queryIsSym _ = False
|
||||
|
||||
queryIsReal :: Query -> Bool
|
||||
queryIsReal (Real _) = True
|
||||
queryIsReal _ = False
|
||||
|
||||
queryIsStatus :: Query -> Bool
|
||||
queryIsStatus (StatusQ _) = True
|
||||
queryIsStatus _ = False
|
||||
|
||||
queryIsType :: Query -> Bool
|
||||
queryIsType (Type _) = True
|
||||
queryIsType _ = False
|
||||
|
||||
queryIsTag :: Query -> Bool
|
||||
queryIsTag (Tag _ _) = True
|
||||
queryIsTag _ = False
|
||||
|
||||
-- | 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.
|
||||
@ -542,29 +547,18 @@ queryIsStartDateOnly False (Date (DateSpan (Just _) _)) = True
|
||||
queryIsStartDateOnly True (Date2 (DateSpan (Just _) _)) = True
|
||||
queryIsStartDateOnly _ _ = False
|
||||
|
||||
-- | Does this query involve a property which only accounts (without their balances) have,
|
||||
-- making it inappropriate for matching other things ?
|
||||
queryIsAccountRelated :: Query -> Bool
|
||||
queryIsAccountRelated = matchesQuery (
|
||||
queryIsAcct
|
||||
||| queryIsDepth
|
||||
||| queryIsType
|
||||
)
|
||||
|
||||
-- | Does this query involve a property which only transactions or postings have,
|
||||
-- making it inappropriate for matching other things ?
|
||||
queryIsTransactionOrPostingRelated :: Query -> Bool
|
||||
queryIsTransactionOrPostingRelated = matchesQuery (
|
||||
queryIsAmt
|
||||
-- ||| queryIsCode
|
||||
-- ||| queryIsCur
|
||||
||| queryIsDesc
|
||||
||| queryIsDate
|
||||
-- | Does this query involve a property of transactions (or their postings),
|
||||
-- making it inapplicable to account declarations ?
|
||||
queryIsTransactionRelated :: Query -> Bool
|
||||
queryIsTransactionRelated = matchesQuery (
|
||||
queryIsDate
|
||||
||| queryIsDate2
|
||||
-- ||| queryIsNote
|
||||
-- ||| queryIsPayee
|
||||
||| queryIsReal
|
||||
||| queryIsStatus
|
||||
||| queryIsCode
|
||||
||| queryIsDesc
|
||||
||| queryIsReal
|
||||
||| queryIsAmt
|
||||
||| queryIsSym
|
||||
)
|
||||
|
||||
(|||) :: (a->Bool) -> (a->Bool) -> (a->Bool)
|
||||
|
@ -29,21 +29,28 @@ tags :: CliOpts -> Journal -> IO ()
|
||||
tags CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
|
||||
let today = _rsDay rspec
|
||||
args = listofstringopt "args" rawopts
|
||||
-- first argument is a tag name pattern, others are a hledger query: hledger tags [TAGREGEX [QUERYARGS..]]
|
||||
mtagpat <- mapM (either Fail.fail pure . toRegexCI . T.pack) $ headMay args
|
||||
let
|
||||
querystring = map T.pack $ drop 1 args
|
||||
querystr = map T.pack $ drop 1 args
|
||||
values = boolopt "values" rawopts
|
||||
parsed = boolopt "parsed" rawopts
|
||||
empty = empty_ $ _rsReportOpts rspec
|
||||
|
||||
argsquery <- either usageError (return . fst) $ parseQueryList today querystring
|
||||
query <- either usageError (return . fst) $ parseQueryList today querystr
|
||||
let
|
||||
q = simplifyQuery $ And [queryFromFlags $ _rsReportOpts rspec, argsquery]
|
||||
txns = filter (q `matchesTransaction`) $ jtxns $ journalApplyValuationFromOpts rspec j
|
||||
q = simplifyQuery $ And [queryFromFlags $ _rsReportOpts rspec, query]
|
||||
matchedtxns = filter (q `matchesTransaction`) $ jtxns $ journalApplyValuationFromOpts rspec j
|
||||
-- also list tags from matched account declarations, but not if there is
|
||||
-- a query for something transaction-related, like date: or amt:.
|
||||
matchedaccts = dbg4 "accts" $
|
||||
if dbg4 "queryIsTransactionRelated" $ queryIsTransactionRelated $ dbg4 "q" q
|
||||
then []
|
||||
else filter (matchesAccountExtra (journalAccountType j) (journalInheritedAccountTags j) q) $
|
||||
map fst $ jdeclaredaccounts j
|
||||
tagsorvalues =
|
||||
(if parsed then id else nubSort)
|
||||
[ r
|
||||
| (t,v) <- concatMap transactionAllTags txns
|
||||
| (t,v) <- concatMap (journalAccountTags j) matchedaccts ++ concatMap transactionAllTags matchedtxns
|
||||
, maybe True (`regexMatchText` t) mtagpat
|
||||
, let r = if values then v else t
|
||||
, not (values && T.null v && not empty)
|
||||
|
@ -1,14 +1,23 @@
|
||||
tags\
|
||||
List the unique tag names used in the journal. With a TAGREGEX argument,
|
||||
only tag names matching the regular expression (case insensitive) are shown.
|
||||
With QUERY arguments, only transactions matching the query are considered.
|
||||
List the unique tag names used in the journal, whether on transactions, postings,
|
||||
or account declarations.
|
||||
|
||||
With the --values flag, the tags' unique values are listed instead.
|
||||
With a TAGREGEX argument, only tag names matching this regular expression
|
||||
(case insensitive, infix matched) are shown.
|
||||
|
||||
With --parsed flag, all tags or values are shown in the order they
|
||||
are parsed from the input data, including duplicates.
|
||||
With QUERY arguments, only transactions and accounts matching this query are considered.
|
||||
If the query involves transaction fields (date:, desc:, amt:, ...),
|
||||
the search is restricted to the matched transactions and their accounts.
|
||||
|
||||
With -E/--empty, any blank/empty values will also be shown, otherwise
|
||||
they are omitted.
|
||||
With the --values flag, the tags' unique non-empty values are listed instead.
|
||||
With -E/--empty, blank/empty values are also shown.
|
||||
|
||||
With --parsed, tags or values are shown in the order they were parsed, with duplicates included.
|
||||
(Except, tags from account declarations are always shown first.)
|
||||
|
||||
_FLAGS
|
||||
|
||||
Tip: remember,
|
||||
accounts also acquire tags from their parents,
|
||||
postings also acquire tags from their account and transaction,
|
||||
transactions also acquire tags from their postings.
|
||||
|
@ -1,32 +1,56 @@
|
||||
# tags command
|
||||
|
||||
account a ; t1:v1
|
||||
account a ; t1:v1, an account tag
|
||||
account b:bb ; t2:v2, an unused account, depth 2
|
||||
|
||||
2000/1/1 ; t2:v2
|
||||
(b) 1 ; t3:v3
|
||||
2000/1/1 ; t3:v3, a transaction tag
|
||||
(a:aa) 1 ; t4:v4, a posting tag
|
||||
|
||||
2000/1/2 ; t4:v4
|
||||
(b) 1 ; t5:v5
|
||||
2000/1/2 ; t5:v4, a reused value
|
||||
(c) 1 ; t6:v6, an undeclared account
|
||||
|
||||
# 1. list all tags
|
||||
$ hledger -f - tags
|
||||
# 1. show all tags
|
||||
$ hledger -f- tags
|
||||
t1
|
||||
t2
|
||||
t3
|
||||
t4
|
||||
t5
|
||||
t6
|
||||
|
||||
# 2. list tag names matching a regex
|
||||
$ hledger -f - tags '[24]'
|
||||
t2
|
||||
t4
|
||||
|
||||
# 3. list tag values
|
||||
$ hledger -f - tags --values
|
||||
# 2. show all tag values
|
||||
$ hledger -f- tags --values
|
||||
v1
|
||||
v2
|
||||
v3
|
||||
v4
|
||||
v5
|
||||
v6
|
||||
|
||||
# 4. list values of tags matching a regex from transactions matching a query
|
||||
$ hledger -f - tags t3 date:2000/1/1 --values
|
||||
v3
|
||||
# 3. show tags matching a regex
|
||||
$ hledger -f- tags '[1-4]'
|
||||
t1
|
||||
t2
|
||||
t3
|
||||
t4
|
||||
|
||||
# 4. show tags matching (a regex and) a hledger query.
|
||||
# If the query is applicable to both transactions and account declarations,
|
||||
# both are searched for tags.
|
||||
$ hledger -f- tags . b c
|
||||
t2
|
||||
t5
|
||||
t6
|
||||
|
||||
# 5. If the query involves transaction attributes,
|
||||
# only accounts used by the matched transactions will contribute tags.
|
||||
$ hledger -f- tags . date:2000/1/1
|
||||
t1
|
||||
t3
|
||||
t4
|
||||
|
||||
# 6. show account tags even when there are no transactions (#1857)
|
||||
<
|
||||
account a ; t1:
|
||||
|
||||
$ hledger -f- tags
|
||||
t1
|
||||
|
Loading…
Reference in New Issue
Block a user