def database_exists_or_raise(etcd_client, db): """If database db doesn't exit raise OperationalError. :param etcd_client: Etcd client. :type etcd_client: Client :param db: Database name. :type db: str :raise OperationalError: if database doesn't exist""" if not db: raise OperationalError('No database selected') # Check if database exists try: etcd_client.read('/%s' % db) except EtcdKeyNotFound: raise OperationalError("Unknown database '%s'" % db)
def eval_identifier(row, identifier): """ Get value of identifier for a given row :param row: row :type row: tuple(ColumnSet, Row) :param identifier: Identifier :type identifier: str :return: value of identifier """ try: identifier_strip = identifier.split('.')[1] except IndexError: identifier_strip = identifier # If row isn't given return column name only if row: columns = row[0] data = row[1] else: return identifier_strip, None try: pos = columns.index(Column(identifier_strip)) return identifier_strip, data[pos] except ValueError: raise OperationalError('Unknown identifier %s', identifier_strip)
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(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 drop_table(etcd_client, tree, db=None): """ Drop table. :param etcd_client: Etcd client :type etcd_client: Client :param tree: Parsing tree :type tree: SQLTree :param db: Database name to use if not defined in the parsing tree. :type db: str :raise OperationalError: if database is not selected or if table doesn't exist. """ if not db: db = tree.db database_exists_or_raise(etcd_client, db) try: key = '/%s/%s' % (db, tree.table) etcd_client.rmdir(key, recursive=True) except EtcdKeyNotFound: if tree.options['if_exists']: pass else: raise OperationalError("Unknown table '%s'" % tree.table)
def _get_current_db(self, tree): db = self._db if tree.db: db = tree.db if not db: raise OperationalError('No database selected') return db
def drop_database(etcd_client, tree): """ Drop database. :param etcd_client: Etcd client :type etcd_client: Client :param tree: Parsing tree :type tree: SQLTree :raise OperationalError: if database doesn't exist """ try: etcd_client.rmdir('/%s' % tree.db, recursive=True) except EtcdKeyNotFound: raise OperationalError("Can't drop database '%s';" " database doesn't exist" % tree.db)
def use_database(etcd_client, tree): """ Return database name if it exists or raise exception. :param etcd_client: etcd client :type etcd_client: pyetcd.client.Client :param tree: Parsing tree. :type tree: SQLTree :return: Database name :raise OperationalError: if database doesn't exist. """ try: etcd_client.read('/%s' % tree.db) return tree.db except EtcdKeyNotFound: raise OperationalError("Unknown database '%s'" % tree.db)
def _get_meta_lock(self, db, tbl): """ Set a meta lock :param db: database name :param tbl: table name """ key = "/{db}/{tbl}/_lock_meta".format(db=db, tbl=tbl) expires = time.time() + LOCK_WAIT_TIMEOUT while time.time() < expires: try: response = self.connection.client.\ compare_and_swap(key, '', ttl=self._timeout, prev_exist=False) self._keep_key_alive(key, self._timeout) return response except EtcdNodeExist: pass raise OperationalError('Lock wait timeout')
def create_table(etcd_client, tree, db=None): """ Create table. :param etcd_client: Etcd client :type etcd_client: Client :param tree: Parsing tree :type tree: SQLTree :param db: Database name to use if not defined in the parsing tree. :type db: str :raise ProgrammingError: If primary key is not defined, or the primary key is NULL-able. :raise OperationalError: if database is not selected or table exists. """ database_exists_or_raise(etcd_client, db) pk_field = None for field_name, value in tree.fields.iteritems(): try: if value['options']['primary']: pk_field = field_name except KeyError: pass if not pk_field: raise ProgrammingError('Primary key must be defined') if tree.fields[pk_field]['options']['nullable']: raise ProgrammingError('Primary key must be NOT NULL') try: full_table_name = '/%s/%s' % (db, tree.table) etcd_client.mkdir(full_table_name) etcd_client.write(full_table_name + "/_fields", json.dumps(tree.fields)) except EtcdNodeExist: raise OperationalError("Table '%s' already exists" % tree.table)