Adding new table to database after app has executed once - android

I'm making a simple database in Android. I want to add new table after my code has executed once. Now, whenever i try changing my onCreate() method in EventDataSqlHelper class my app crashes.
This is probably because onCreate() associated with SQLiteOpenHelper is executed only when app is first run and we can't make further modifications in it .
I also tried writing a separate function for adding new table. It worked perfectly on first execution.But since on 2nd exection it will overwrite its previous database, hence it causes app to crash.
Is there any way to add new tables to database if database has already been created?
package org.example.sqldemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.util.Log;
/** Helper to the database, manages versions and creation */
public class EventDataSQLHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "events.db";
private static final int DATABASE_VERSION = 1;
// Table name
public static final String TABLE = "events";
// Columns
public static final String TIME = "time";
public static final String TITLE = "title";
public EventDataSQLHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table " + TABLE + "( " + BaseColumns._ID
+ " integer primary key autoincrement, " + TIME + " integer, "
+ TITLE + " text not null);";
Log.d("EventsData", "onCreate: " + sql);
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

This is what onUpgrade and DATABASE_VERSION is for.
Example:
You have a table events, and is executed on phone.
Now you decide, you want a new table users.
change DATABASE_VERSION = 2; (this is your version number)
in onCreate() , create all tables (create table events & create table users)
in onUpgrade(), create all tables that changed between version oldVersion and newVersion (create table users)
Later if you want to add new tables, increment DATABASE_VERSION again, and create all tables in onCreate, and changes in onUpgrade

You could use CREATE TABLE IF NOT EXISTS TABLENAME ... as your query, that wouldn't overwrite your existing table.

Related

How to make changes to the database without having to uninstall APK every time?

public class ProjectConstants {
public static final String myDbName = "ContactsDatabase.db";
public static final String myTableName = "ContactDetails";
// public static final String myTableName = "ContactDetails1";
public static final String nameColumn = "ContactName";
public static final String numberColumn = "ContactNumber";
}
First I create a contact application with Table Name : ContactDetails
Then I do all the adding, editing and deleting operations over that database table. Say I have 15 contact details in that database table named ContactDetails.
Now in the above code snippet I make 2 changes:
I comment this line
//public static final String myTableName = "ContactDetails";
And I uncomment this line
public static final String myTableName = "ContactDetails1";
Now if I run the code, the App crashes.
My learning from Stack Overflow has crudely taught me 2 things to ponder
1.
Remember to uninstall and then reinstall your app so the onCreate
method is called again and the database recreated.
2.
If the database is created for the first time, the onCreate method is
called in the helper class, otherwise onUpgrade is called.
My subclass that extends SQLiteOpenHelper class looks like this,
public class DBHelper extends SQLiteOpenHelper {
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQLCreateEntries =
"CREATE TABLE " + ProjectConstants.myTableName + " (" +
ProjectConstants.nameColumn + TEXT_TYPE + COMMA_SEP +
ProjectConstants.numberColumn + TEXT_TYPE + " )";
private static final String SQLDeleteEntries = "DROP TABLE IF EXISTS " + ProjectConstants.myTableName;
public DBHelper(Context context) {
super(context, String.valueOf(name), null, version);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(SQLCreateEntries);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL(SQLDeleteEntries);
onCreate(sqLiteDatabase);
}
Now if I follow the instruction in the 1st quote block by uninstalling and reinstalling the application every time I mess with the database, the app never crashes.
But if I revert back to the original database,(then I do this uninstalling and reinstalling the application) obviously my data in the database do not exist anymore.
As mentioned above my Database table named "ContactDetails" which held 15 contacts will no more have that data now.
But I want that 15 contacts to stay intact inside my database Table "ContactDetails".
Is there anyway to make changes to the database without having to uninstalling-reinstalling apk and without losing the previous data ?
You have write SQL Commands and execute block of SQL commands with different version of code on OnUpgrade() of Helper class as follows:
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL(SQLDeleteEntries);
onCreate(sqLiteDatabase);
switch(i){
case 1:
<commands for version 1>
break;
case 2:
<commands for version 2>
break;
}
You can write the swich cases as per version of applications. you can write different block of SQL commands as you want to execute on different version of applications.

Manually executing sql query in Android

I already have a database in my app using a 3rd party library. The library doesn't seem to have drop table functionality. So I was thinking to directly change it using SQLiteOpenHelper API. Is this possible?
I have created a class that extends SQLiteOpenHelper and give it the same db name as the one used in the library.
public class SqliteDatabaseHelper extends SQLiteOpenHelper {
// Database Info
private static final String DATABASE_NAME = "myDatabase";
private static final int DATABASE_VERSION = 1;
private Context context;
public SqliteDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
L.w("old: " + oldVersion + ", " + "new: " + newVersion);
if (oldVersion != newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + "deals_latest");
onCreate(db);
L.w("drop it like it's hot");
}
}
}
And I initialize it in Application class, just to see if it reflects the db class I created.
SQLiteDatabase db = new SqliteDatabaseHelper(this).getReadableDatabase();
L.w("version: " + db.getVersion());
L.w("path: " + db.getPath());
SqliteDatabaseHelper helper = new SqliteDatabaseHelper(this);
helper.onUpgrade(db, 1, 2); // this line suppose to invoke the drop table query
When running the app, onUpgrade() method doesn't seem to be called.
Mind you, I have never had any experience in using the native SQLite helper, so I have no idea what is going on here. My objective is just to see if the query in onUpgrade is executed or not. But the table still exists in the database.
How do I get around this?
The SQLiteOpenHelper class helps to manage versions of your own database.
It does not make sense to use it for a database that is managed by third-party code.
Just open the database directly with openDatabase().

