How can I use more than one table in SQLiteAssetHelper? - android

I am using SQLiteAssetHelper dealing with database to realize selection, inserting and updating. But I need more than one database; can I put all the databases' method in one class? I tried, but the error is cannot find my second table. Thank you.

What do you mean by all the databases method in one class?
You can't have a single Helper class for multiple databases. Each database is represented by one single Helper. Then, you can create another class that takes an helper in its constructor and create methods using it.
EDIT
For each table you want to use, you need to create a class that extends SQLiteAssetHelper.
public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "northwind.db";
private static final int DATABASE_VERSION = 1;
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
Use a different name for each table in the DATABASE_NAME variable.
Then use the helper corresponding to the table you want to read or write to as normal. There is samples here: http://developer.android.com/training/basics/data-storage/databases.html#ReadDbRow

Related

App doesn't show database changes with SQLite Asset Helper

I'm writing an app that comes packaged with an SQLite database.
I'm in the process of gradually adding to the database, but when I compile the code in Android Studio the app doesn't see the latest update to it.
The workaround I've found is changing the filename of the database and updating it in the code, but that's going to get very tiresome if I'm making frequent updates, and I feel there must be a better way.
For what it's worth, here's the relevant code snippet:
public class DatabaseHelper extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "database5.db";
private static final String BOOKS = "books";
private static final String AUTHORS = "authors";
public DatabaseHelper (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// etc
}
You need to increment the version number then use the setForcedUpgrade(). Something like this:
private static final int DATABASE_VERSION = 2;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// call this method to force a database overwrite every time the version number increments:
//setForcedUpgrade();
}
You can found the details in the sample project.
when I compile the code in Android Studio the app doesn't see the latest update to it
SQLiteAssetHelper only copies the database out of assets if the database does not already exist.
I feel there must be a better way
If you are not modifying the database at runtime, and if you plan on distributing updates to that database in the form of fresh assets, you can use setForcedUpgrade(), as is covered in the documentation.
Otherwise, you can uninstall the app when you change the database, or clear the app's data in Settings when you change the database.
Just change your sqlite database file name from asset folder
[here i have change name Quran.db to Quran1.db]
And from class where you have access it.
[from class also i have changed Quran.db to Quran1.db]
This method worked fine for me.

Android SQLiteAssetHelper Can't upgrade read-only database from version 1 to 2:

I want to create an offline dictionary app, that need sometimes to get update and old database will be replaced by new one. It's what I want to do, and I did something like this with SQLiteAssetHelper Library:
Note: SQLiteAssetHelper will copy database from assets folder into app data folder
public class MyDb extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "db.sqlite";
private static final int DATABASE_VERSION = 1;
public MyDb(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
now i want to update database, after puting new db.sqlite file into assets folder, I have manipulate my codes like this:
public class MyDb extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "db.sqlite";
private static final int DATABASE_VERSION = 2;
public MyDb(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
but when i compiled and run, it says: Can't upgrade read-only database from version 1 to 2
what is the solution?
by clearing app data, it will works fine...
SORRY FOR MY BAD ENGLISH...
Quoting the documentation:
If you have a read-only database or do not care about user data loss, you can force users onto the latest version of the SQLite database each time the version number is incremented (overwriting the local database with the one in the assets) by calling the setForcedUpgrade() method in your SQLiteAsstHelper subclass constructor.
You can additionally pass an argument that is the version number below which the upgrade will be forced.
Note that this will overwrite an existing local database and all data within it.
You are not calling setForcedUpgrade() from your constructor.
You should call setForcedUpgrade(); after your Constructor :
public class MyDb extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 2;//+1
public MyDb(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
setForcedUpgrade();
}
}
Please note that deleting the old db and creating new one in onUpgrade is not the right solution. Older data has to be migrated. Incase you are not interested in maintaining older data ov version 1, it is alright.
Right way is to use onUpgrade to modify the schema. Most of the time altering the schema required recreating table. In such cases follow below approach
rename existing table (say table_xyz) to be altered to some temp
name (say temp_table_xyz)
create the table (table_xyz) with new schema
copy the contents from temp table temp_table_xyz to the
new table_xyz
It's solved by this:
#Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion != newVersion) {
context.deleteDatabase(DATABASE_NAME);
new MyDb(context);
}else
super.onUpgrade(db, oldVersion, newVersion);
}
It's very useful for some database that we don't need old data when getting update.

