I am writing an app that displays fun-facts (and the source they are from). The user can browse through the facts one by one.
Here is the design I thought of :
Create a table in SQLiteDatabase with a text column that stores the fun-fact and a second column that stores it's source. (not sure if this is the best way to go about doing it, but I want the app available even without the network)
My question is, when database is initially created on the device, should I manually populate the database from within the code, something like this pseodo-code:-
#Override
public void onCreate(SQLiteDatabase db) {
//Create the table
//Populate the table
//Insert statement 1
//Insert statement 2
//Insert statement 3
...
//Insert statement 500
}
Surely there must be a better method to create the initial database when the app is installed?
Are you certain that you really need a databse? Doesn't it just add unnecessary overhead to something so trivial?
Can't you just declare the array in your code, or am I missing something? Whether it's in the db or your code, it is taking up space. The db will add some overhead to that and vious?will take some time to load, plus your code has to handle errors, etc.
Woudl you not be better off with a simple array declared in your code? Or am I misisng something obvious? (maybe users can d/l a new db? But is that so much more overhead than d/ling a new program?)
If I'm way off, please explain (rather than downvoting). I am trying to help
Edit: presumably you already have your facts soemwhere? Maybe in a text file? You could just write code to parse that and initialze and array (or populate a db). It should bascially be a short for loop.
use a class derived from SQLiteOpenHelper
i already wrote sth obout this on my blog www.xenonite.net
public class myDatabase extends SQLiteOpenHelper
{
private static final String DB_NAME = "database.db";
private static final int DB_VERSION = 1;
public MyDatabase(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE tbl_test ( id INTEGER PRIMARY KEY AUTOINCREMENT, test TEXT NOT NULL )");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS tbl_test");
onCreate(db);
}
}
you can use this like
myDatabase db = new myDatabase(getApplicationContext());
sql = "INSERT INTO tbl_test (test) VALUES ('xyz')";
db.getWritableDatabase().execSQL(sql);
String sql = "SELECT id FROM tbl_test";
Cursor result = db.getWritableDatabase().rawQuery(sql, null);
int value;
while(result.moveToNext())
{
value = result.getInt(0);
}
on every call to db, myDatabase.onCreate() is called, so your database will be created on the first run. when changing the table structure, implement onUpgrade() and increment DB_VERSION
Related
I am currently working on a diet app in android. So, I have planned to have a food database which could store information like calories, protein, fats, carbohydrates of food items. I don't know how to use SQL databases, that's why please tell me how can i use that data....for ex - if user searches for a food, say apple, in a search bar then how could the nutritional information of apple could be displayed.
Please provide me the source code for doing that...if you still feel confused about my question see the "myFitnessPal" android app and how the entries are made in that.
If you know any kind of references i could use kindly suggest.
Thanks in advance.
Here is a link that provides the details you need: http://developer.android.com/training/basics/data-storage/databases.html
I can't provide any code for you, as you have to think of what features your app should have and according to that you have to build up a database structure. But basically in your code you open a database which is then represented as a SQLiteDatabase object in your code. You can then run sql queries on the database with the execSQL function.
That's a lot of code to show to get something basic working. I would suggest following Vogella's SQLite Tutorial to get you started.
One thing in this tutorial that stumped me was he seemed to suggest that you need a SQLiteOpenHelper for each table. In fact what he meant was the SQLiteOpenHelper is for a single database and you would have a separate static class for each table where you would do something like:
public class MyDatabaseHelper extends SQLiteOpenHelper {
...
#Override
public void onCreate(SQLiteDatabase database) {
MyTable.onCreate(database);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
MyTable.onUpdate(db, oldVersion, newVersion)
}
}
The MyTable class contains the methods to create and update the database for that specific table.
public class MyTable {
private static final String TABLE_NAME = "example";
private static final String COLUMN_ID = "id";
private static String DATABASE_CREATE = "CREATE TABLE " + TABLE_NAME + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY)";
public static void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
...
}
In my already created and deployed application, I've created a database MainDB, using a single class file which extended SQLiteOpenHelper, viz.
public class BaseSQLiteOpenHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAME = "MainDB";
....
....
}
Issue is I've tied this class, too much to a particular functionality.
Now I'm adding a totally new module in application, which will also interact with DB, but with different new tables.
Issue is I can't use the same class, as it is conflicting in more than one way. And even if I redesign the code, it will only add complexity from functional/understanding point of view.
So, I've decided to use same DB, but different tables.
Now I've already created DB in BaseSQLiteOpenHelper class.
So, how can I create new tables in seprate class using same DB?
One approach is to use separate Database as well, Or,
Create my new table in onCreate() in BaseSQLiteOpenHelper class only (issue with this is mentioning new table in same class seems awkward, as this class has nothing to do with my new table).
Please suggest.
Thank You
First check the current database version for this database
private final static String DATABASE_NAME = "MainDB";
private static final int DATABASE_VERSION = 1;
public BaseSQLiteOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
and increment the database version(DATABASE_VERSION), and add your new table query in on Upgrade and oncreate method like below.
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("old query no need to change");
db.execSQL("Create your new table here");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
db.execSQL("Create your new table here as well this for update the old DB");
}
}
Done!!!
Is it possible to delete any existing data set by a previous install of same app (databse tables and shared preferences etc) when the app is re-installed?
I have an app that stores some values in sqlite database, if the app is re-installed without prior properly uninstalling. I face problems from previous database entries etc.
If uninstalling the app didn't do the stuff try this :
System Parameters -> Manage Applications -> Your Application -> Clear data
If you click on the button (Clear data) you will see a dialog which shows you what kind of data will be cleared.
Edit:
If you want to do that programmatically, you can :
Change database version in the super method of the constructor:
super(context, DATABASE_NAME, null, NEW_DB_VERSION);
Add a drop statement before creating tables.
database.execSQL("DROP TABLE IF EXISTS your_table");
database.execSQL(" CREATE TABLE your_table ...");
Proceed to a hard drop of the database:
this.context.deleteDatabase(YOUR_DATABASE_NAME;
Its very Simple.
First Delete the table using drop query
sdb.execSQL("DROP TABLE IF EXISTS tablename");
and then again use the create table query
sdb.execSQL(" CREATE TABLE tablename(col1 TEXT PRIMARY KEY)");
or
delete the DB file using file explorer in path data->data->package->databases->dbname
update the Database version to greater value in the OpenHelper, it will automatically drop all the tables in database and recreate them.
For shared preferences.. you can clear them from the OpenHelper when onUpgrade is called.
Like Ankit Popli said, Using version is the right way to go:
public class Database extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "YourDBName.db";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// ALl the deletion operation here.
db.execSQL("DROP TABLE IF EXISTS "+Database.TABLE);
onCreate(db);
}
}
AndroidSqlite will automatically call onUpgrade function when the version number is incremented. Do all the database deletion there.
I have an application in which i am trying to create a Database. On the first run the application works properly. Subsequent launch of the application it crashes. The error is because the application is trying to create the db again.
So i want to know how to create a database or tables only if they dont exists or only if the application is run the first time.
You can extend the class SQLiteOpenHelper to handle different versions of your database. Here is an example:
public class MyDbOpenHelper extends **SQLiteOpenHelper** {
final static int VERSION = 2;
public MyDbOpenHelper(Context context, String dbname) {
super(context, dbname, null, VERSION);
}
#Override
public void **onCreate**(SQLiteDatabase db) {
/* TODO SQL-Queries for new Database */
}
#Override
public void **onUpgrade**(SQLiteDatabase db, int oldVersion, int newVersion) {
/* SQL-Queries t*/
if (oldVersion < 2) {
db.execSQL("ALTER TABLE my_table ADD COLUMN new_attrubte INTEGER");
}
}
}
Handle of database is new in onCreate and if it exist, onUpgrade is called with existing version number in oldVersion parameter.
SQLite has a CREATE TABLE IF NOT EXISTS command. You could try that.
It is usually an error to attempt to create a new table in a database that already contains a table, index or view of the same name. However, if the "IF NOT EXISTS" clause is specified as part of the CREATE TABLE statement and a table or view of the same name already exists, the CREATE TABLE command simply has no effect (and no error message is returned). An error is still returned if the table cannot be created because of an existing index, even if the "IF NOT EXISTS" clause is specified.
My DBHelper class
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context)
{
super(context,"SIMPLE_DB",null,1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE SIMPLE_TABLE ( " +
"ID INTEGER PRIMARY KEY " +
"DESC TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Activity class
public class SimpleDatabase extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this);
SQLiteDatabase db = dbHelper.getReadableDatabase();
db.execSQL("INSERT INTO SIMPLE_TABLE VALUES (NULL, 'test');");
Cursor cursor = db.rawQuery("SELECT * FROM SIMPLE_TABLE", null);
TextView text = (TextView)findViewById(R.id.textbox);
text.setText(cursor.getString(0));
}
}
I figure it crashed (application has stopped unexpectedly!) at SQLiteDatabase db = ... because if I commented the code out from there to the end then it worked fine. But I have no idea whatsoever why it does that.
Any help would be appreciated.
Never mind, figured out what I did wrong now.
db.execSQL("CREATE TABLE SIMPLE_TABLE ( " + "ID INTEGER PRIMARY KEY<comma goes here> " + "DESC TEXT);");
Commas are serious businesses. Sorry for the stupid question.
first of all you should ensure that your SQL statement is correct. If sqlite3 is in your path you could execute the command:
$>: sqlite3 testdb.db
after that you are in an shell where you can test your SQL statements if there are syntactically correct. (Hint: refering the example above: it is not correct).
After that you should handle your cursor correctly as described by Aurora.
Maybe you should implement your onUpgrade() method, e.g:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS SIMPLE_TABLE");
onCreate(db);
}
First, to help in your debugging, make sure to use the debug monitor and Log. This will make your life a lot easier in the long run! If you are using Eclipse, select Window -> Open Perspective -> Other -> DDMS. The LogCat will show you what is happening as the program is run. Documentation describes it here. Run your program again and watch the LogCat. It should give you more information and tell you what line of code is crashing.
As far as your code goes, the first thing I notice is that after you get a cursor back, you need to call cursor.moveToFirst(); to select the (first) row. Then when you call cursor.getString(0);, it indicates the zeroeth column of the zeroeth row. If you do not call moveToFirst(); then you cursor.getString(0) is going to get the zeroeth column of the -1st row and be an index out of bounds error. By default, the cursor will start at row -1.
Depending on how you want to move through your cursor, and how many results/rows you get back, you may also need to call cursor.movetoPosition() or cursor.moveToNext(). Check out the documentation on cursors here.