Android - Sqlite - Detect if new version not found

不问归期 提交于 2019-12-25 09:41:27

问题


Updated: Bref: The answer of Kuffs is simple and correct. The answer of MikeT is a interesting approach.

Old version: I'm working on an android app. I need to know if there are a new sql version or not. If my db is up to date, I will trigger an async action. But how can I trigger my async action?

Currently, I have my own flag onNewVersion who is set to true in onUpgrade(). Then I do the check in onOpen(). Are there any other methods?

@override
onUpgrade(...) {
    onNewVersion = true;
    ...
}

@override
onOpen(...) {
    if (onNewVersion == FALSE)
        triggerAction();
}

Thanks.


回答1:


Are there any other methods?

Yes, I personally use a sort of pseudo/wanted/desired schema and in short compare this against what actually exists columns, tables, indexes being created(tables indexes)/added(columns) as required.

As such I don't use versions and onUpgrade is empty.

for example these are the core methods in my SQLiteOpenhelper subclass :-

    @Override
    public void onCreate(SQLiteDatabase db) {
        usable = this.onExpand(db,false);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
    }

    public boolean onExpand(SQLiteDatabase db, boolean buildandexpand) {
        boolean rv = true;
        if (db == null) {
            db = instance.getWritableDatabase();
        }
        // Is the Database definition valid to use?
        if (DBConstants.cardonsier.isDBDatabaseUsable()) {
            ArrayList<String> buildsql = DBConstants.cardonsier.generateDBBuildSQL(db);
            // Anything to build
            if (!buildsql.isEmpty()) {
                // YES so build the Database
                DBConstants.cardonsier.actionDBBuildSQL(db);
            }
            if (buildandexpand) {
                ArrayList<String> altersql = DBConstants.cardonsier.generateDBAlterSQL(db);
                if (!altersql.isEmpty()) {
                    DBConstants.cardonsier.actionDBAlterSQL(db);
                }
            }
        }
        else {
            rv = false;
        }
        return rv;
    }

DBConstants.cardoniser refers to the DBDatabase object defined as :-

    static final DBDatabase cardonsier = new DBDatabase(DATABASENAME,
            new ArrayList<>(Arrays.asList(
                    DBCardsTableConstants.CARDS,
                    DBUsertableConstants.USERS,
                    DBCardUserLinkTableConstants.CARDUSERLINKS,
                    DBPreftableConstants.PREFS,
                    DBPayeestableContants.PAYEES,
                    DBCategoriestableConstants.CATEGORIES,
                    DBCardCategoryLinkTableConstants.CARDCATEGORYLINKS,
                    DBCardPayeeLinkTableConstants.CARDPAYEELINKS,
                    DBTransactionsTableConstants.TRANSACTIONS,
                    DBCardTypesTableConstants.CARDTYPES
            ))
    );

i.e. the list of DBTable objects, they including DBColumn objects e.g :-

static final DBTable CARDS = new DBTable(CARDS_TABLE,
        new ArrayList<>(Arrays.asList(
                CARDID,
                CARDOWNER,
                CARDNAME,
                CARDTYPEREF,
                CARDNUMBER,
                CARDCVVCODE,
                CARDPIN,
                CARDNOTES,
                CARDEXPIRYDATE,
                CARDNAMEONCARD
        ))
);

Columns being defined like :-

static final DBColumn CARDID = new DBColumn(true);
static final DBColumn CARDOWNER = new DBColumn(
        CARDOWNER_COL,
        SQLINTEGER,
        false,
        "0"
);
static final DBColumn CARDNAME = new DBColumn(
        CARDNAME_COL,
        SQLTEXT,
        false,
        ""
);
static final DBColumn CARDTYPEREF = new DBColumn(
        CARDTYPEREF_COL,
        SQLINTEGER,
        false,
        "0"
);

Note! the first column CARDID, uses a shortcut constructor for standard _id columns.

To add a new column it's simply a matter of defining the DBColumn and including the DBColumn in the DBTable definition. The onExpand method will add the column via, in the case of a new column, the DBDatabase's actionDBAlterSQL method. New tables require the above plus the inclusion of the table in the DBDatabase definition and are applied by onExpand via the actionDBBuildSQL method.

onExpand is also called when the App(s) is started. However, with true being passed so that the actionDBAlterSQL method is called.

As an example adding :-

private static final String CARDCOLOUR_COL = "cardcolour";
..........
static final DBColumn CARDCOLOUR = new DBColumn(
        CARDCOLOUR_COL,
        SQLINTEGER,
        false,
        Long.toString(0x00_00_00_00_00L)
        // Flag, alpha, red, green, blue
        // Flag used to inidcate if colour has been set
);

and then adding CARDCOLOUR to the DBTable definition as per :-

static final DBTable CARDS = new DBTable(CARDS_TABLE,
        new ArrayList<>(Arrays.asList(
                CARDID,
                CARDOWNER,
                CARDNAME,
                CARDTYPEREF,
                CARDNUMBER,
                CARDCVVCODE,
                CARDPIN,
                CARDNOTES,
                CARDEXPIRYDATE,
                CARDNAMEONCARD,
                CARDCOLOUR     //<<<<<<<<<<
        ))
);

Results in (note logging exists when developing) :-

09-22 08:30:26.802 2713-2713/? D/DBEXPAND: Expanding Database Schema Usability=true
09-22 08:30:26.803 2713-2713/? D/DBEXPAND: Build SQL is as follows:-
09-22 08:30:26.803 2713-2713/? D/DBEXPAND: ALTERSQL is as folows:-
09-22 08:30:26.807 2713-2713/? D/DBEXPAND: ALterSQL Line=    ALTER TABLE cards ADD COLUMN cardcolour INTEGER  DEFAULT 0  ;

The resultant already populated table then looks like :-

Using ALTER TABLE with a DEFAULT value (4th parameter of DBColumn (1st is column name, 2nd Type, 3rd true to include in primary index)) populates the new column for existing rows.




回答2:


You can set a flag inside your onUpgrade method of your SQLiteOpenHelper.

If the flag is not set by the time you get your reference to the OpenHelper then the database was already current and did not need updating.




回答3:


Check onUpgrade

Called when the database needs to be upgraded. The implementation should use this method to drop tables, add tables, or do anything else it needs to upgrade to the new schema version.

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion < 5) {
         db.execSQL("ALTER_TABLE_STATEMENT");
    }
    if (oldVersion < 6) {
         db.execSQL("ALTER_TABLE_STATEMENT2");
    }
}


来源:https://stackoverflow.com/questions/46339534/android-sqlite-detect-if-new-version-not-found

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!