示例#1
0
def execute_update(etcd_client, tree, db):
    """Execute UPDATE query"""
    affected_rows = 0
    table_columns = get_table_columns(etcd_client, db, tree.table)

    for primary_key in list_table(etcd_client, db, tree.table):

        table_row = get_row_by_primary_key(etcd_client, db, tree.table,
                                           primary_key)
        key = '/{db}/{tbl}/{pk}'.format(db=db, tbl=tree.table, pk=primary_key)

        row = {}
        for column in table_columns:
            index = table_columns.index(column)
            row[str(column)] = table_row[index]

        for update_fields in tree.expressions:
            field_name, field_expression = update_fields

            field_value = eval_expr(table_row, field_expression)
            # print('Update %s with %s' % (field_name, field_value[1]))
            row[field_name] = field_value[1]

        if tree.where:

            if eval_expr((table_columns, table_row), tree.where)[1]:
                _update_key(etcd_client, key, json.dumps(row))
                affected_rows += 1
        else:
            _update_key(etcd_client, key, json.dumps(row))
            affected_rows += 1
    return affected_rows
示例#2
0
def execute_select_plain(etcd_client, tree, db):
    """Execute SELECT that reads rows from table."""

    result_columns = prepare_columns(tree)
    result_set = ResultSet(result_columns)

    table_columns = get_table_columns(etcd_client, db, tree.table)

    last_row = None
    for primary_key in list_table(etcd_client, db, tree.table):

        table_row = get_row_by_primary_key(etcd_client, db, tree.table,
                                           primary_key)

        if tree.where:
            expr = tree.where
            if eval_expr((table_columns, table_row), expr)[1]:
                row = Row(eval_row(table_columns, table_row, tree),
                          etcd_index=table_row.etcd_index,
                          modified_index=table_row.modified_index)
                result_set.add_row(row)
                last_row = table_row
        else:
            row = Row(eval_row(table_columns, table_row, tree),
                      etcd_index=table_row.etcd_index,
                      modified_index=table_row.modified_index)
            result_set.add_row(row)
            last_row = table_row

    g_function, pos = group_function(table_columns, last_row, tree)
    if g_function:
        result_set = group_result_set(g_function, result_set, last_row, tree,
                                      pos)

    return result_set
示例#3
0
def execute_wait(etcd_client, tree, db):
    """Execute WAIT.

    :param etcd_client: Etcd client.
    :type etcd_client: Client
    :param tree: Parsing tree.
    :type tree: SQLTree
    :param db: Current database.
    :type db: str
    """

    result_columns = prepare_columns(tree)
    result_set = ResultSet(result_columns)

    table_columns = get_table_columns(etcd_client, db, tree.table)

    for primary_key in list_table(etcd_client, db, tree.table):

        table_row = get_row_by_primary_key(etcd_client, db, tree.table,
                                           primary_key)
        etcd_index = table_row.etcd_index

        if tree.where:
            expr = tree.where
            try:
                wait_index = tree.options['after']
            except KeyError:
                wait_index = etcd_index + 1

            if eval_expr((table_columns, table_row), expr)[1]:
                start = time.time()
                while True:
                    if time.time() > start + WAIT_WAIT_TIMEOUT:
                        raise InternalError('Wait timeout %d '
                                            'seconds expired' %
                                            WAIT_WAIT_TIMEOUT)
                    try:
                        new_row = get_row_by_primary_key(etcd_client,
                                                         db,
                                                         tree.table,
                                                         primary_key,
                                                         wait=True,
                                                         wait_index=wait_index)
                        break
                    except KeyError:
                        wait_index += 1
                row = Row(eval_row(table_columns, new_row, tree),
                          etcd_index=new_row.etcd_index,
                          modified_index=new_row.modified_index)
                result_set.add_row(row)
        else:
            row = Row(eval_row(table_columns, table_row, tree),
                      etcd_index=etcd_index,
                      modified_index=etcd_index)
            result_set.add_row(row)

    return result_set
