SQLite
 sql >> Base de données >  >> RDS >> SQLite

Mettre à jour une base de données préremplie

Selon le commentaire de Gabe Sechan, la méthode la plus simple serait de copier la base de données du dossier assets à chaque démarrage de l'application, c'est-à-dire de changer :-

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

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

    }
    dbSglite=getReadableDatabase();
}

à :-

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

Vous avez apparemment des inquiétudes en commentant

"Cela ne copierait-il pas la base de données à chaque démarrage de l'activité."

oui ce serait (est-ce que ce serait si mauvais ? - rhétorique ).

Cependant, supposons que vous deviez utiliser la version de la base de données, c'est-à-dire vérifier la version dans le dossier des actifs par rapport à la version actuelle. Vous devez toujours accéder à la base de données à partir du dossier des actifs, vous vérifierez donc une base de données par rapport à une autre (au moins en les ouvrant). Il y aurait donc encore des frais généraux.

Une option qui peut être moins intensive serait de vérifier la dernière modification du fichier d'actif date par rapport à la date du dernier fichier d'actif copié dans les préférences partagées. (File lastModified méthode) Fichier - lastModified.

Une autre option, dans une vue similaire, serait de vérifier la version du package par rapport au dernier implémenté, à nouveau stocké dans les préférences partagées.PackageInfo - versionCode.

Bien sûr, dans ces deux options, le remplacement de la base de données à partir du fichier d'actifs ne se produit que lorsqu'il y a une différence (augmentation).

Exemple utilisant la version du package

L'exemple suivant (toutes les modifications dans le dbHelper class) copiera la base de données à partir des actifs si la version du package est augmentée (ou si la base de données n'existe pas) :-

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

Remarques

  • Le code est très basé sur le code de la question. Il y a :-
    • Deux variables de classe supplémentaires (constantes) pour la gestion des préférences partagées.
    • Trois nouvelles méthodes :-
    • isQuestionsDBNew qui renvoie true si la version du package est supérieure à la version du magasin dans les préférences partagées (rien dans les préférences partagées ne donne -1, donc doit être inférieur à n'importe quelle version du package).
    • getPackageVersion renvoie la version du package sous la forme d'un long.
    • setQuestionsDBNew qui met à jour la préférence partagée applicable.
    • Modifications apportées à createDB pour vérifier le changement de version du package, puis copier la base de données à partir des actifs. Il y a une vérification supplémentaire pour voir si la base de données existe, bien que cela ne soit nécessaire que si seul le fichier de base de données a été supprimé. La suppression des données de l'application supprimerait les préférences partagées, ce qui entraînerait la copie de la base de données.
  • Le code inclut une journalisation de diagnostic que j'ai laissée.
  • Cela n'a pas été testé de manière approfondie (c'est-à-dire que je ne suis pas allé jusqu'à augmenter la version du package).

Résultat de l'exemple - Application en cours d'installation :-

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

Sortie de l'exemple - Exécution suivante :-

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
  • Messages supplémentaires en raison du message plus long utilisé lors du signalement que la base de données n'a pas été copiée en appelant à nouveau des méthodes qui ajoutent des messages de journal.