sql >> Database >  >> RDS >> SQLite

Een vooraf ingevulde database bijwerken

Volgens de opmerking van Gabe Sechan zou de eenvoudigste methode zijn om de db uit de map activa te kopiëren elke keer dat de app wordt gestart, dat wil zeggen om te veranderen:-

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

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

    }
    dbSglite=getReadableDatabase();
}

naar:-

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

Je hebt blijkbaar bedenkingen bij het reageren op

"Zou dat niet elke keer dat de activiteit wordt gestart DB kopiëren."

ja het zou (zou dat zo erg zijn? - retorisch ).

Stel echter dat u de databaseversie zou gebruiken, d.w.z. controleer de versie in de activamap met de huidige versie. U moet in principe nog steeds toegang hebben tot de database vanuit de activamap, dus u zou de ene database met de andere vergelijken (ten minste openen). Er zouden dus nog wat overheadkosten zijn.

Een optie die minder intensief kan zijn, is het controleren van de laatst gewijzigde . van het activabestand datum tegen de datum van het laatst gekopieerde activabestand in gedeelde voorkeuren. (File lastModified methode) Bestand - lastModified.

Een andere optie, in een vergelijkbare weergave, zou zijn om de versie van het pakket te controleren tegen de laatst geïmplementeerde, opnieuw opgeslagen in gedeelde voorkeuren.PackageInfo - versionCode.

Natuurlijk gebeurt bij beide opties het vervangen van de database uit het activabestand alleen als er een verschil is (toename).

Voorbeeld met pakketversie

Het volgende voorbeeld (alle wijzigingen binnen de dbHelper class) kopieert de database van de activa als de pakketversie wordt verhoogd (of als de database niet bestaat):-

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

Opmerkingen

  • De code is grotendeels gebaseerd op de code uit de vraag. Er zijn :-
    • Twee extra klassevariabelen (constanten) voor het afhandelen van gedeelde voorkeuren.
    • Drie nieuwe methoden:-
    • isQuestionsDBNew dat geeft true terug als de pakketversie groter is dan de versieopslag in gedeelde voorkeuren (niets in gedeelde voorkeuren resulteert in -1, dus zou kleiner moeten zijn dan elke pakketversie).
    • getPackageVersion retourneert de pakketversie als een long.
    • setQuestionsDBNew die de toepasselijke gedeelde voorkeur bijwerkt.
    • Wijzigingen in de createDB om te controleren op de pakketversiewijziging en om vervolgens de database uit de assets te kopiëren. Er is een extra controle om te zien of de database bestaat, hoewel dit alleen nodig zou zijn als alleen het databasebestand zou worden verwijderd. Als u de gegevens van de app verwijdert, worden de gedeelde voorkeuren verwijderd, zodat de database wordt gekopieerd.
  • De code bevat een aantal diagnostische logboeken die ik heb achtergelaten.
  • Dit is niet uitgebreid getest (d.w.z. ik ben niet zover gegaan om de pakketversie te vergroten).

Uitvoer van het voorbeeld - App wordt geïnstalleerd:-

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

Uitvoer van het voorbeeld - Volgende uitvoering:-

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
  • Extra berichten vanwege het uitgebreidere bericht dat wordt gebruikt bij het melden dat de database niet opnieuw is gekopieerd, aanroepmethoden die logberichten toevoegen.



  1. MySQL's ORDER BY FIELD() simuleren in Postgresql

  2. JSON_ARRAY() Functie in Oracle

  3. CAST() versus TRY_CAST() in SQL Server:wat is het verschil?

  4. Hoe kan ik een FULL OUTER JOIN doen in MySQL?