Google documentation for SQLiteOpenHelper.onUpgrade is very general. I'm wondering how onUpgrade execution exactly works?
Does Android stores database version number inside database itself (I tried to find it using database tool aSQLiteManager, btw very good piece of software, but it seems to be hidden if exist)? Or does Android just compares the old and new version of app in the moment of installation and basing on this it definieds old and new version as parameters of onUpgrade.
Let's take an example. I have app verson 1 which can work with multiple databases. At the beginning I have only database A version 1. Next I upgrade app to version 2 and database A is also upgraded to version 2 (onUpgrade is executed). Next I get database B from my friend created by the same app but in version 1 (thus B has also version 1). I copy it to the appropriate dir and run my app. Will onUpgrade method be executed then (for database B version 1, no app reinstallation)?
If you want, you may want to use SQLiteDabase (the first parameter of onUpgrade), with the method getPath to know which databse will be updated.
When you will ask SQLiteOpenHelper.getWritableDatabase (or getReadableDatabase()), it will be updated if the version you set in constructor is greater than the current version of the database.
If you need different upgrade statements for different databases (which is generally the case), you may want to declare two classes extending SQLiteOpenHelper.
Related
Technologies used for the app: Ionic, Capacitor, Angular and SQLite
The requirement is to use a prepopulated SQLite database in the app. The methods that I found over the internet across various blogs and forums mentioned running a SQL script to initialize the DB as a pre-population step, but this brings about an unwanted overhead time to start querying the DB. As in the user needs to wait for a minute or so for the SQL Script to run completely every time, even if the app exists.
This issue became a roadblock because when the need became to port a large-sized database, it was no longer feasible to write SQL scripts as the overhead time increased drastically. Also, a bigger problem is, in Android studio, Java started throwing Heap Memory exceeded error.
A solution that I tried was to port the database directly as an asset of the app so that it can be shipped along with the app. But, while placing the database file in src/assets/, every build of the app generates www/ to create a web app that can be wrapped in a native view. The builder and compiler delete all the contents of the previous build in the www/ folder, we must understand that the capacitor looks for the database file at www/ and not in www/assets/, but we can't place the database file at www/ as it gets deleted on every build.
Link to existing issue on using the sqlite extension
maybe my experience can help you
RULES FOR DEVELOPMENT
1
database1 of bundle ( Android APK) from /assets must be static and not for update. because they can be changed when the application will be reinstalled on you version
2
you must to create new database2 - local , on the device , programmatically - to store a user's data. you can affill this database2 with data from database1
3
when you will install new version of application: database1 one may be changed, but the database2 becomes constant
the same situation is in browser: programmatically created database not disappear from session to session.
I check - it works in my application...
This will be a long post but please do read until the end and help out. Thank you!
In continuation of my previous post, [Android Studio - Database file loaded in the wrong encoding: 'UTF-8' my app was working fine when I run it both on my phone & an emulator despite the encoding error.
However, I am facing new issues now and I would like to just clarify why.
Just a head's up, I am using DB Browser for SQLite & Android Studio (3.2.1). My phone is Samsung S7 Edge+ and the emulator I have used is Pixel 2 XL API 28 (Android 9, API 28).
The first issue is that I have added new data into my database but it is not reflected when I run it on my phone. See attached for reference to new data added "database - knowledge.db" database = . I have also ensured that the data is updated by clicking the "Write Changes" tab. Afterward, to import the database to Android Studio, I have to create a database asset folder and stored my Knowledge.db file inside it. I have done so. However, when I run my app on my phone, it does not show the updated data when I scroll down, see the attached
actual phone
. But, when I run it on an emulator, the updated data are shown at
phone emulator
. The new data are those titled, "IIDS" "FIDS" and "GMID". Notice the two phones screenshots, the actual phone screenshots stopped at "Passenger Terminal" and upon scrolling down further no new data are shown, but on the phone emulator, new data are shown.
Initially, I thought it could be the sizing issue so I minimized the text sizes accordingly but the issue persisted. I can't think of other possible causes.
Secondly, I know I have updated the database at DB Browser by clicking the "Write Changes" because when I open it again, the new data and naming changed. But when I import it to Android Studio, it is not fully updated. See attached and the circled for reference. differences
As such, does anyone know what could cause this issue and how I can fix it? Any help is greatly appreciated!
The initial issue was due to the database already existing and thus that the copy from the assets folder is/was not done.
Delete the database (deleting the App's data or uninstalling the App) would result in the database then being copied from the assets folder.
However, you then encountered an issue with the version number. I believe that this was because the App had been changed to use database version 2 (actually from SQLite's point of view the user_version). Thus as the version isn't 1 (I suspect if it's 1 no version check is made, hence why not even having a version (as from the comments was the case)) then an attempt was made to check the DB's version resulting in a null pointer exception as there was no user_version set (perhaps a bug).
Basically you do not want to change the DB version from 1 if you are (when developing the App) re-introducing a changed database that is copied from the assets folder. Alternately you need to set the appropriate version using PRAGMA user_version=? (where ? is the version number) in the database, using whatever tool you use, before copying the databse into the assets folder.
The only reason why you would increase the database version (android wise) is when you are wanting the onUpgrade method to run.
Note assumptions have been made re checking the version number.
If you have released an App, then it could be far more complex to roll out a changed database as an asset.
I am not new to Android or Java but very new to Databases. I have been practicing with SQLite in Android and have now become completely stuck.
I want to completely remove the current database that I have been using in my app and create a new one with more columns, different types of columns, and etc...
I have tried "context.deleteDatabase()" which appears to delete the database but then after that I uninstall the app and re-install it with the myDatabaseHandler java class file having all the new columns and changed added to the file.
The code compiles and runs fine until I try to add info to the database, I receive an error cannot find columns, the error refers specifically to the columns that I added.
Why does it seem that I cannot start over completely. It seems like the structure or schema of the database won't change.
So how do I eliminate any evidence of the databases that I was practicing and messing around with, and just start completely new? After all, thats what practice is, you don't know what you are doing and you learn by making mistakes. So now I need to completely wipe away the mistakes, not upgrade just to make alterations.
Upgrading the database seems to provide an avenue for achieving close to what I want, but ultimately is way more involved and confusing for what I need when I just need to start over with a freshly created databases that has more columns.
The SQLiteOpenHelper class goes to great care to keep the old database to allow you to upgrade it in place.
If you're not interested in the old data, just change the file name. Then it is guaranteed that there is no old version. (You still have to call deleteDatabase() to get rid of the old file, but now that call cannot conflict with any accesses to the new file.)
Using the ADB tools from the SDK/platform-tools folder can help to remove all data (including the database schema)
./adb.exe -s shell pm clear <your app's package name>
will remove all the data associated with your app. Then you install the new version of the app, it will use the new database schema.
Is there a way, when there is a database upgrade with onUpgrade() method, to get the previous database?.
I mean, if current database version in 2 and I change it to 3, onUpgrade method is called, but after that is there a way to get the database corresponding to version 2 ?
No, there isn't. When you upgrade your database, the older version is overwritten.
You could try making a backup copy by copying the file from the internal storage's databases folder to your normal internal storage or the external storage, and then restoring it if you have to.
You cannot get the previous version, because now it is upgraded to version 3.
What you can do, is downgrade the database to the previous version with onDowngrade when you deliver a new app with database version 2. Although, this is only available from API level 11.
There are some things my application needs to do on first start up(first startup after update) . These actions could be described in a .txt file and then when it is the case read the file and do according to it ,or on the other hand (I lean to use this option) a sqlite database could be used to store the information . The apk file would be shipped with an .txt file/prebuild sql db stored in res/raw or res.asset and then copied into proper space and used. This I have figured out how !, though I'm not sure which option of this two would be the fittest ? One thing that is unclear to me is how could sqlite version mismatch affect me, and if it serious enough to take into consideration ? I 'm using Android api level 4 (Android 1.6) and the future application might be used on several different devices , with different api levels.
These actions could be described in a
.txt file and then when it is the case
read the file and do according to it
,or on the other hand (I lean to use
this option) a sqlite database could
be used to store the information .
Or, they could be implemented in Java.
Well the actions that the application
needs to perform on install / after
update , according to the update
version and the pre update version of
the application
Why not just implement this as regular Java code in your app?
Or, as Albert Einstein wrote, in homage to Occam's Razor: "Make everything as simple as possible, but not simpler."