Very (very) basic question that unclear to me:
Is SQLite db remain after application shutdown with all the data that was added to it or destroyed?
If so (and I hope so), when is the the DB schema created during the app lifecycle? I would expect it to be created on app installation,
but according to the documentation I see this is done every time that the application started.
What am I missing?
When is the code below executed during the application life cycle?
public class DatabaseHandler extends SQLiteOpenHelper {
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
} //DatabaseHandler
the DB data is stored under /data/data/<your.app.package.name>/database/ (or something similar to that). It is a physical file that remains stored on the device until your application is uninstalled or the user goes to Settings->App->Clear Data
the code you posted is executed the first time ever your app executes getReadableDatabase or getWritableDatabase. That means, the SQLiteOpenHelper class checks if a valid DB file exist on that location in disk. If there's no file, it executes the onCreate (which creates the DB file).
excerpt from methods getReadableDatabase or getWritableDatabase documentation:
Create and/or open a database
SQLite database will remain after shutdown.
Try use
CREATE TABLE IF NOT EXIST
to prevent the re-creation of the database
Yes, it remains until you remove your app from the smartphone or explicitly clear the DB.
You should check this tutorial, which covers a lot of sqlite for android.
Hope it helps.
Related
I've a requirement in my android app.
There is an already existing database A which has a table T. From the next release of the app, I want to create a new database B and MOVE my table from A to B WITH all the existing data.
I am guessing there'd be some way to take dump from the existing db and store that in an asset file. And then use that file to restore the table in new db.
Can't store that data in-memory as it might go to inconsistent state if the app is killed in between.
I am not able to find any well-defined way to do this after spending some time searching in the docs/on the forums.
Please help.
You can achieve this by using ATTACH command of sqlite. First is by specifying the path of the first database.
private static String FIRST_DB_PATH = context.getDatabasePath("Sample.sqlite").toString();
Then you attach it to secondDb
SQLiteDatabase secondDB = secondDBHandler.getWritableDatabase();
secondDB.execSQL("ATTACH DATABASE '" + FIRST_DB_PATH + "' AS tempDb");
Then do the insert query. NOTE: You use secondDB as main
secondDB.execSQL("INSERT INTO main." + SeconDB_table_name + "SELECT * FROM tempDb."+ FirstDB_table_name );
Then finally detach the first db
secondDB.execSQL("DETACH tempDb");
Hope this helps
EDIT:
Do this for dropping table
secondDB.execSQL("DROP TABLE IF EXISTS main." + SeconDB_table_name);
Ok heres how to create a table for secondDB as a copy of the firstDb
secondDB.execSQL("CREATE TABLE main." + SeconDB_table_name + " AS SELECT * FROM tempDb." + FirstDB_table_name);
If what you mean in comment is to drop the first table after moving it to second table, then drop it before dettaching
secondDB.execSQL("DROP TABLE IF EXISTS tempDb." + FirstDB_table_name);
I am programming in Android and am trying to make an SQL database to store highscores. In my onCreate method, I have
String query = "CREATE TABLE " + TABLE_SCORES + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_SCORE + " TEXT" + ");";
db.execSQL(query);
where TABLE_SCORES is the table name and the COLUMNS are my columns.
When I run the app, it works the first time and saves, but crashes the second time. In the logs, it says that it was unable to compile my query. I have already tried IF NOT EXISTS but it did not help.
Simply add IF NOT EXISTS after CREATE TABLE!
you should subclass SQLiteOpenHelper, implement public abstract void onCreate (SQLiteDatabase db), and put your create query there. onCreate is called just once, the first time the database is created. This way you can avoid checking if the table exits or not
When my application starts for the first time it needs to create the database it'll be using. I don't know at what point I should be creating the database if it doesn't already exist yet, and I don't know how to ensure I don't try to create the database if it already does exist. Currently, the following works, where I execute CreateTable when the first activity in my app runs:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
base.SetContentView(Resource.Layout.SiteListLayout);
DataManager.CreateTable<Site>();
DataManager.CreateTable<PanelLog>();
DataManager.CreateTable<Trace>();
}
Basically, this works because the CreateTable method checks to see if the table already exists before creating it. However, I don't like the idea of frivolously running some code knowing it's going to fail because of some of some exception to its expectations. I'd prefer to be more explicit.
Therefore, how can I execute code the first time my app runs to test if the tables need to be created, and if so to create them? And any subsequent time my app runs it doesn't check that code.
This is what I use to create or upgrade my database, and it seems to work really well. It's a hack from various sources in the web. It creates 4 tables, unless they already exist. I haven't included the static variables but that should be clear enough to follow?
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
db.execSQL(DATABASE_CREATE_2);
db.execSQL(DATABASE_CREATE_3);
db.execSQL(DATABASE_CREATE_LIST_SUB);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_2);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_3);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_LIST_SUB);
onCreate(db);
}
}
You can use other data storage options in android.take a look at http://developer.android.com/guide/topics/data/data-storage.html#filesInternal.You may find any storage option that are specific and secure to be used by a single app and their lifetime will be until you uninstall the app.So store in it the information either you created database or not,and check that storage everytime you run that app.
Create your database at the main_activity if you want, you can even create it on the splash screen activity if you have one.
As long you don't change the tables names, they will be created only one time, which is the first time the class that contains create table commands is called.
UPDATE
Check this Website, there you ll find a very simle tutorial, a bit long but very helful, if you don't have time you can try to use the code for creating your tables.
I m following this tutorial.http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
can any body please make me clear this chunk of code.
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
// Create tables again
onCreate(db);
}
Questions
What is the purpose of onUpgrade(); method?
When it is Called? as docs says this is Called when the database needs to be upgraded what does it means by upgrading the database?
Important
why we drop the table in this method and recreate?
Thanks in advance.
onUpgrade is basically for handling new db changes(could be new columns addition,table addition) for any new version of your app.
Droping the table is not always necessary in onUpgrade it all depends on what your use case is. If the requirment is to not to persists the data from your older version of app then drop should help,but if its like changing schema then it should only have alter scripts.
Upgrade means changes have been made to the database schema(version numbers are different) and it needs to be upgraded. Dropping the table and recreating is one way to do that. You could also issue "alter table" statements.
When you open your database it checks the version number and whether or not it exists. You can just "upgrade" your database rather than creating it new.
A good tutorial: http://www.vogella.com/articles/AndroidSQLite/article.html
This method is called when you update your database version. It drops the existing tables and creates it again when onCreate method is called again.
Replying to your 4 questions:
1) The purpose of onUpgrade is to manage a new database structure. You could start you app with simple features, then you need for instance to add a new column, so you need to increase the version of your database from 1 to 2 and in onUpgrade
give the instruction to add a new column, so that if the user update the app, the new column become added.
2) onUpgrade is called when you have a new version of your database and you incremented the int number in the super method( here is 1, so you eventually change it to 2)
public static class DatabaseHelper extends SQLiteOpenHelper{
DatabaseHelper(Context context){
super (context,DATABASE_NAME,null,1);
}
3) Please see above regarding what does it means to update the db
4) We Drop the table and recreate, because to modify the table (example for adding a new column that fits a new feature) a logic way to proceed could be, before to "destroy"/DROP the table and then create a new one with all the data. But this can be not the way to go although recreating the data could mean that the id numbers will be consecutive( usually are not consecutive: you could have 1, 2, and..4 because 3 has been deleted), hence dropping and then creating the table again, and eventually loading the previous data you could have this id consistency.
Sometimes you may want to use ALTER instead of DROP. Why? Usually because using DROP the user loses the content already has in the database, then if you want to learn more about Best practices and more complex real life scenarios please have a look at this amazing reply
I'm trying to create an Android app that can handle a history of played games and their scores, but as I expand from the Notepad tutorial, this is turning into a rat's nest of repeated statements like this:
private static final String GAME_TABLE_CREATE =
"create table " + GAME_TABLE + " (_id integer primary key autoincrement, "
+ "title text not null);";
private static final String PLAY_TABLE_CREATE =
"create table " + PLAY_TABLE + " (_id integer primary key autoincrement, "
+ "game_id integer, game_date date);";
private static final String PLAYER_TABLE_CREATE =
"create table " + PLAYER_TABLE + " (_id integer primary key autoincrement, "
+ "name text not null);";
private static final String SCORE_TABLE_CREATE =
"create table " + SCORE_TABLE + " (_id integer primary key autoincrement, "
+ "game_id int, player_id int, score int);";
...
public void onCreate(SQLiteDatabase db) {
db.execSQL(GAME_TABLE_CREATE);
db.execSQL(PLAY_TABLE_CREATE);
db.execSQL(PLAYER_TABLE_CREATE);
db.execSQL(SCORE_TABLE_CREATE);
}
This seems like a nightmare for readability and maintainability. Any advice on how to better manage multiple SQL tables, and turn these kinds of lists into nice clean loops? I was thinking about trying to do it via resource string-arrays, but haven't been able to figure out how to manage that.
I haven't had to deal with this in the Android world but have in the past in the Web world. I'd said for starters you may want to look at an ORM for managing you statements. There seems to be some pointers here that might help.
I manage this by turning off formatting in Eclipse (you must be using Helios or higher) by using the statement //formatter: off (and turning it on after). This SO question will give you more information on that.
I also place all my initial SQL statements (CREATE, Triggers, etc.) inside a static String array. This way all your statements can be run with this code in your onCreate:
public static final String[] SQL_CREATE_TABLES = new String[] { TABLE_1, TABLE_2};
#Override
public void onCreate(SQLiteDatabase db) {
for (String sql : SQL_CREATE_TABLES)
db.execSQL(sql);
}
The SQL statements could also be placed in the strings.xml resource file, but I don't think that would help maintain readability or maintainability.
I ran into this same issue when first starting out, managing the create tables as statements inside the Android app became really cumbersome, especially trying to update the schemas as development progressed. What worked really well for me was simply placing a copy of my database in the assets folder and then copy the database to the data folder. The first time your DBAdapter starts you can check if the database already exists, if it doesn't you can then copy your database over. This is also handy where tables need to be prepopulated with data, or pre loaded with data for testing. It made life so much easier to manage the database schemas in a normal/GUI based database tool.
There are lots of Android copy database code examples, a simple Google search should set you in the right direction.
Hope this helps,
Cheers,