correct use of SQLiteOpenHelper (and some consultation)

I have the following code below.
I am creating a database in my application that uses SQLiteOpenHelper.
I have couple of concerns and would appreciate some consults.
Direct answers for these were not found on stack overflow as they might be subjective.
1 - I will be using this database from several activities. However I am not planning on making this a singleton to avoid leaks, but rather I will be getting the getWritableDatabase() and getReadableDatabase() inside each method. I plan on doing a db.close() inside each activity's onDestroy() .Is this advisable ? given my app has couple of activites and is not a huge app.
2 - I am not following and DAO model, nor I am using a different class for every table.
The way I see it, I don't need to. Do I ?
3 - (A question rather than consult)
In the code below, I am not creating a database of the form
private SQLiteDatabase database;
So all the references to the database (from my activities) are being done via the methods in the same subclassed SQLiteOpenHelper, therefore I am referencing the physically created database directly via getWritableDatabase and getReadableDatabase.
Do I need to create an instance of SQLiteDatabase and use it ? Even inside the subclass of SQLiteOpenHelper ?
Below is the code.
public class DbHelper extends SQLiteOpenHelper
{
private static final String DATABASE_NAME = "myDbName";
private static final String DATABASE_TABLE = "myTable";
private static final int DATABASE_VERSION = 1;
private Context ctx;
public DbHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.ctx = context;
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE myTable(_id INTEGER PRIMARY KEY, title TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
//nothing here now. maybe later.
}
public void insertTitle(String title)
{
ContentValues titleCV = new ContentValues();
titleCV .put("title", title);
getWritableDatabase().insert(DATABASE_TABLE, null, titleCV );
}
public void getTitles()
{
Cursor result = getReadableDatabase().rawQuery("SELECT _id, title FROM myTable", null);
while (result.moveToNext())
{
int id = result.getInt(0);
String titleGotten= result.getString(1);
}
result.close();
}
Q1
If you have a scenario within your app that have two parallel threads accessing the database, use a single instance of the SQLiteOpenHelper (singleton or member in the Application or whatever). If not you don't need to.
about calling db.close(), if it is in the onDestroy(), then it's fine.
Q2
a DAO is an abstraction layer to ease maintaining and scaling your project. If you are not going to scale or maintain your code (upcoming releases or something), then I suppose you don't need one.
Q3
You don't need to create an instance of SQLiteDatabse. when you call getReadableDatabase() or getWritableDatabase(), SQLiteOpenHelper creates and maintains an instance. The same instance is used the next time you call getReadable\WritableDatabase().
let me know if you still have questions.
step 1: make a staic instace of SqliteOpenHelper
step 2: you never close conexion to database, sqlite manage itself the sequencial access to write or read :)
private static ControladorBBDD instancia;
my class: public class ControladorBBDD extends SQLiteOpenHelper {
default :
private ControladorBBDD(Context ctx_p) throws Exception {
super(ctx_p, DB_NAME, null, DATABASE_VERSION);
try {
ControladorBBDD.ctx = ctx_p;
DB_PATH = ctx.getDatabasePath(DB_NAME).getAbsolutePath();
String myPath = DB_PATH;// + DB_NAME;
this.createDataBase();
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException ex) {
Conexiones.escribirLog(Log.getStackTraceString(ex),
ctx.getString(R.string.versionReal));
db.close();
}
}
and my way to implement a conexion to database:
public static synchronized ControladorBBDD getBBDD(Context ctx_p)
throws Exception {
if (instancia == null) {
instancia = new ControladorBBDD(ctx_p);
}
return instancia;
}
and to call it from activities:
dblectura = ControladorBBDD.getBBDD(getApplicationContext());
where private ControladorBBDD dblectura;
i hope that it helps, important thing is that you use applicationContext, no Activity context ;))
well if i were u i would create a class and the dbhelper as a subclass then i would use a open and a close function for main class and also the insert
whenever i want to use database i do it like this
mainclass mc=new mainclass(this);
mc.open();
mc.insert();
mc.close();

