SQLite
 sql >> Baza danych >  >> RDS >> SQLite

Aktualizacja wstępnie wypełnionej bazy danych

Zgodnie z komentarzem Gabe Sechan, najprostszą metodą byłoby skopiowanie bazy danych z folderu zasobów przy każdym uruchomieniu aplikacji, czyli zmiana :-

private void createDB(){
    boolean dbExist = DBExists();

    if(!dbExist){
        this.getReadableDatabase();
        copyDBFromResource();

    }
    dbSglite=getReadableDatabase();
}

do :-

private void createDB(){
    copyDBFromResource();
    dbSglite=getReadableDatabase();
}

Najwyraźniej masz wątpliwości, komentując

„Czy nie byłoby to kopiowanie bazy danych za każdym razem, gdy rozpoczyna się aktywność?”

tak, to by (czy to byłoby aż tak złe? - retoryczne ).

Załóżmy jednak, że miałeś użyć wersji bazy danych, tj. Porównać wersję w folderze zasobów z bieżącą wersją. Zasadniczo nadal potrzebujesz dostępu do bazy danych z folderu zasobów, więc porównujesz jedną bazę danych z drugą (przynajmniej otwierając je). Więc nadal będzie trochę kosztów ogólnych.

Opcją, która może być mniej intensywna, jest sprawdzenie ostatniej modyfikacji pliku zasobu data z datą ostatniego skopiowanego pliku zasobu we wspólnych preferencjach. (File lastModified metoda) Plik - lastModified.

Inną opcją, z podobnego punktu widzenia, byłoby sprawdzenie wersji pakietu w stosunku do ostatnio zaimplementowanej, ponownie przechowywanej we wspólnych preferencjach.PackageInfo - versionCode.

Oczywiście w obu tych opcjach zastąpienie bazy danych z pliku zasobów ma miejsce tylko wtedy, gdy jest różnica (wzrost).

Przykład użycia wersji pakietu

Poniższy przykład (wszystkie zmiany w dbHelper class) skopiuje bazę danych z zasobów, jeśli wersja pakietu zostanie zwiększona (lub jeśli baza danych nie istnieje) :-

class dbHelper extends SQLiteOpenHelper {


    private static final String DATABASE_NAME = "questions.db";
    private  static final int SCHEMA_VERSION = 1;
    private static  final String SHARED_PREFS = "shared_prefs";
    private static final String SHARED_PREFKEY_QUESTIONSDBLASTUPDATED = "spkey_qdblastupdated";

    public SQLiteDatabase dbSglite;
    private String mDBPath;

    private final Context myContext;

    public dbHelper(Context context) {
        super(context, DATABASE_NAME, null, SCHEMA_VERSION);
        this.myContext=context;
        this.mDBPath=context.getDatabasePath(DATABASE_NAME).getParent();
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        Log.d("ONCREATE","OnCreate Method Called.");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public void createDatabase(){
        createDB();
    }

    private void createDB(){

        if (isQuestionsDBNew() || (!DBExists())) {
            Log.d("COPYFROMASSET", "Copying Questions From Assets");
            copyDBFromResource();
            setQuestionsDBNew(getPackageVersion());
        } else {
            Log.d("COPYFROMASSET",
                    "Questions not copied from Assets - New Questions Check result was " +
                            Boolean.toString(isQuestionsDBNew()) +
                            " DB Exists result was " + Boolean.toString(DBExists())
            );
        }
        dbSglite=getReadableDatabase();
    }

    private boolean DBExists(){

        SQLiteDatabase db = null;

        try {
            String databasePath = myContext.getDatabasePath(DATABASE_NAME).getPath();
            db = SQLiteDatabase.openDatabase(databasePath,null, SQLiteDatabase.OPEN_READWRITE);
            db.setLocale(Locale.getDefault());
            db.setLockingEnabled(true);
            db.setVersion(1);
        } catch (SQLiteException e) {

            Log.e("SqlHelper", "database not found");
        }

        if (db != null) {
            db.close();
        }
        return db != null;

    }

    private void copyDBFromResource() {
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            inputStream = myContext.getAssets().open(DATABASE_NAME);
            File databasedir = new File(myContext.getDatabasePath(DATABASE_NAME).getParent());
            databasedir.mkdirs();
            outputStream = new FileOutputStream(mDBPath+"/"+DATABASE_NAME);
            byte[] buffer = new byte[1024];
            int length;
            while ((length=inputStream.read(buffer))>0){
                outputStream.write(buffer, 0, length);
            }

            outputStream.flush();
            outputStream.close();
            inputStream.close();

        } catch (IOException e) {
            e.printStackTrace();
            throw new Error("Problem copying database.");
        }

    }

