I have an sqlite3 database in Android. There is a thread that works with
the db. From another thread, I'd like to copy the sql file to a different location. I do not know whether the db is closed at the moment, or maybe there is a transaction going on at precisely the same moment. Can I assume that the copy of a file will always be a valid sqlite database?
Since the transactions in sqlite are atomic, this looks reasonable but I'd like to be sure.
The db is opened using DatabaseHelper and data is inserted time to time with SQLiteDatabase.insert. Some times the db is closed and then reopened.
Database transactions are atomic, but copying a file is, by itself, not a database transaction.
To ensure that no other SQLiteDatabase object can access the database file, execute BEGIN EXCLUSIVE first.
As long as you do not change the database inside this transaction, the database file is in a consistent state.
Related
Android Room has method void clearAllTables() and according to docs it makes the following:
Deletes all rows from all the tables that are registered to this database as entities().
This does NOT reset the auto-increment value generated by autoGenerate().
After deleting the rows, Room will set a WAL checkpoint and run VACUUM. This means that the data is completely erased. The space will be reclaimed by the system if the amount surpasses the threshold of database file size.
I checked it in my project and looks like db has no data after that call, but when I pulled
*.db file from my device and opened it in sqlite viewer I've seen that all the data exists, the tables are filled and nothing has been erased.
How can that be? I consider this as a potential flaw in my app. Please provide a reliable approach of cleaning room database
looks like db has no data after that call
It means the method worked.
when I pulled *.db file from my device and opened it in sqlite viewer
I've seen that all the data exists
Most probably the transactions are not moved to the original database from the WAL file yet.
Solution
You can force a checkpoint using the wal_checkpoint pragma. Query the following statement against the database.
pragma wal_checkpoint(full)
I have an android application that relies on a sqlite database, and use OrmLite to access my DB.
Instead of OrmLite creating the tables I rely on downloading the database from a central server as the user will often want to "sync" things. Currently I don't have the fancy sync code written so the app replaces the db. The steps are:
1 Download the latest SQLite db file from the server, as a zip
2 Expand the file to produce a database.sqlite file in a temporary folder
3 Deletes the contents of a data folder, which contains the live database.sqlite file
4 Move the database.sqlite file from the temporary folder to the data folder.
The problem is that the new database file seems to get ignored and DAO queries I run return old data. The only way to show data from the new version of the DB is to restart the application.
To test things I created a table with a timestamp that records when the database was generated, each time you request a new copy of the sqlite db from the server this is updated. I have a fragment that displays this time so you know how fresh your data is. In the fragments onResume method I make a call to the DAO to get the timestamp and put value on screen. I've stepped through this and I see the call to the DAO but the value that comes back is from the old, now deleted, db. Restart the app and the correct value is shown.
So my question is, if I replace the underlying sqlite db file that stores my database, how can I tell ormlite to pick it up or refresh the connection or whatever it has to do???
I tried calling clearObjectCache on the DAO, made no difference.
I'm new to programing for android and i'm still learning. So I have a question about the location of the SQLite database. Is it stored in the same file system as the application ?
And also i'm not sure can the database be created before the app is installed(can it come with the app) or can the database only be created from inside the app ?
And what if i wanted my app to come with a database that already has tables and records which is local and not on a server. Would that be possible ?
SQLite is available on every Android device. Using an SQLite database in Android does not require any database setup or administration.
You only have to define the SQL statements for creating and updating the database. Afterwards the database is automatically managed for you by the Android platform.
Access to an SQLite database involves accessing the filesystem. This can be slow. Therefore it is recommended to perform database operations asynchronously, for example inside the AsyncTask class.
If your application creates a database, this database is by default saved in the directory DATA/data/APP_NAME/databases/FILENAME.
The parts of the above directory are constructed based on the following rules. DATA is the path which the Environment.getDataDirectory() method returns. APP_NAME is your application name. FILENAME is the name you specify in your application code for the database.
You can also follow this tutorial for further understanding.
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
Database is created after the app installation or after the db changes. The db is stored in /data/data/your_package/databases/
I am building an application which has a database with two tables created internally using SQLiteOpenHelper.When ever the application is running,it receives some data and saves it into the tables.What I want is to clear the data tables when ever the application is started?
I looked into this post How can I clear an SQLite database each time I start my application? which is not clear of how to use application.
SQLiteOpenHelper has the ability of creating in-memory databases if you pass the constructor a null name. Probably this is what you are looking for.
For example:
SQLiteOpenHelper sqloh = new SQLiteOpenHelper(context, null, null, 1);
SQLiteDatabase sqldb = sqloh.getWritableDatabase();
will create an in-memory db.
SqliteDatabase uses the method openOrCreate(...) which opens a database if it exist and creates and opens it when it doesn't exist. see docs based on that you could just delete the database file that is created before you do any database calls so that a new one is created each time.
This SO question gives the location of the file: Location of sqlite database on the device
There other route would be just to delete the data in the tables when the application starts by executing a sqlite query:
DELETE FROM your_table
My only thought would be do you really need a database if you are going to delete it every time the application starts. If you are not updating the data then why not just "cache" a json file with the data. The GSON library is awesome for taking json and converting it to java object with very little code, going to be less code than working with sqlite. But the recommendation comes from not having the big picture for what you are trying to accomplish. You then would just delete the json file(s) when the app starts instead of the db file.
I have an app that creates a database and do some stuff. I am wondering if i upload a new db to a server and download it to the exact folder where the older one exists it will be overwritten and i am good to go? Or there will be a problem. Assuming it has the same name, same column names, etc. Of course i am reffering to sqlite.
In Android, when performing a database update you should be using onUpgrade inside of the SQLiteOpenHelper. One way of doing this is to download text files that include the sql instructions needed to modify the current database or update rows with new data. The reason you have to do this is because Android will only create the database once. After the initial creation the call to onCreate for the database will not occur.