Обновите базу данных, используя правильный обратный вызов onUpgrade - PullRequest
0 голосов
/ 09 июня 2019

Я получаю данные с веб-сайта (JSON) и сохраняю их в базе данных. Это хорошо работает. Однако я хочу обновлять базу данных с новым номером версии каждый раз, когда изменяются данные, полученные из Интернета. Для этого, я думаю, лучший способ - удалить таблицу, обновить версию номера базы данных и воссоздать таблицу перед заполнением ее новыми данными (по крайней мере, есть способ вставить только новые записи и обновить только старые, имеющие измененная).

Я видел, что это можно сделать с помощью обратного вызова onUpgrade для базы данных из плагина sqflite .

Итак, я создал Helper с методом init(), который открывает базу данных. Однако я не понимаю, когда вызывается обратный вызов onUpgrade. Действительно, в этом коде ниже, version всегда равен 1.

Я хотел бы иметь метод инициализации БД и:

  • создает его, если он не существует ИЛИ
  • открыть текущую версию, если номерная версия не указана (что-то подобное) ИЛИ
  • обновление до новой версии путем автоматического увеличения номера версии (например, путем вызова database.upgrade ()).

Как вы думаете, это возможно уникальным методом или мне нужно разделить это на два метода? Если да, какой смысл в обратном вызове onUpgrade?

class DBHelper {
  // Private constructor
  DBHelper._privateConstructor();

  // Get an instance of DBHelper
  static final DBHelper _dbHelper = DBHelper._privateConstructor();

  // Getter to get the instance of the DBHelper
  factory DBHelper() => _dbHelper;

  static Database _database;

  Future<Database> get database async {
    if (_database != null) return _database;
    // lazily instantiate the db the first time it is accessed
    _database = await init();
    return _database;
  }

  Future<Database> init() async {
    print("DBHelper: init database");
    // Get a location using path_provider
    String path = await getDBPath();
    // I THINK ALL HAPPENS HERE
    return await openDatabase(path, version: 1, onCreate: _onCreate, onUpgrade: _onUpgrade);
  }

  void _onCreate(Database db, int version) async {
    print("DBHelper: _onCreate called");
    // When creating the db, create the table
    _createTable();
  }

  void _onUpgrade(Database db, int oldVersion, int newVersion) async{
    print("DBHelper: _onUpgrade called");
    try {
      await db.transaction((Transaction txn) async {
        await txn.execute("DROP TABLE TABLE_NAME");
      });
    } catch (e) {
      print("Error : " + e.toString());
    }
    _createTable();
  }

  void _createTable() async {
    Database db = await database;
    try {
      await db.transaction((Transaction txn) async {
        await txn.execute("CREATE TABLE TABLE_NAME ("
            "TABLE_ID INTEGER PRIMARY KEY AUTOINCREMENT,"
            "TABLE_INT INTEGER,"
            "TABLE_TEXT TEXT,");");
      });
    } catch (e) {
      print("Error : " + e.toString());
    }
  }
}

Лучший

1 Ответ

0 голосов
/ 12 июня 2019

Управление версиями базы данных в sqflite соответствует тому, что было сделано в Android, где версия является константой для конкретной версии вашего приложения с определенной схемой. onCreate/onUpgrade обычно вызывается только один раз в жизненном цикле вашего приложения. В любом случае он не будет вызван, если вы не закроете и не откроете базу данных заново. Смотри https://github.com/tekartik/sqflite/blob/master/sqflite/doc/migration_example.md.

Так что я бы сказал, что существующая версия пользователя не соответствует вашим потребностям. Поэтому я бы не использовал ни это значение, ни onUpgrade в вашем сценарии. Однако вы можете определить свое собственное одноэлементное значение (то есть свою собственную систему управления версиями) и удалить / создать таблицу в транзакции, пока база данных открыта. Ничто не мешает вам сделать это.

...