'Extract the data from rows and store them in self.field_data
@param rows: the rows
@param pkey: the primary key
@param columns: the columns to extract
@param join: the rows are the result of a join query
@param records: the records dict to merge the data into
@param represent: collect unique values per field and estimate
representation efforts for list:types'

def extract(self, rows, pkey, columns, join=True, records=None, represent=False):

    field_data = self.field_data
    effort = self.effort
    if (records is None):
        records = {}
    def get(key):
        (t, f) = key.split('.', 1)
        if join:
            return (lambda row, t=t, f=f: ogetattr(ogetattr(row, t), f))
        else:
            return (lambda row, f=f: ogetattr(row, f))
    getkey = get(pkey)
    getval = [get(c) for c in columns]
    from itertools import groupby
    for (k, g) in groupby(rows, key=getkey):
        group = list(g)
        record = records.get(k, {})
        for (idx, col) in enumerate(columns):
            (fvalues, frecords, joined, list_type, virtual, json_type) = field_data[col]
            values = record.get(col, {})
            lazy = False
            for row in group:
                try:
                    value = getval[idx](row)
                except AttributeError:
                    current.log.warning(('Warning    S3Resource.extract:    column    %s    not    in    row' % col))
                    value = None
                if (lazy or callable(value)):
                    value = value()
                    lazy = True
                if (virtual and (not list_type) and (type(value) is list)):
                    list_type = True
                if (list_type and (value is not None)):
                    if (represent and value):
                        effort[col] += (30 + len(value))
                    for v in value:
                        if (v not in values):
                            values[v] = None
                        if (represent and (v not in fvalues)):
                            fvalues[v] = None
                elif json_type:
                    value = json.dumps(value)
                    if (value not in values):
                        values[value] = None
                    if (represent and (value not in fvalues)):
                        fvalues[value] = None
                else:
                    if (value not in values):
                        values[value] = None
                    if (represent and (value not in fvalues)):
                        fvalues[value] = None
            record[col] = values
            if (k not in frecords):
                frecords[k] = record[col]
        records[k] = record
    return records
