1"""A library to run queries. This glues together all the parts of the query engine.
2"""
3__copyright__ = "Copyright (C) 2015-2017  Martin Blais"
4__license__ = "GNU GPLv2"
5
6from beancount.query import query_parser
7from beancount.query import query_compile
8from beancount.query import query_env
9from beancount.query import query_execute
10from beancount.query import numberify as numberify_lib
11
12
13def run_query(entries, options_map, query, *format_args, numberify=False):
14    """Compile and execute a query, return the result types and rows.
15
16    Args:
17      entries: A list of entries, as produced by the loader.
18      options_map: A dict of options, as produced by the loader.
19      query: A string, a single BQL query, optionally containing some new-style
20        (e.g., {}) formatting specifications.
21      format_args: A tuple of arguments to be formatted in the query. This is
22        just provided as a convenience.
23      numberify: If true, numberify the results before returning them.
24    Returns:
25      A pair of result types and result rows.
26    Raises:
27      ParseError: If the statement cannot be parsed.
28      CompilationError: If the statement cannot be compiled.
29    """
30    env_targets = query_env.TargetsEnvironment()
31    env_entries = query_env.FilterEntriesEnvironment()
32    env_postings = query_env.FilterPostingsEnvironment()
33
34    # Apply formatting to the query.
35    formatted_query = query.format(*format_args)
36
37    # Parse the statement.
38    parser = query_parser.Parser()
39    statement = parser.parse(formatted_query)
40
41    # Compile the SELECT statement.
42    c_query = query_compile.compile(statement,
43                                    env_targets,
44                                    env_postings,
45                                    env_entries)
46
47    # Execute it to obtain the result rows.
48    rtypes, rrows = query_execute.execute_query(c_query, entries, options_map)
49
50    # Numberify the results, if requested.
51    if numberify:
52        dformat = options_map['dcontext'].build()
53        rtypes, rrows = numberify_lib.numberify_results(rtypes, rrows, dformat)
54
55    return rtypes, rrows
56