'__Select() - Used to implement Select and Delete (above)
Returns a dictionary keyed on rowids containing dicts
holding the row data for columns listed in the columns param
that match the given conditions.
* conditions is a dictionary keyed on column names
containing callable conditions expecting the data string as an
argument and returning a boolean.'

def __Select(self, table, columns, conditions):

    if (table not in self.__tablecolumns):
        self.__load_column_info(table)
    if (columns is None):
        columns = self.tablecolumns[table]
    for column in (columns + conditions.keys()):
        if (not self.__tablecolumns[table].count(column)):
            raise TableDBError, ('unknown    column:    %r' % (column,))
    matching_rowids = {}
    rejected_rowids = {}
    def cmp_conditions(atuple, btuple):
        a = atuple[1]
        b = btuple[1]
        if (type(a) is type(b)):
            def cmp(a, b):
                if (a == b):
                    return 0
                if (a < b):
                    return (-1)
                return 1
            if (isinstance(a, PrefixCond) and isinstance(b, PrefixCond)):
                return cmp(len(b.prefix), len(a.prefix))
            if (isinstance(a, LikeCond) and isinstance(b, LikeCond)):
                return cmp(len(b.likestr), len(a.likestr))
            return 0
        if isinstance(a, ExactCond):
            return (-1)
        if isinstance(b, ExactCond):
            return 1
        if isinstance(a, PrefixCond):
            return (-1)
        if isinstance(b, PrefixCond):
            return 1
        return 0
    if (sys.version_info < (2, 6)):
        conditionlist = conditions.items()
        conditionlist.sort(cmp_conditions)
    else:
        conditionlist = []
        for i in conditions.items():
            for (j, k) in enumerate(conditionlist):
                r = cmp_conditions(k, i)
                if (r == 1):
                    conditionlist.insert(j, i)
                    break
            else:
                conditionlist.append(i)
    cur = self.db.cursor()
    column_num = (-1)
    for (column, condition) in conditionlist:
        column_num = (column_num + 1)
        searchkey = _search_col_data_key(table, column)
        if (column in columns):
            savethiscolumndata = 1
        else:
            savethiscolumndata = 0
        try:
            (key, data) = cur.set_range(searchkey)
            while (key[:len(searchkey)] == searchkey):
                rowid = key[(- _rowid_str_len):]
                if (rowid not in rejected_rowids):
                    if ((not condition) or condition(data)):
                        if (rowid not in matching_rowids):
                            matching_rowids[rowid] = {}
                        if savethiscolumndata:
                            matching_rowids[rowid][column] = data
                    else:
                        if (rowid in matching_rowids):
                            del matching_rowids[rowid]
                        rejected_rowids[rowid] = rowid
                (key, data) = cur.next()
        except db.DBError as dberror:
            if (dberror.args[0] != db.DB_NOTFOUND):
                raise
            continue
    cur.close()
    del rejected_rowids
    if (len(columns) > 0):
        for (rowid, rowdata) in matching_rowids.items():
            for column in columns:
                if (column in rowdata):
                    continue
                try:
                    rowdata[column] = self.db.get(_data_key(table, column, rowid))
                except db.DBError as dberror:
                    if (sys.version_info < (2, 6)):
                        if (dberror[0] != db.DB_NOTFOUND):
                            raise
                    elif (dberror.args[0] != db.DB_NOTFOUND):
                        raise
                    rowdata[column] = None
    return matching_rowids
