Flutter如何备份和还原sqflite数据库?

时间:2019-04-29 11:50:15

标签: flutter sqflite

我正在将sqflite用于我的flutter项目,现在,我想备份然后还原它。我搜索了此问题,但找不到结果。有什么办法吗? 谢谢。

2 个答案:

答案 0 :(得分:0)

您可以使用本指南进行还原。 https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md

这样,您可以从.db的某个位置下载文件并更改手机版本。

要备份,您可以在上面的示例中更改一些行。

答案 1 :(得分:0)

依赖项

dependencies:
  encrypt: ^4.1.0
  path: ^1.6.4
  sqflite: ^1.3.1

班级

import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:convert' as convert;
import 'package:encrypt/encrypt.dart' as encrypt ;

class DatabaseRepository {
 
  Database _db;

  static const SECRET_KEY = "2020_PRIVATES_KEYS_ENCRYPTS_2020";
  static const DATABASE_VERSION = 1;

  List<String> tables =[
     
  ];

  Future<Database> get db async 
  {
    if(_db != null)
    {
      return _db;
    } 
    else
    {
      _db = await initDb();
      return _db;
    }
  }

  Future<String> _databasePath() async 
  {
    String databasesPath = await getDatabasesPath();
    return join(databasesPath, "database.db");
  }
  
  Future<Database> initDb() async 
  {
    String path = await _databasePath();
    return await openDatabase(path, version:DATABASE_VERSION, onCreate: onCreate,onUpgrade: onUpgrade);
  }

  Future deleteDB() async 
  {
    String path = await _databasePath();
    await deleteDatabase(path);
  }

  FutureOr onCreate(Database db, int newerVersion) => this._creates[newerVersion](db);

  Map<int,Function> _creates = {
    1:(Database db) async {

     
      print("DATABASE CREATE v1");
    },
    2:(Database db) async{

   
      print("DATABASE CREATE v2");
    },
  };

  FutureOr<void> onUpgrade(Database db , int oldVersion, int newVersion ) async 
  {
    for (var migration = oldVersion; migration < newVersion; migration++) 
    {
      this._onUpgrades["from_version_${migration}_to_version_${migration+1}"](db);
    }
  }

  Map<String,Function> _onUpgrades = {
    'from_version_1_to_version_2':(Database db) async {
      
    },
  };

  Future clearAllTables() async 
  {
    try
    {
      var dbs = await this.db;
      for (String table  in tables )
      {
        await dbs.delete(table);
        print('------ DELETE $table');
      }
    }
    catch(e){}
  }

  Future<String>generateBackup({bool isEncrypted = true}) async {

    print('GENERATE BACKUP');
   
    var dbs = await this.db;

    List data =[];

    List<Map<String,dynamic>> listMaps=[];

    for (var i = 0; i < tables.length; i++)
    {

      listMaps = await dbs.query(tables[i]); 

      data.add(listMaps);

    }

    List backups=[tables,data];

    String json =convert.jsonEncode(backups);

    if(isEncrypted)
    {

      final key = encrypt.Key.fromUtf8(SECRET_KEY);
      final iv = encrypt.IV.fromLength(16);
      final encrypter = encrypt.Encrypter(encrypt.AES(key));
      final encrypted = encrypter.encrypt(json, iv: iv);
        
      return encrypted.base64;  
    }
    else
    {
      return json;
    }
  }

  Future<void>restoreBackup(String backup,{ bool isEncrypted = true})async{

    var dbs = await this.db;
    
    Batch batch = dbs.batch();
    
    final key = encrypt.Key.fromUtf8(SECRET_KEY);

    final iv = encrypt.IV.fromLength(16);

    final encrypter = encrypt.Encrypter(encrypt.AES(key));

    List json = convert.jsonDecode(isEncrypted ? encrypter.decrypt64(backup,iv:iv):backup);

    for (var i = 0; i < json[0].length; i++)
    {
      for (var k = 0; k < json[1][i].length; k++)
      {
        batch.insert(json[0][i],json[1][i][k]);
      }
    }

    await batch.commit(continueOnError:false,noResult:true);

    print('RESTORE BACKUP');
  }
}
       

使用:

    final DatabaseRepository databaseRepository = new DatabaseRepository();

    String backup =  await databaseRepository.generateBackup(isEncrypted: true);

    await databaseRepository.clearAllTables();

    await databaseRepository.restoreBackup(backup,isEncrypted: true);