sql >> Databáze >  >> RDS >> SQLite

Aktualizace předvyplněné databáze

Podle komentáře od Gabe Sechan by nejjednodušší metodou bylo zkopírovat db ze složky aktiv při každém spuštění aplikace, to znamená změnit :-

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

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

    }
    dbSglite=getReadableDatabase();
}

do :-

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

Zjevně máte obavy z komentování

"Nebylo by to kopírovat DB při každém spuštění aktivity?"

Ano, (bylo by to tak špatné? - rétorické ).

Řekněme však, že byste měli použít verzi databáze, tj. zkontrolovat verzi ve složce aktiv oproti aktuální verzi. Stále v podstatě potřebujete přistupovat k databázi ze složky aktiv, takže byste porovnávali jednu databázi s druhou (alespoň je otevírali). Takže by tam ještě byly nějaké režie.

Možnost, která může být méně náročná, by byla kontrola poslední úpravy souboru aktiv datum oproti datu posledního zkopírovaného souboru aktiv ve sdílených předvolbách. (File lastModified metoda) Soubor - lastModified.

Další možností v podobném zobrazení by bylo zkontrolovat verzi balíčku oproti poslední implementované, opět uložené ve sdílených předvolbách.PackageInfo - versionCode.

Samozřejmě v obou těchto možnostech k výměně databáze ze souboru aktiv dochází pouze v případě rozdílu (zvýšení).

Příklad použití verze balíčku

Následující příklad (všechny změny v dbHelper class) zkopíruje databázi z aktiv, pokud se verze balíčku zvýší (nebo pokud databáze neexistuje) :-

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();
    }
}

Poznámky

  • Kód je do značné míry založen na kódu z otázky. Existují :-
    • Dvě další proměnné třídy (konstanty) pro zpracování sdílených předvoleb.
    • Tři nové metody :-
    • isQuestionsDBNew která vrátí hodnotu true, pokud je verze balíčku větší než verze uložená ve sdílených předvolbách (nic ve sdílených předvolbách nevede k hodnotě -1, takže by měla být menší než jakákoli verze balíčku).
    • getPackageVersion vrátí verzi balíčku jako dlouhou.
    • setQuestionsDBNew která aktualizuje příslušné sdílené preference.
    • Změny v createDB pro kontrolu změny verze balíčku a následné zkopírování databáze z prostředků. Existuje další kontrola, zda databáze existuje, i když by to bylo potřeba pouze v případě, že by byl odstraněn pouze soubor databáze. Smazáním dat aplikace dojde ke smazání sdílených předvoleb, takže databáze bude zkopírována.
  • Kód obsahuje některé diagnostické protokoly, které jsem ponechal.
  • Toto nebylo důkladně testováno (tj. nezašel jsem do té míry, abych zvýšil verzi balíčku).

Výstup z příkladu – Aplikace se instaluje :-

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

Výstup z příkladu – Následné spuštění :-

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
  • Zprávy navíc kvůli rozsáhlejší zprávě použité při hlášení, že databáze nebyla zkopírována, znovu volá metody, které přidávají zprávy protokolu.



  1. Jak spustit SQL skript v MySQL?

  2. SQL Server Collection Inventory Script -2

  3. Halloweenský problém – 3. část

  4. Výukový program připojení SQL