Android dev: Creating a sqlite database for word games, no user inputs

I have a simple game where users guess words. Now, I'm thinking using database to store these words to be guessed.
My problem is the tutorials that are available in the web show how to create a database and save user inputs to that database. They create, for example, a DBHelper.java in src, extends it to SQLiteOpenHelper, override the methods. Back to a specific activity, create an instance of DBHelper, then create the db, open the writable, insert user inputs, close db.
But what I think I only need to do is create a database, insert words in it, then make my app retrieve words from this database.
Am i just wondering if what i'm planning to do is right:
1. create a DBHelper.java in src, extends the class to SQLiteOpenHelper
2. define needed Strings like name of database etc.
3. Create a constructor and override the onCreate and onUpgrade methods
4. CREATE A LOADWORDS METHOD this is where i will insert my words to the database.
5. on my main activity(the first screen on my app) I will create an instance of DBHelper and call the onCreate and loadWords method.
// you would want an onCreate and onUpgrade method for best practices,, here's a partial look of what you want...
public class DBManager extends SQLiteOpenHelper
{
static final String TAG = "DBManager";
static final String DB_NAME = "words.db";
static final int DB_VERSION = 1;
static final String TABLE = "words_table";
static final String C_ID = "id";
static final String C_WORD = "word";
public DBManager(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
String sql = "CREATE TABLE " + TABLE + " ("
+ C_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ C_WORD + " TEXT)";
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE);
onCreate(db);
}
//**** Code Insert Word and Retrieve Word Methods *****//
//**** End Code Insert Word and Retrieve Word Methods *****//
}

Android Database not being created on install / android packages

I want to use a SQLite database within my application. I have created a class which extends SQLiteOpenHelper. When I first wrote the code the database appeared in /data/data/(package)/database. The package name was my reverse domain + /mobile/app. I then created a separate package within my project reverse domain + /mobile/data and moved my Database class into it.
/data/data/(original package)/database existed until I reloaded(to not use the snapshot) my emulator.
since then:
/data/data/(original package)/ is created but with no database directory, /data/data/(data package)/ is not created on the file system. I have tried:
moving my database class back to the original package
creating a new version of the emulator
uninstalling the app within the emulator and then re-installing it.
increasing the database version variable
commenting our code associated with the database class in other parts of my app.
Here is my db class code.
public class BusinessOpsDatabase extends SQLiteOpenHelper {
private static final String TAG = "BusinessOpsDatabase";
private static final int DB_VERSION = 1;
private static final String DB_NAME = "bss_business_ops";
// country table variables
public static final String TABLE_COUNTRY = "country";
public static final String ID = "_ID";
public static final String COL_COUNTRY_NAME = "country_name";
private static final String CREATE_TABLE_COUNTRY = "create table "
+ TABLE_COUNTRY + " (" + ID
+ " integer primary key autoincrement, " + COL_COUNTRY_NAME
+ " text not null);";
private static final String COUNTRY_SCHEMA = CREATE_TABLE_COUNTRY;
public BusinessOpsDatabase(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// create tables
db.execSQL(COUNTRY_SCHEMA);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// drop country
Log.w(TAG, "Upgrading database. Existing contents will be lost. ["
+ oldVersion + "]->[" + newVersion + "]");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_COUNTRY);
// create tables
onCreate(db);
}
}
http://www.techotopia.com/index.php/An_Android_SQLite_Database_Tutorial
Use above link to learn . you may solve all your problems regarding sqlite
I managed to resolve the problem by adding the following code to the database constructor.
SQLiteDatabase db = getWritableDatabase();

