示例#1
0
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)
示例#2
0
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)
示例#3
0
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
示例#4
0
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
示例#5
0
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)
示例#6
0
    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
示例#7
0
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)
示例#8
0
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)
示例#9
0
    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')
示例#10
0
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)