    public void openDataBase() throws SQLException {
        String myPath = myContext.getDatabasePath(DATABASE_NAME).getPath();
        dbSglite = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);

    }

    private boolean isQuestionsDBNew() {
        SharedPreferences prefs = myContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE);
        long stored_lastused = prefs.getLong(SHARED_PREFKEY_QUESTIONSDBLASTUPDATED,-1);
        Log.d("NEWQUESTIONS?", "Result of testing package version " +
                String.valueOf(stored_lastused) +
                " against " +
                String.valueOf( getPackageVersion()) +
                " was " + String.valueOf(stored_lastused < getPackageVersion()));
        return  (stored_lastused < getPackageVersion());
    }

    private long getPackageVersion() {
        PackageInfo pi;
        try {
            pi = myContext.getPackageManager().getPackageInfo(myContext.getPackageName(),0);
        } catch (PackageManager.NameNotFoundException e) {
            return -1;
        }
        Log.d("PACKAGEVERSION", "The version of package " +
                myContext.getPackageName() +
                " was " +
                String.valueOf(pi.versionCode)
        );
        return pi.versionCode;
    }

    private void setQuestionsDBNew(long lastused) {
        SharedPreferences.Editor editor = myContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE).edit();
        editor.putLong(SHARED_PREFKEY_QUESTIONSDBLASTUPDATED,lastused);
        editor.apply();
    }
}

Notatki

  • Kod jest w dużej mierze oparty na kodzie z pytania. Są :-
    • Dwie dodatkowe zmienne klasy (stałe) do obsługi wspólnych preferencji.
    • Trzy nowe metody:-
    • isQuestionsDBNew to zwraca prawdę, jeśli wersja pakietu jest większa niż wersja przechowywana we wspólnych preferencjach (nic we wspólnych preferencjach nie daje -1, więc powinno być mniejsze niż jakakolwiek wersja pakietu).
    • getPackageVersion zwraca wersję pakietu jako długą.
    • setQuestionsDBNew który aktualizuje odpowiednie wspólne preferencje.
    • Zmiany w createDB w celu sprawdzenia zmiany wersji pakietu, a następnie skopiowania bazy danych z zasobów. Istnieje dodatkowe sprawdzenie, czy baza danych istnieje, chociaż byłoby to potrzebne tylko w przypadku usunięcia samego pliku bazy danych. Usunięcie danych aplikacji spowoduje usunięcie wspólnych preferencji, co spowoduje skopiowanie bazy danych.
  • Kod zawiera pewne rejestry diagnostyczne, które zostawiłem.
  • To nie zostało gruntownie przetestowane (tj. nie poszedłem w zakresie zwiększania wersji pakietu).

Wyjście z przykładu — instalowana aplikacja :-

01-05 19:46:44.849 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/NEWQUESTIONS?: Result of testing package version -1 against 1 was true
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/COPYFROMASSET: Copying Questions From Assets
01-05 19:46:44.855 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1

Wyjście z przykładu - Kolejne uruchomienie :-

01-05 19:48:10.375 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.376 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.376 26755-26755/m.com.so48103235_updateprepopdb D/NEWQUESTIONS?: Result of testing package version 1 against 1 was false
01-05 19:48:10.376 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.381 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.381 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.381 26755-26755/m.com.so48103235_updateprepopdb D/NEWQUESTIONS?: Result of testing package version 1 against 1 was false
01-05 19:48:10.382 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.387 26755-26755/m.com.so48103235_updateprepopdb D/COPYFROMASSET: Questions not copied from Assets - New Questions Check result was false DB Exists result was true
  • Dodatkowe komunikaty ze względu na bardziej obszerny komunikat używany podczas zgłaszania, że ​​baza danych nie została skopiowana, wywołując ponownie metody, które dodają komunikaty dziennika.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQLite - Utwórz relację

  2. SQLite IN

  3. Jak uzyskać aktualny czas w SQLite?

  4. Jak sprawdzić, czy tabela istnieje w SQLite?

  5. błąd pokoju:Kolumny zwrócone przez zapytanie nie mają pól nazwa pola