Ejemplo n.º 1
0
def get_matching_entries(entries, options_map, query):
    query_text = 'SELECT * ' + query
    parser = query_parser.Parser()
    parsed_query = parser.parse(query_text)
    c_from = None
    if parsed_query.from_clause:
        c_from = query_compile.compile_from(parsed_query.from_clause, query_env.FilterEntriesEnvironment())
    c_where = None
    if parsed_query.where_clause:
        c_where = query_compile.compile_expression(parsed_query.where_clause, query_env.FilterPostingsEnvironment())

    # Figure out if we need to compute balance.
    balance = None
    if c_where and query_execute.uses_balance_column(c_where):
        balance = inventory.Inventory()

    context = query_execute.RowContext()
    context.balance = balance
    

    # Initialize some global properties for use by some of the accessors.
    context.options_map = options_map
    context.account_types = options.get_account_types(options_map)
    context.open_close_map = getters.get_account_open_close(entries)
    #context.commodity_map = getters.get_commodity_map(entries)
    context.price_map = prices.build_price_map(entries) 

    if c_from is not None:
        filtered_entries = query_execute.filter_entries(c_from, entries, options_map)
    else:
        filtered_entries = entries
    return filtered_entries
Ejemplo n.º 2
0
def transform_balances(balances):
    """Translate a Balances entry into an uncompiled Select statement.

    Args:
      balances: An instance of a Balance object.
    Returns:
      An instance of an uncompiled Select object.
    """
    ## FIXME: Change the aggregation rules to allow GROUP-BY not to include the
    ## non-aggregate ORDER-BY columns, so we could just GROUP-BY accounts here
    ## instead of having to include the sort-key. I think it should be fine if
    ## the first or last sort-order value gets used, because it would simplify
    ## the input statement.

    cooked_select = query_parser.Parser().parse("""

      SELECT account, SUM({}(position))
      GROUP BY account, ACCOUNT_SORTKEY(account)
      ORDER BY ACCOUNT_SORTKEY(account)

    """.format(balances.summary_func or ""))

    return query_parser.Select(cooked_select.targets,
                               balances.from_clause,
                               balances.where_clause,
                               cooked_select.group_by,
                               cooked_select.order_by,
                               None, None, None, None)
Ejemplo n.º 3
0
def transform_journal(journal):
    """Translate a Journal entry into an uncompiled Select statement.

    Args:
      journal: An instance of a Journal object.
    Returns:
      An instance of an uncompiled Select object.
    """
    cooked_select = query_parser.Parser().parse("""

        SELECT
           date,
           flag,
           MAXWIDTH(payee, 48),
           MAXWIDTH(narration, 80),
           account,
           {summary_func}(position),
           {summary_func}(balance)
        {where}

    """.format(where=('WHERE account ~ "{}"'.format(journal.account)
                      if journal.account
                      else ''),
               summary_func=journal.summary_func or ''))

    return query_parser.Select(cooked_select.targets,
                               journal.from_clause,
                               cooked_select.where_clause,
                               None, None, None, None, None, None)
Ejemplo n.º 4
0
    def __init__(self, is_interactive, loadfun, outfile):
        super().__init__(is_interactive, query_parser.Parser(), outfile)

        self.loadfun = loadfun
        self.entries = None
        self.errors = None
        self.options_map = None

        self.env_targets = query_env.TargetsEnvironment()
        self.env_entries = query_env.FilterEntriesEnvironment()
        self.env_postings = query_env.FilterPostingsEnvironment()
Ejemplo n.º 5
0
    def __init__(self, is_interactive, loadfun, outfile,
                 default_format='text', do_numberify=False):
        super().__init__(is_interactive, query_parser.Parser(), outfile,
                         default_format, do_numberify)

        self.loadfun = loadfun
        self.entries = None
        self.errors = None
        self.options_map = None

        self.env_targets = query_env.TargetsEnvironment()
        self.env_entries = query_env.FilterEntriesEnvironment()
        self.env_postings = query_env.FilterPostingsEnvironment()
Ejemplo n.º 6
0
def run_query(entries, options_map, query, *format_args, numberify=False):
    """Compile and execute a query, return the result types and rows.

    Args:
      entries: A list of entries, as produced by the loader.
      options_map: A dict of options, as produced by the loader.
      query: A string, a single BQL query, optionally containing some new-style
        (e.g., {}) formatting specifications.
      format_args: A tuple of arguments to be formatted in the query. This is
        just provided as a convenience.
      numberify: If true, numberify the results before returning them.
    Returns:
      A pair of result types and result rows.
    Raises:
      ParseError: If the statement cannot be parsed.
      CompilationError: If the statement cannot be compiled.
    """
    env_targets = query_env.TargetsEnvironment()
    env_entries = query_env.FilterEntriesEnvironment()
    env_postings = query_env.FilterPostingsEnvironment()

    # Apply formatting to the query.
    formatted_query = query.format(*format_args)

    # Parse the statement.
    parser = query_parser.Parser()
    statement = parser.parse(formatted_query)

    # Compile the SELECT statement.
    c_query = query_compile.compile(statement, env_targets, env_postings,
                                    env_entries)

    # Execute it to obtain the result rows.
    rtypes, rrows = query_execute.execute_query(c_query, entries, options_map)

    # Numberify the results, if requested.
    if numberify:
        dformat = options_map['dcontext'].build()
        rtypes, rrows = numberify_lib.numberify_results(rtypes, rrows, dformat)

    return rtypes, rrows
Ejemplo n.º 7
0
    """A token having a certain type and value.

    The lexer attribute only exists since PLY writes to it in case of a parser
    error.
    """
    __slots__ = ['type', 'value', 'lexer']

    def __init__(self, type_, value):
        self.type = type_
        self.value = value

    def __repr__(self):
        return 'Token({}, {})'.format(self.type, self.value)


QUERY_PARSER = query_parser.Parser()
ENV_ENTRIES = query_env.FilterEntriesEnvironment()


class FilterSyntaxLexer(object):
    """Lexer for Fava's filter syntax."""
    # pylint: disable=missing-docstring,invalid-name,no-self-use

    tokens = (
        'ANY',
        'KEY',
        'LINK',
        'STRING',
        'TAG',
    )
Ejemplo n.º 8
0
 def setUp(self):
     super().setUp()
     self.parser = query_parser.Parser()
Ejemplo n.º 9
0
 def setUp(self):
     self.parser = qp.Parser()
Ejemplo n.º 10
0
 def __init__(self):
     super().__init__()
     self.parser = query_parser.Parser()
     self.env_entries = query_env.FilterEntriesEnvironment()
     self.c_from = None