Android multiple ContentProviders with same database name throws 'no such table' exception

When using same database name for multiple ContentProviders, query fails with exception thrown as 'no such table'.
I researched the reference, and books, the Internet discussions, but could not find resolution.
I noticed that all the ContentProviders fail except the one ContentProvider declared first in the manifest. So I gave unique database name and the exception goes away. It works but it's weird to have multiple single-table databases.
I want to figure out why the problem occurs if possible. Below is my implementation in essence.
All ContentProviders have separate SQLiteOpenHelper defined as inner private class. DATABASE_NAME and DATABASE_VERSION are all the same.
public class TheFirstProvider extends ContentProvider {
private static final String DATABASE_NAME = "dbname.db";
private static final int DATABASE_VERSION = 1;
private SQLiteOpenHelper dbHelper;
#Override
public boolean onCreate(){
mContext = getContext();
dbHelper = new FirstDbHelper(mContext, DATABASE_NAME, null, DATABASE_VERSION);
}
private class FirstDbHelper extends SQLiteOpenHelper {
...
private static final String DATABASE_CREATE_FIRST = ... ;
#Override
public void onCreate(SQLiteDatabase db){
db.execSQL(DATABASE_CREATE_FIRST);
}
}
Check your Create table statement and verify if it was correctly executed and see if the table you are using on the query has the exact same name as the one created. Sometimes a little mistake on the DDL (create statement) lead to problems like this that happens silently.
I also suggest you to install this eclipse plugin to visualize the database on your emulator so you can see the tables you have created and check if it's what you've expected.
private class FirstDbHelper extends SQLiteOpenHelper{
public FirstDbHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String query="Your Query";
db.execSQL(query);
}
Set your Code as below.It will Work.

SQLite Database in android

Hii everybody ,
I am noob at android and need some help...
I am developing an app which requires me to write to an SQLiteDatabase in one activity and access it from another activity . I am facing a problem implementing this. Any suggestions/ideas as to how we can share the database across multiple activities ...?
I'd recommend you to use the SQLiteOpenHelper class.
Simply use the same database name consistently across your activities, it should not cause any problem.
SQLiteOpenHelper helper = new SQLiteOpenHelper(
context, R.string.db_name, null, 1);
SQLiteDatabase db = helper.getWritableDatabase();
The issue of accessing the same database two different activities can be handled in a few different ways.
The simplest, which should work for your case, is to create a new class that extends SQLITEOpenHelper and instantiate that class from both activities.
Android has no problem with multiple Activities or processes accessing the SQlite database simultaneously.
Simply you can make a common Class for DataBase and use it by creating object.
public class DbOperation extends SQLiteOpenHelper{
public static final String name="mydb.db";
public static final String MainTab="MainTab";
public static final String ID="_ID";
public static final String LevelName="LevelName";
int version =2;
public DbOperation(Context context, String name, CursorFactory factory,
int version) {
super(context, name,null, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
String str="CREATE TABLE "+MainTab+"("+ID+" integer primary key autoincrement,"+LevelName+" text not null unique key)";
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Use this data base in any activity in below way
DbOperation ob=new DbOperation ();
SQLiteDatabase db=new SQLiteaDatabase();
db=ob.getWritableDataBase();
and now you can use operation like query,delete,update
Cursor cur=db.query(Table_name,null,null,null,null); etc

Categories

Resources