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().
Related
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 *****//
}
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();
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.
I've been racking my brain on this for days and I just can't wrap my head around using SQLite databases in Android/Java. I'm trying to select two rows from a SQLite database into a ListArray (or two, one for each row. Not sure if that would be better or worse) and I just don't understand how to do it. I've tried various database manager classes that I've found but none of them do what I need and it seems that I should be able to do this simple task without the extra features I've seen in other database managers. Is there any simple way to JUST query some data from an existing SQLite database and get it into a ListArray so that I can work with it? I realize I need to copy the database from assets into the Android database path and I can handle that part. I also need to be able to modify one of the columns per row. I don't need to create databases or tables or rows. I implore someone to help me with this as I consider any code I've written (copied from the internet) to be completely useless.
You can create a method like this :
private List<MyItem> getAllItems()
List<MyItem> itemsList = new ArrayList<MyItem>();
Cursor cursor = null;
try {
//get all rows
cursor = mDatabase.query(MY_TABLE, null, null, null, null,
null, null);
if (cursor.moveToFirst()) {
do {
MyItem c = new MyItem();
c.setId(cursor.getInt(ID_COLUMN));
c.setName(cursor.getString(NAME_COLUMN));
itemsList.add(c);
} while (cursor.moveToNext());
}
} catch (SQLiteException e) {
e.printStackTrace();
} finally {
cursor.close();
}
return itemsList;
}
This will be inside your class let say MyDatabaseHelper where you will also have to declare a :
private static class DatabaseHelper extends SQLiteOpenHelper{
private final static String DATABASE_CREATE="create table " + MY_TABLE + " (id integer primary key, country string);";
public DatabaseHelper(Context context,String name, CursorFactory factory, int version){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db){
db.execSQL(DATABASE_CREATE);
}
#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 "+ MY_TABLE);
onCreate(db);
}
}
used to open() and close() the database.
I'm planning on improving my SQLite implementation - currently, activities are opening the SQLite DB whenever they need some relevant data, then closing it. Closing the DB is important to avoid exceptions.
my design goals:
thread-safe access to an applications' SQLite DB
synchronous operation
What I thought I would do is implement some kind of "Manager" class instead of my basic "SQLhelper" class. I want synchronous operation so that rules out implementing it as a service with messages.
I think the best way to implement this "SQLiteManager" is as a singleton.
Are there any better implementations ?
Step 1 - extend the Application class
import android.app.Application;
import android.content.Context;
/**
* This class is created automatically when the app launches.
* It is used to provide an application-level context for the SQLiteOpenHelper
*/
public class ApplicationContext extends Application
{
private static ApplicationContext instance;
public ApplicationContext()
{
instance = this;
}
public static Context getContext()
{
return instance;
}
}
Step 2 - update the manifest so that this application class is used
<application android:name="ApplicationContext"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="true">
Step 3 - build the singleton SQLdataHelper into your app
public class SQLdataHelper
{
//for logging
private final String TAG = this.getClass().getSimpleName();
//DATABASE
private static final String DATABASE_NAME = "my.db";
private static final int DATABASE_VERSION = 1;//initial version
//TABLE NAMES
private static final String TABLE_NAME_A = "exampleOneTable";
//MEMBER VARIABLES
private DatabaseHelper mDBhelper;
private SQLiteDatabase mDB;
//SINGLETON
private static final SQLdataHelper instance = new SQLdataHelper();
private SQLdataHelper()
{
final DatabaseHelper dbHelper = new DatabaseHelper(ApplicationContext.getContext());
//open the DB for read and write
mDB = dbHelper.getWritableDatabase();
}
public static SQLdataHelper getInstance()
{
return instance;
}
/**
* INSERT FUNCTIONS consisting of "synchronized" methods
*/
public synchronized long insertTableA(String myName, int myAge)
{
Long lValueToReturn;
//organize the data to store as key/value pairs
ContentValues kvPairs = new ContentValues();
kvPairs.put("ColumnOne", myName);
kvPairs.put("ColumnTwo", myAge);
lValueToReturn = mDB.insert(TABLE_NAME_A, null, kvPairs);
return lValueToReturn;
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//this is called for first time db is created.
// put all CREATE TABLE here
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL( "CREATE TABLE "
+ TABLE_NAME_A
+ " ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "ColumnOne TEXT,"
+ "ColumnTwo TEXT"
+ ")" );
}
//this is called when an existing user updates to a newer version of the app
// add CREATE TABLE and ALTER TABLE here
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
//update SQL DB with new columns depending on old version
// also add new tables
//NOTE: whatever is done here must also go into onCreate() so that new users get the correct db created
switch(oldVersion)
{
case 1:
//EXAMPLE db.execSQL("ALTER TABLE " + TABLE_NAME_A + " ADD COLUMN ColumnThree INTEGER;");
//don't use a break. for next case simply let them run together to update all the way to latest version
//This way, the case just represents a starting point to start updating.
case 2:
//EXAMPLE db.execSQL("ALTER TABLE " + TABLE_NAME_A + " ADD COLUMN ColumnFour INTEGER;");
}
//this code drops the table and will create a fresh one. Note all data lost!
// db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_C);
// onCreate(db);
}
}
}
I've only included one example insert operation. Add more as you need them and simply make sure they are 'synchronized' methods.
Step 4 - use the SQLdataHelper in your activity
SQLdataHelper mDataHelper = SQLdataHelper.getInstance();
mDataHelper.insertTableA("Someone", 100);