'Cleanup after migration
@param moves     : List of dicts {tablename: [(fieldname, new_tablename, link_fieldname)]} to move a field from 1 table to another
- fieldname can be a tuple if the fieldname changes: (fieldname, new_fieldname)
@param news      : List of dicts {new_tablename: {\'lookup_field\': \'\',
\'tables\': [tablename: [fieldname]],
\'supers\': [tablename: [fieldname]],
} to create new records from 1 or more old tables (inc all instances of an SE)
- fieldname can be a tuple if the fieldname changes: (fieldname, new_fieldname)
@param strbools : List of tuples [(tablename, fieldname)] to convert from string/integer to bools
@param strints  : List of tuples [(tablename, fieldname)] to convert from string to integer'

def post(self, moves=None, news=None, strbools=None, strints=None):

    db = self.db
    folder = ('%s/databases/backup' % current.request.folder)
    db_bak = DAL('sqlite://backup.db', folder=folder, auto_import=True, migrate=False)
    if moves:
        for tablename in moves:
            table = db_bak[tablename]
            (fieldname, new_tablename, link_fieldname) = moves[tablename]
            if isinstance(fieldname, (tuple, list)):
                (fieldname, new_fieldname) = fieldname
            else:
                new_fieldname = fieldname
            old_field = table[fieldname]
            new_linkfield = db[new_tablename][link_fieldname]
            rows = db_bak((table._id > 0)).select(old_field, link_fieldname)
            for row in rows:
                update_vars = {}
                update_vars[new_fieldname] = row[old_field]
                db((new_linkfield == row[link_fieldname])).update(**update_vars)
    if news:
        for tablename in news:
            data = {}
            new = news[tablename]
            lookup_field = new['lookup_field']
            _tables = new['tables']
            for t in _tables:
                fields = _tables[t]
                table = db_bak[t]
                table_fields = [table[f] for f in fields]
                rows = db_bak((table.deleted == False)).select(table[lookup_field], *table_fields)
                for row in rows:
                    record_id = row[lookup_field]
                    if (record_id in data):
                        _new = False
                        _data = data[record_id]
                    else:
                        _new = True
                        _data = {}
                    for f in fields:
                        if (f in row):
                            if (row[f] not in ('', None)):
                                _data[f] = row[f]
                    if _new:
                        data[record_id] = _data
            for s in new['supers']:
                fields = new['supers'][s]
                stable = db_bak[s]
                superkey = stable._id.name
                rows = db_bak((stable.deleted == False)).select(stable._id, stable.instance_type)
                for row in rows:
                    etable = db_bak[row['instance_type']]
                    _fields = [f for f in fields if (f in etable.fields)]
                    table_fields = [etable[f] for f in _fields]
                    record = db_bak((etable[superkey] == row[superkey])).select(etable[lookup_field], *table_fields).first()
                    if record:
                        record_id = record[lookup_field]
                        if (record_id in data):
                            _new = False
                            _data = data[record_id]
                        else:
                            _new = True
                            _data = {}
                        for f in _fields:
                            if (f in record):
                                if (record[f] not in ('', None)):
                                    _data[f] = record[f]
                        if _new:
                            data[record_id] = _data
            table = db[tablename]
            for record_id in data:
                update_vars = data[record_id]
                if update_vars:
                    update_vars[lookup_field] = record_id
                    update_vars['created_on'] = datetime.datetime.utcnow()
                    update_vars['deleted'] = False
                    update_vars['mci'] = 0
                    update_vars['modified_on'] = datetime.datetime.utcnow()
                    update_vars['uuid'] = uuid4().urn
                    table.insert(**update_vars)
    if strints:
        for (tablename, fieldname) in strints:
            newtable = db[tablename]
            newrows = db((newtable.id > 0)).select(newtable.id)
            oldtable = db_bak[tablename]
            oldrows = db_bak((oldtable.id > 0)).select(oldtable.id, oldtable[fieldname])
            oldvals = oldrows.as_dict()
            for row in newrows:
                _id = row.id
                val = oldvals[_id][fieldname]
                if (not val):
                    continue
                try:
                    update_vars = {fieldname: int(val)}
                except:
                    current.log.warning(('S3Migrate:    Unable    to    convert    %s    to    an    integer    -    skipping' % val))
                else:
                    db((newtable.id == _id)).update(**update_vars)
    if strbools:
        for (tablename, fieldname) in strbools:
            to_bool = self.to_bool
            newtable = db[tablename]
            newrows = db((newtable.id > 0)).select(newtable.id)
            oldtable = db_bak[tablename]
            oldrows = db_bak((oldtable.id > 0)).select(oldtable.id, oldtable[fieldname])
            oldvals = oldrows.as_dict()
            for row in newrows:
                _id = row.id
                val = oldvals[_id][fieldname]
                if (not val):
                    continue
                val = to_bool(val)
                if val:
                    update_vars = {fieldname: val}
                    db((newtable.id == _id)).update(**update_vars)
    db.commit()