how to create database once only, then read and write multiple times from it, SQLite, OpenHelper, Android

I made two classes, the main class that extends Activity and the Database class that holds the database and it's methods. parts of the code from the database class are shown below.
the SQLiteOpenHelper class is a nested class inside the database class. I took it from an example I found on the internet. inside of this nested class is the method,
db.execSQL(SCRIPT_CREATE_DATABASE);
how do I create a new database? If I instantiate the Database class from the Main class like this:
Database db = new Database(this);
does that instantiation automatically instantiate the nested SQLiteOpenHelper class too? so i don't have to explicitly do that.
however for this example of how to create a database, i am confused. if every time I instantiate a new instance calling the addNewRow() method like this:
public void addNewRow(String label, int price){
Database db = new Database(context);
db.openToWrite();
db.insertNewRow(checkBoxStatus, label, price);
db.close();
}
then a new database is created on the "new Database(context)" call, and next I add the info to enter into the columns. and finally call db.close(), however every time i call the addNewRow method shown above, it will instantiate a new database and that also instantiates SQLiteOpenhelper class so a new database is created. that means the last database has been overwritten, and my last row added has been lost, is this correct?
how do i use this Database class to create a Database only once and then read and write things from it with multiple calls like this?
Database db = new Database(context);
db.openToWrite(); or db.openToRead();
// read or update or create new row in database
db.close();
the database class:
public class Database {
public static final String MYDATABASE_NAME = "my_database";
public static final String MYDATABASE_TABLE = "my_table";
public static final int MYDATABASE_VERSION = 1;
public static final String KEY_CHECKBOX_STATUS = "check_box_status";
public static final String KEY_CHECKBOX_LABEL = "check_box_label";
public static final String KEY_PRICE = "price";
//create table MY_DATABASE (ID integer primary key, Content text not null);
private static final String SCRIPT_CREATE_DATABASE =
"CREATE TABLE " + MYDATABASE_TABLE + " (" + "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
"KEY_CHECKBOX_STATUS INTEGER, " + "KEY_CHECKBOX_LABEL TEXT, " + " KEY_PRICE INTEGER" + ");";
SQLiteDatabase sqLiteDatabase;
SQLiteHelper sqLiteHelper;
Context context;
public Database(Context c){
context = c;
}
// after this all the rest of the methods for get and set of database values
code for the SQLiteOpenHelper class, nested inside of the Database Class:
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(SCRIPT_CREATE_DATABASE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
Yes, every time you instantiate a Database class a SQLiteHelper is instantiate. But the SQLiteHelper onCreate is only called if the database does not exist. You can test this by adding a new column to one of the table and then try to insert a row having value in this column then your app will crash. The error would be "no such column". You then need to clear your data or change the version of your database or uninstall your app to have your change table to be recreated.
Whenever you want to just open your database, you need to use this:
myDatabase = myOpenHelper.getWritableDatabase();
This won't create a new database. It would just return the instance of existing database on which you can do Read/Write operations.
Refer this to get a firm idea of how creating database works in Sqlite. Hope it helps.
private static final String SCRIPT_CREATE_DATABASE =
"CREATE TABLE IF NOT EXISTS " + MYDATABASE_TABLE + " (" + "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
"KEY_CHECKBOX_STATUS INTEGER, " + "KEY_CHECKBOX_LABEL TEXT, " + " KEY_PRICE INTEGER" + ");";
Use this query while creating the table. It will create the Table if it doesn't exist.

Categories

Resources