示例#4
0
def test_expr_in_simple_expr():
    tree = SQLTree()
    tree.expressions = [(('bool_primary', ('predicate',
                                           ('bit_expr',
                                            ('simple_expr',
                                             ('expr', ('bool_primary',
                                                       ('predicate',
                                                        ('bit_expr',
                                                         ('simple_expr',
                                                          ('literal',
                                                           '1')))))))))), 'a')]

    assert eval_expr(None, tree.expressions[0][0]) == ('1', '1')
示例#5
0
    def _execute_select(self, tree):
        db = self._get_current_db(tree)
        tbl = tree.table
        rows = ()
        columns = ()
        lock_id = self._get_read_lock(db, tbl)
        try:
            function_exists = False
            variable_exists = False
            for expression in tree.expressions:
                columns += (expression['name'], )
                if expression['type'] == 'function':
                    function_exists = True
                if expression['type'] == 'variable':
                    variable_exists = True

            result_keys = self._get_pks(db, tbl, tree)

            if function_exists or variable_exists:
                result_keys.append(None)

            for pk in result_keys:
                row = self.get_table_row(tree, pk)
                if tree.where:
                    if eval_expr((columns, row), tree.where):
                        rows += (row, )
                else:
                    rows += (row, )

            if tree.order['by'] and tree.order['by'] in columns:
                pos = columns.index(tree.order['by'])

                def getKey(item):
                    return item[pos]

                reverse = False
                if tree.order['direction'] == 'DESC':
                    reverse = True

                rows = sorted(rows, reverse=reverse, key=getKey)

            if tree and tree.limit is not None:
                rows = rows[:tree.limit]
            return columns, rows
        finally:
            self._release_read_lock(db, tbl, lock_id)
示例#6
0
def prepare_columns(tree):
    """
    Generate ColumnSet for query result. ColumnsSet doesn't include
    a grouping function.

    :return: Columns of the query result.
    :rtype: ColumnSet
    """
    columns = ColumnSet()
    for select_item in tree.expressions:

        expr, alias = select_item

        colname, _ = eval_expr(None, tree=expr)
        if alias:
            colname = alias

        columns.add(Column(colname))

    return columns
示例#7
0
def execute_delete(etcd_client, tree, db):
    """Execute DELETE query"""
    affected_rows = 0
    table_columns = get_table_columns(etcd_client, db, tree.table)
    for primary_key in list_table(etcd_client, db, tree.table):

        table_row = get_row_by_primary_key(etcd_client, db, tree.table,
                                           primary_key)

        key = "/{db}/{tbl}/{pk}".format(db=db, tbl=tree.table, pk=primary_key)

        if tree.where:
            expr = tree.where
            if eval_expr((table_columns, table_row), expr)[1]:
                _delete_key(etcd_client, key)
            affected_rows += 1
        else:
            _delete_key(etcd_client, key)
            affected_rows += 1

    return affected_rows
示例#8
0
def group_function(table_columns, table_row, tree):
    """True if resultset should be grouped

    :return: Grouping function or None and its position.
    :rtype: tuple(EtcdbFunction, int)"""

    try:

        group_position = 0
        for select_item in tree.expressions:
            expr = select_item[0]
            expr_value = eval_expr((table_columns, table_row), tree=expr)[1]

            if isinstance(expr_value, EtcdbFunction):

                if expr_value.group:
                    return expr_value, group_position
            group_position += 1
        return None, None
    except TypeError:
        return None, None
示例#9
0
def eval_row(table_columns, table_row, tree):
    """Find values of a row. table_columns are fields in the table.
    The result columns is taken from tree.expressions.

    :param table_columns: Columns in the table row.
    :type table_columns: ColumnSet
    :param table_row: Input row.
    :type table_row: Row
    :param tree: Parsing tree.
    :type tree: SQLTree
    """
    result_row = ()

    for select_item in tree.expressions:
        expr = select_item[0]
        expr_value = eval_expr((table_columns, table_row), tree=expr)[1]
        if isinstance(expr_value, EtcdbFunction) and not expr_value.group:
            expr_value = expr_value()

        result_row += (expr_value, )

    return result_row