示例#1
0
    def run_idl(self, txn):
        table_schema = self.api._tables[self.table]
        idx = idlutils.get_index_column(table_schema)
        columns = self.columns or list(table_schema.columns.keys()) + ['_uuid']
        # If there's an index for this table, we'll fetch all columns and
        # remove the unwanted ones based on self.records. Otherwise, let's try
        # to get the uuid of the wanted ones which is an O(n^2) operation.
        if not idx and self.records:
            rows = []
            for record in self.records:
                try:
                    rows.append(self.api.idl.lookup(self.table, record))
                except idlutils.RowNotFound:
                    if self.if_exists:
                        continue
                    raise
        else:
            rows = table_schema.rows.values()

        def _match(row):
            elem = getattr(row, idx)
            return elem in self.records

        def _match_remove(row):
            elem = getattr(row, idx)
            found = elem in self.records
            if found:
                records_found.remove(elem)
            return found

        def _match_true(row):
            return True

        records_found = []
        if idx and self.records:
            if self.if_exists:
                match = _match
            else:
                # If we're using the approach of removing the unwanted
                # elements, we'll use a helper list to remove elements as we
                # find them in the DB contents. This will help us identify
                # quickly if there's some record missing to raise a RowNotFound
                # exception later.
                records_found = list(self.records)
                match = _match_remove
        else:
            match = _match_true

        self.result = [
            rowview.RowView(row) if self.row else {
                c: idlutils.get_column_value(row, c)
                for c in columns
            }
            for row in rows if match(row)
        ]

        if records_found:
            raise idlutils.RowNotFound(table=self.table, col=idx,
                                       match=records_found[0])
示例#2
0
    def _lookup(self, table, record):
        if record == "":
            raise TypeError("Cannot look up record by empty string")

        # Handle commands by simply returning its result
        if isinstance(record, cmd.BaseCommand):
            return record.result

        t = self.tables[table]
        if isinstance(record, uuid.UUID):
            try:
                return t.rows[record]
            except KeyError:
                raise idlutils.RowNotFound(table=table,
                                           col='uuid',
                                           match=record) from None
        try:
            uuid_ = uuid.UUID(record)
            return t.rows[uuid_]
        except ValueError:
            # Not a UUID string, continue lookup by other means
            pass
        except KeyError:
            # If record isn't found by UUID , go ahead and look up by the table
            pass

        if not self.lookup_table:
            raise idlutils.RowNotFound(table=table, col='record', match=record)
        # NOTE (twilson) This is an approximation of the db-ctl implementation
        # that allows a partial table, assuming that if a table has a single
        # index, that we should be able to do a lookup by it.
        rl = self.lookup_table.get(
            table, idlutils.RowLookup(table, idlutils.get_index_column(t),
                                      None))
        # no table means uuid only, no column means lookup table has one row
        if rl.table is None:
            raise idlutils.RowNotFound(table=table, col='uuid', match=record)
        if rl.column is None:
            if t.max_rows == 1:
                return next(iter(t.rows.values()))
            raise idlutils.RowNotFound(table=table, col='uuid', match=record)
        row = idlutils.row_by_value(self, rl.table, rl.column, record)
        if rl.uuid_column:
            rows = getattr(row, rl.uuid_column)
            if len(rows) != 1:
                raise idlutils.RowNotFound(table=table,
                                           col='record',
                                           match=record)
            row = rows[0]
        return row
示例#3
0
    def autocreate_indices(self):
        """Create simple one-column indexes

        This creates indexes for all lookup_table entries and for all defined
        indexes columns in the OVSDB schema, as long as they are simple
        one-column indexes (e.g. 'name') fields.
        """

        tables = set(self.idl.tables.keys())
        # lookup table indices
        for table, (lt, col, uuid_col) in self.lookup_table.items():
            if table != lt or not col or uuid_col or table not in tables:
                # Just handle simple cases where we are looking up a single
                # column on a single table
                continue
            index_name = idlutils.index_name(col)
            try:
                idx = self.idl.tables[table].rows.index_create(index_name)
            except ValueError:
                LOG.debug("lookup_table index %s.%s already exists", table,
                          index_name)
            else:
                idx.add_column(col)
                LOG.debug("Created lookup_table index %s.%s", table,
                          index_name)
            tables.remove(table)

        # Simple ovsdb-schema indices
        for table in self.idl.tables.values():
            if table.name not in tables:
                continue
            col = idlutils.get_index_column(table)
            if not col:
                continue
            index_name = idlutils.index_name(col)
            try:
                idx = table.rows.index_create(index_name)
            except ValueError:
                LOG.debug("schema index %s.%s already exists", table,
                          index_name)
            else:
                idx.add_column(col)
                LOG.debug("Created schema index %s.%s", table.name, index_name)
            tables.remove(table.name)