I am using a SQLite database file in my Android application that is created from several pieces stored in the assets folder by using the following approach:
ReignDesign - Using your own SQLite database in Android applications
On completion of the assemby process I would like to check if the database was correctly merged. The following approaches crossed my mind:
MD5 hash comparison
Checking table existence and entry counts
Which approach would you recommend? Is there a better way?
Thanks,
Philipp
http://www.sqlite.org/pragma.html#pragma_integrity_check.
In Api 11, SQLiteDatabase has a method isDatabaseIntegrityOk for checking integrity of SQLite databases :
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#isDatabaseIntegrityOk()
And source code is avaible here :
https://github.com/android/platform_frameworks_base/blob/ics-mr1-release/core/java/android/database/sqlite/SQLiteDatabase.java#L2585
It's easy to backport on old devices.
I had a similar situation in an application I'm developing. There are a variety of ways of doing it; but in the end I stopped worrying about what exactly and how to best measure database integrity, and instead focused on 'is my database usable by my application'.
So basically I test whether: 1) I can open the SQLite database properly 2) I can perform queries on the database and 3) Whether the result for a pre-defined query returns what is expected.
So basically: include a table with a record of known ID that gives a value that you know, then try to read that value. Checking the table count can't hope.
That said I'm hoping someone here with a good knowledge of DB systems will explain a) exactly what PRAGMA integrity_check does and b) how reliable it is and how efficient it is compared with manual table checks.
I would prefer second approach on the first one both with respect to performance and ease of coding.
Related
I'll begin with explaining how I stumbled upon SQLite Asset Helper library. I am trying to build a small android application which is basically shows the meaning of words. And to do so I intend to keep everything offline (no dependence of internet connectivity). Now, as far as I can think of, there are 2 ways of achieving that:
1. Using String array, which I believe will be a tedious task and a memory hog.
2. By providing a pre-populated database, using which I can easily establish relations between words and their meanings and do more (searching, sorting, etc).
Now, the problem I am facing is supplying a pre-populated database (or words and meanings) with the app itself. And for doing that I came across SQLite Asset Helper which does the job.
I have read a number of articles related to SQlite Asset Helper but not many which confirm its implementation on latest iterations of Android. Also, is the only possible solution to deliver a pre-populated database to the user (without needing to go online)? Is it acceptable method? Any other better alternative up for suggestion would be great!
I have read a number of articles related to SQlite Asset Helper but not many which confirm its implementation on latest iterations of Android
It works on the latest iterations of Android.
Also, is the only possible solution to deliver a pre-populated database to the user (without needing to go online)?
You are welcome to roll your own implementation. I do not know what you would gain by this.
Is it acceptable method?
I am not aware of anything better.
I'm trying to create some sort of backup & restore function in my app. Before that, I've been reading for a while to understand if it's possible to achieve, but I found out this question:
Sqlite DB Android Backup/Restore
The only other way I could see to do it, would be to read the actual contents of the DB and generate a file containing the SQL which which it can be restored from, this is obviously a more complex and doesn't offer any advantages to justify this complexity.
This answer, I think, is the best way to accomplish that; not explorting the .db file, but exporting queries.
You know; when you export a SQL data from mysql, you get a file which contains all the queries that creates the structure and queries that fill the structure with data.
That's what I'm trying to mimic; generate a file which contains sql queries from a .db file.
Do you guys think it's possible, I mean, is there any builtin method to achieve that?
Otherwise, if its too hard to handle, how do you manage to avoid what this user (https://stackoverflow.com/a/10842043/1943607) is talking about?
So, I disabled WAL with "PRAGMA journal_mode = DELETE" and then I was able to view the database in the browser and able to restore it on my test device fine.
That previous part, I can't understand it. Is this a configuration you set to sqlite?
Thanks
I haven't actually tried this with sqlite, but with mysql you could do things like create "dumps" of your database. Those dumps contained exactly what you describe: a set of queries that, when executed together, recreate the database, including the contents.
Judging from the "sqlite3" documentation found at http://www.sqlite.org/sqlite.html (especially the "Converting An Entire Database To An ASCII Text File" section), you can do the same for sqlite. Since you can execute shell commands from a java application (using Runtime.getRuntime().exec() methods), and you are the "owner" (Linux user id) of the database, you should be able to run this "sqlite3 .dump" command even on a non-rooted device. I have never seen an Android device without the sqlite3 tool installed, so the command should always be available.
Moreover, since dump file is just a text file, you should be able to prepend any PRAGMA's to it that are required for compatibility (like the one you quoted).
I haven't tested any of this, but just wanted to think with you on this interesting topic.
An sqlite database is just a file so you could copy the file but I think you may have problems with permissions in android preventing you from accessing the database.
A better solution IMO would be to sync your data to an external website.
Using a combination of a custom sync adapter and the account manager with a website or web service that has a RESTfull api to receive and send the synced data would be the most reliable approach.
http://developer.android.com/training/id-auth/identify.html is a great introduction to setting up the account manager.
And for a custom sync adapter this is a great starting point.
http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/
and http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-2/
And finally an explanation of how it all fits together
https://sites.google.com/site/andsamples/concept-of-syncadapter-androidcontentabstractthreadedsyncadapter
The above approach would enable a user to switch phones and retain data at the same time and the data would always be up to date (providing you sync at the appropriate times.
It seems like a lot of work as you will need to set up a web service but it is the BEST way to make sure data is kept safe and secure and can be restored and backed up at any point.
For a web service there are lots of options available to you including cloud services such as Google docs or writing your own website. Ruby on Rails is a great solution for developing your own site as you get a full RESTfull api out of the box and it;'s dead easy to secure/lock down a rails site to authorised users only with a couple of lines of code and with Heroku you can get free hosting.
As usual with Android development the simplest of requirements actually ends up being the most difficult to implement but where data safety is paramount then it's worth the effort to do it properly.
The question is too open to answer simply because the changes that may apply to the db file content are open and one can't guarantee a specific behavior .
On the positive side sqlite project is an open source and the format of the DB file is specified Here
After taking a look there, it seems very possible/not too complicated to parse any DB file looking for Data Only and write it/dump it to another functional db file.
I believe this is the fastest and cleanest solution to the issue in hand.
so to wrap up:
Copy DB file everytime you want to back it up.
When you want to restore create a new DB using Android APIs.
Parse the data from the backed up file and write them to the newly created DB.
P.S:
regarding how to use
PRAGMA journal_mode = DELETE
Simply use db.exec("PRAGMA journal_mode = DELETE"); when creating the DB
I have a huge set of data that I want to insert into the sqlite database before the user is able to do anything inside my application. Right now I have all my data stored in CSV files, then I parse those files and use DatabaseUtils.InsertHelper to do a bulk insertion, but this is taking to long to complete.
I stumbled on this tutorial some time ago and I'm wondering: is it safe to distribute a pre-generated sqlite file? Can I run into problems due to different versions of SQLite on different devices?
I'm planning to support Android 2.1 and higher.
I suppose it depends on your definition of safe. It is certainly possible as long as the database conforms to the metadata table spec Android expects, which is what that tutorial you stumbled upon is showing you. You won't have to worry about version conflicts with SQLite as that is a package built into the core platform and isn't something OEMs add to or implement anything on top of.
However, if by safe you mean "protected" you would need to take special steps to ensure that your database is not externally readable if that is a concern. If you simply place the preconstructed DB into assets/ and copy it over, anyone who can properly deconstruct an APK file can view your database data. This may or may not be an issue for you.
The best approach is to populate this data in the database, keep the database in assets & then copy it to the device ... You can follow this complete sample code here.
I need to ship an app that uses read-only access to several preexisting SQLite3 DB's that each are a couple of 100MB's, total combines size > 1GB. The databases are created on a Mac, and are currently used in a shipping iOS app. I am pretty proficient in Java, but new to Android.
This leads to the following questions:
1) Will I need to modify the databases? I only plan to use them with SQLiteDatabase::rawQuery queries, so no nee for bindings and metadata I hope.
2) It it really correct that even if the DB's will only be used as read-only, I'll have to copy them out of the app bundle or download them to user directory on first start-up?
3) The queries can be slow. I want to run them in a thread and provide data via a callback. Is this done the way it's done in normal Java (Runnable/Thread), or will I have to use another method?
4) Is there anything else that's obvious to the Androidan that I have clearly missed?
1) No, it should work fine.
2) Yes, if you want to ship an APK that is over 50Mb you will need to use an expansion file.
3) For easy background tasks with a call back you could use an ASyncTask.
for a decent example of a sqlite helper class look here
you shouldnt need to edit the database. my sqlite databases work the same wether I access them via sqlite3 or with the android my sqlite helper class
once you copy them you can read and write
not really sure about this answer. i will say though that the database helper class above seems to work just fine (fast) but my db is smaller (500kb)
dont think so
I'm creating an app which is going to have some data that is stored in an SQLite database. I want the user to be able to create "folders" which can be assigned to each data item.
I was going to do this using a one to many relationship e.g. one "folder" can have many data objects under it but having looked at relationships with SQLite and Android it seems that this would only work in 2.2+ so I'm just wondering what the alternative is?
Any information is much appreciated.
You can still have relationships; older versions of SQLite just won't enforce them. As a stopgap, you can build triggers to do it; in fact there's a handy generator that will generate the SQL for you to use as a starting point.