def show_tables(etcd_client, tree, db): """ Execute SHOW [FULL] TABLES query# :param etcd_client: etcd client :type etcd_client: pyetcd.client.Client :param db: Current database :type db: str :param tree: Parse tree :type tree: SQLTree :return: ResultSet instance :rtype: ResultSet """ columns = ColumnSet().add(Column('Tables_in_%s' % db)) if tree.options['full']: columns.add(Column('Table_type')) result_set = ResultSet(columns) try: etcd_response = etcd_client.read('/%s' % db) except EtcdKeyNotFound: raise OperationalError('No database selected') try: for node in etcd_response.node['nodes']: table_name = node['key'].replace('/%s/' % db, '', 1) row = (table_name, ) if tree.options['full']: row += ('BASE TABLE', ) result_set.add_row(Row(row)) except KeyError: pass return result_set
def execute_select_no_table(tree): """Execute SELECT that doesn't read from a table. SELECT VERSION() or similar.""" result_columns = prepare_columns(tree) result_set = ResultSet(result_columns) result_row = Row(eval_row(result_columns, Row(()), tree)) result_set.add_row(result_row) return result_set
def test_cursor_fetchone(etcdb_connection): cursor = etcdb_connection.cursor() columns = ColumnSet().add(Column('VERSION()')) rs = ResultSet(columns) rs.add_row(Row(('2.3.7', ))) cursor._result_set = rs row = cursor.fetchone() assert isinstance(row, tuple) assert row == ('2.3.7', )
def test_show_tables(content, rows): response = mock.Mock() response.content = content etcd_response = EtcdResult(response) etcd_client = mock.Mock() etcd_client.read.return_value = etcd_response cols = ColumnSet() cols.add(Column('Tables_in_foo')) # print(cols) rs = ResultSet(cols, rows) tree = SQLTree() tree.db = 'foo' tree.options['full'] = False # noinspection PyTypeChecker result = show_tables(etcd_client, tree, tree.db) print("Expected: \n%s" % rs) print("Actual: \n%s" % result) # noinspection PyTypeChecker assert result == rs
def execute_select(etcd_client, tree, db): """ Execute SELECT query. :param etcd_client: etcd client. :type etcd_client: pyetcd.client.Client :param db: Current database. :type db: str :param tree: Parse tree. :type tree: SQLTree :return: ResultSet instance. :rtype: ResultSet """ if not db: raise OperationalError('No database selected') if tree.table: tree = fix_tree_star(tree, etcd_client, db, tree.table) result_set = execute_select_plain(etcd_client, tree, db) else: result_set = execute_select_no_table(tree) if tree.limit is not None: result_set = ResultSet(result_set.columns, result_set[:tree.limit]) return result_set
def test_fetch_many(rows, n, result, etcdb_connection): cursor = etcdb_connection.cursor() rs = ResultSet(ColumnSet().add(Column('Tables')), rows ) cursor._result_set = rs assert cursor.fetchmany(n) == result
def test_fetch_all(rows, result, etcdb_connection): cursor = etcdb_connection.cursor() rs = ResultSet(ColumnSet().add(Column('Tables')), rows ) cursor._result_set = rs # for i in xrange(len(result)): assert cursor.fetchall() == result assert cursor.fetchall() == ()
def show_databases(etcd_client): """ Execute SHOW [FULL] TABLES query :param etcd_client: etcd client :type etcd_client: pyetcd.client.Client :return: ResultSet instance :rtype: ResultSet """ etcd_response = etcd_client.read('/') columns = ColumnSet().add(Column('Database')) result_set = ResultSet(columns) try: for node in etcd_response.node['nodes']: val = node['key'].lstrip('/') result_set.add_row(Row((val, ))) except KeyError: pass return result_set
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
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
def group_result_set(func, result_set, table_row, tree, pos): """Apply a group function to result set and return an aggregated row. :param func: Aggregation function. :type func: callable :param result_set: Result set to aggregate. :type result_set: ResultSet :param table_row: Table row to base aggregated row on. :type table_row: Row :param tree: Parsing tree. :type tree: SQLTree :param pos: Aggregate function position in the resulting row. :type pos: int :return: Result set with aggregated row. :rtype: ResultSet""" group_value = func(result_set) values = list(eval_row(result_set.columns, table_row, tree)) values[pos] = group_value row = Row(tuple(values)) return ResultSet(prepare_columns(tree), [row])
def test_show_databases(content, rows): response = mock.Mock() response.content = content etcd_response = EtcdResult(response) etcd_client = mock.Mock() etcd_client.read.return_value = etcd_response cols = ColumnSet() cols.add(Column('Database')) # print(cols) rs = ResultSet(cols, rows) # noinspection PyTypeChecker result = show_databases(etcd_client) print("Expected: \n%s" % rs) print("Actual: \n%s" % result) # noinspection PyTypeChecker assert result == rs
def test_n_rows(cursor): rs = ResultSet(ColumnSet().add(Column('foo'))) cursor._result_set = rs assert cursor.n_rows == 0
def desc_table(etcd_client, tree, db): """ Execute DESC table query# :param etcd_client: etcd client :type etcd_client: pyetcd.client.Client :param tree: Parse tree :type tree: SQLTree :param db: Current database :type db: str :return: ResultSet instance :rtype: ResultSet """ key = '/{db}/{table}/_fields'.format(db=db, table=tree.table) try: etcd_result = etcd_client.read(key) except EtcdKeyNotFound: raise ProgrammingError('Table `{db}`.`{table}` ' 'doesn\'t exist'.format(db=db, table=tree.table)) columns = ColumnSet() columns.add(Column('Field')) columns.add(Column('Type')) columns.add(Column('Null')) columns.add(Column('Key')) columns.add(Column('Default')) columns.add(Column('Extra')) result_set = ResultSet(columns) fields = json.loads(etcd_result.node['value']) for key, value in fields.iteritems(): field_type = value['type'] if value['options']['nullable']: nullable = 'YES' else: nullable = 'NO' indexes = '' if 'primary' in value['options'] and value['options']['primary']: indexes = 'PRI' if 'unique' in value['options'] and value['options']['unique']: indexes = 'UNI' try: default_value = value['options']['default'] except KeyError: default_value = '' extra = '' if 'auto_increment' in value['options'] \ and value['options']['auto_increment']: extra = 'auto_increment' result_set.add_row( Row((key, field_type, nullable, indexes, default_value, extra))) return result_set
], (EtcdbFunction(etcdb_count, group=True),) ) ]) def test_eval_row(cs, row, expressions, result): tree = SQLTree() tree.expressions = expressions assert eval_row(cs, row, tree) == result @pytest.mark.parametrize('rs, row, expressions, result', [ ( ResultSet(ColumnSet().add(Column(str( EtcdbFunction(etcdb_count, group=True)))), []), None, [ ( ('bool_primary', ('predicate', ('bit_expr', ('simple_expr', ('function_call', 'COUNT') ) ) ) ), '__count' ) ],
def test_etcdb_count(rows, count): cs = ColumnSet().add(Column('id')) rs = ResultSet(cs, rows) assert etcdb_count(rs) == count