'Backup the database to a local SQLite database
@ToDo: Option to use a temporary DB in Postgres/MySQL as this takes
too long for a large DB'

def backup(self):

    moves = self.moves
    news = self.news
    strints = self.strints
    strbools = self.strbools
    if ((not moves) and (not news) and (not strbools) and (not strints)):
        return
    import os
    db = self.db
    folder = ('%s/databases/backup' % current.request.folder)
    if os.path.exists(folder):
        shutil.rmtree(folder)
        import time
        time.sleep(1)
    os.mkdir(folder)
    db_bak = DAL('sqlite://backup.db', folder=folder, adapter_args={'foreign_keys': False})
    skip = []
    for tablename in db.tables:
        if (tablename == 'gis_location'):
            table = db[tablename]
            fields = [table[field] for field in table.fields if (field != 'the_geom')]
            try:
                db_bak.define_table(tablename, *fields)
            except KeyError:
                del db_bak[tablename]
                skip.append(tablename)
        else:
            try:
                db_bak.define_table(tablename, db[tablename])
            except KeyError:
                del db_bak[tablename]
                skip.append(tablename)
    while skip:
        _skip = []
        for tablename in skip:
            if (tablename == 'gis_location'):
                table = db[tablename]
                fields = [table[field] for field in table.fields if (field != 'the_geom')]
                try:
                    db_bak.define_table(tablename, *fields)
                except KeyError:
                    del db_bak[tablename]
                    _skip.append(tablename)
                except:
                    import sys
                    print ('Skipping    %s:    %s' % (tablename, sys.exc_info()[1]))
            else:
                try:
                    db_bak.define_table(tablename, db[tablename])
                except KeyError:
                    del db_bak[tablename]
                    _skip.append(tablename)
                except:
                    import sys
                    print ('Skipping    %s:    %s' % (tablename, sys.exc_info()[1]))
        skip = _skip
    tables = []
    if moves:
        for tablename in moves:
            tables.append(tablename)
    if news:
        for tablename in news:
            new = news[tablename]
            for t in new['tables']:
                tables.append(t)
            for s in new['supers']:
                tables.append(s)
                stable = db[s]
                rows = db((stable._id > 0)).select(stable.instance_type)
                instance_types = set([r.instance_type for r in rows])
                for t in instance_types:
                    tables.append(t)
    if strbools:
        for (tablename, fieldname) in strints:
            tables.append(tablename)
    if strints:
        for (tablename, fieldname) in strints:
            tables.append(tablename)
    tables = set(tables)
    import csv
    csv.field_size_limit(((2 ** 20) * 100))
    for tablename in tables:
        filename = ('%s/%s.csv' % (folder, tablename))
        file = open(filename, 'w')
        rows = db((db[tablename].id > 0)).select()
        rows.export_to_csv_file(file)
        file.close()
        file = open(filename, 'r')
        db_bak[tablename].import_from_csv_file(file, unique='uuid2')
        file.close()
        db_bak.commit()
    self.db_bak = db_bak
