Build SQLite database from JSON file in runtime - is it Good? - android

I need opinion regarding rendering of data in android app. I have all the data stored in a json file abc.json which is in res > raw folder. i have a class that then reads data from that json file and build SQLite database when the app runs and later on i'm performing all operations like searching the data using sql queries for that database. But i am afraid if thats not a good option and the code is not optimized because code now contains so many functions for adding the items to database.
For example, json file has Authors, books, keywords, references, acknowledgements, subauthors and when the database is built, data is read and a specific function is called for each item. I'm just concerned because of too many functions as one for each item. Like whenever json is parsed for an item, e.g author, it calls addAuthors function to add that to database. Following are 2 of the functions for example.
//Sample function code for adding authors to db
public void addAuthors(Integer id, String Name, String is_corresponding) {
ContentValues value = new ContentValues();
value.put("_id", id);
value.put("NAME", Name);
value.put("IS__CORRESPONDING", is_corresponding);
authors_id = database.insert(TABLENAME_AUTHOR, null, value);
}
//example function for adding keywords to db
public void addKeyWord(String KeyWords, Integer id) {
ContentValues values = new ContentValues();
values.put("KEYWORDS", KeyWords);
values.put("_id ", id);
database.insert(TABLENAME_ABSTRACT_KEY_WORDS, null, values);
}
I need help with optimizing my code. Is there any way to optimize the current code ? Kindly help me with this and suggest some improvements for it. Thanks in advance

I would recommend bundling a sqlite database as an asset in your APK instead of bundling the JSON file and then inserting the data into a database. If your data isn't changing, you can then get rid of all your insert functions. You will also save the cost of creating and populating your database dynamically.
You can use the methods described here to create your database and to copy it from the assets of your APK. Be sure to copy it first before you try to open in in your app -- you can't open it directly as an asset.

Related

How to Close SQLite Cursor and other open SQLite database?

I am trying to write a code in Android and going through following errors. I am opening a SQLite database and using Cursor.
Java Code
for(int y3=0;y3<10;y3++)
{
String sql_query5= "SELECT * FROM Data WHERE Id="+y3+"";
Cursor cur5 = SQLiteDatabase.openDatabase(db, null, SQLiteDatabase.OPEN_READWRITE).rawQuery(sql_query5, null);
if(cur5.moveToNext())
{
//
}}
So i need to display the Age in the layout but i am facing SQLiteCantOpenDatabaseException and Database object not closed. I don't understand the errors.
Please let me know some solution and suggestion !!!
Do not use hard-coded file paths. You have no guarantees about the structure of the filesystem.
Learn to use SQLiteOpenHelper. This is what helps you create and maintain your SQLite database. Instead of trying to open the database yourself, you create a new SQLiteOpenHelper and call getReadableDatabase().
When you are done reading from a Cursor, call cursor.close().
If you want to close the database, you can call close() on it as well; just be aware that any cursors you got by querying it will no longer be able to give you data, so make sure you are finished them those before closing the database.
add '' in your
String sql_query5= "SELECT * FROM Data WHERE Id='"+y3+"' ";

How to write a common code for inserting data in android's Sqlite

For inserting into sqlite presently I have to follow these steps:
Create contentValues i.e. ContentValues contentValues = new ContentValues();
Put column_name and Value
lastly, call sqLiteDatabase.insert(DATABASE_NAME,null,contentValues)
Problem is only in step 2,we have manually Columnname and Columnvalue for n number of times assuming I have n Columns to persist.
So, I wrote the following method thinking I can reuse it:
public void insert(Map tableMap){
ContentValues contentValues = new ContentValues();
Iterator tableMapIterator = tableMap.entrySet().iterator();
while(tableMapIterator.hasNext()){
Map.Entry mapEntry = (Map.Entry)tableMapIterator.next();
contentValues.put((String)mapEntry.getKey(), mapEntry.getValue());
}
sqLiteDatabase.insert(DATABASE_NAME,null,contentValues)
}
But the problem is that when I call mapEntry.getValue(), the return type is Object for which contentValues.put is not defined.
So, can anyone tell me any workaround so that I can use the above approach efficiently to do the data insertion.
NOTE : I want to write method so that I can use it for all data types in SQLITE.
The objects that will access your ContentMap will be verified by this method DatabaseUtils.getTypeOfObject()
Therefore, if you put anything in your ContentValue that is not one of the expected type, it will be assumed to be a String, and in bindArguments(), toString() will be called on it.
Now, assuming that all your object are either recognized valid types, or have sufficient String representation (for instance, a File object would give its path, which is sufficient to recreate it when you extract it from the database), there are ways to put an arbitrary Map in a ContentValue.
The trivial way is to use reflection to access the internal map, which is consistently named mValues across all versions of android.
Another, shorter (but slower) and clearer way, I find, is to use the Parcel mechanism. Indeed, ContentValue.writeToParcel only writes the internal map.
The entire code is here:
Parcel parcel = obtain();
parcel.writeMap(map);
parcel.setDataPosition(0);
ContentValues values = ContentValues.CREATOR.createFromParcel(parcel);
Detailed explanation on my blog : http://njzk2.wordpress.com/2013/05/31/map-to-contentvalues-abusing-parcelable/
I am not exactly sure if i get your question but i will try my best.
1) You can use some kind of already written ORM. - It can automatically detect field types.
2) You can write your own simple ORM to handle situations like this. When i want to automatically add object to DB, i inherit this table object from GenericTableObject, which has methods like getFieldsValues, getFieldsTypes etc... With help of these methods, it is fully automated.
You will probably spend a few hours by writing this generic table object but it is usefull. - It is all about java reflection.
try this one
public void addEntity(EntityClass e) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("Name",e.getmProductName());
values.put("Price",e.getmProductPrice());
values.put("Date",e.getmPurchaseDate());
// Inserting Row
db.insert(TABLE_Accounts, null, values);
Log.d("insert", "success");
Toast.makeText(mContext, "Info added Successfully", Toast.LENGTH_SHORT).show();
db.close(); // Closing database connection
}

Where to store values to be inserted to SQLite at installation

I am new for SQLite and here is the story;
I'm developing an apk which is a kind of quiz application. I want to store the questions and answers in SQLite database. ( I am also not sure if this is the best way to store data, in SQLite )
In onCreate() method I should create the db and insert all questions, answers etc. So, I'm not sure where to put the data that will be inserted to db before insert them to db tables.
I mean;
values.put("key", "What is abc");
** insert
values.put("key", "What is def");
** insert
values.put("key", "What is ghi");
** insert
values.put("key", "What is xyz");
** insert
...
where should I get those strings (What is bla bla) to insert to table ?
If this was a windows application, I would put them in a .txt file, read from there, and insert rows.
In android, I don't know.
Thanks for any suggestions.
I am also not sure if this is the best way to store data, in SQLite
There are worse choices. :-)
In onCreate() method i should create the db and insert all questions, answers etc.
I'd prepare the database ahead of time, package it with your app, and deploy it using SQLiteAssetHelper. This would be easier to write, easier to maintain, and faster to run.
You can use this to read a text file.
Once you have that in your SQLiteOpenHelper#onCreate() method you would add your default values.
One way to do this would be:
Store the data as XML file in your res/raw folder.
Create a Parser. (DOM would work for a small file. SAX would be better if the file size is large)
Parse the data in onCreate and insert the values.
For example:
` public void onCreate(SQLiteDatabase db) {
ArrayList quizDataList;
quizDataList = ParseQuizData.getQuizData(context);
ContentValues values = new ContentValues();
try {
// Create Database
db.execSQL(TABLE_CREATE);
for (Iterator<QuizData> iterator = quizDataList.iterator(); iterator.hasNext();) {
QuizData quizData = iterator.next();
values.put(COLUMN1, quizData.getAttributeFirst());
values.put(COLUMN2, quizData.getAttributeSecond());
db.insertOrThrow(TABLE_NAME, null, values);
}
} catch (Exception e) {
e.printStackTrace();
}
`

Populate an SQLiteDatabase in Android with static data

I have a database with multiple tables. One of these tables (sport) is where i have to put a static list of object, each one with an _id, name, logo and an int. The _id will be used by other tables to do some queries (eg. select from "table X" where sport_id = _id), so it shouldn't change overtime (is there a way to update all the reference to this _id if it will change?).
Where should i put the code (i think it will be a simple list of db.insertSport()) to make it add this row only one time (and check if the row number grow, to add the new ones)?
There won't be much row, 50 at the best.
I think I would make a method in the dbHelper to insert that data, then call that method immediately upon app start. I'm making a couple of assumptions here... first that you are shipping this static info with the app and when you want to add more info you will be shipping a new version.
You could store the data as a text file in your assets folder and then read the file in execute a batch insert in the method.
If you set it up right (use insertWithOnConflict and the CONFLICT_IGNORE flag in the method) it will only add the new rows (if any) each time so you can run it every time the app starts and not worry about duplicate data or crashes for constraint violations.
If you only want it to run the once and then again when there is additional info, put a version number in the text file and check that against the previous one (which you can store in SharedPreferences).
EDIT
Example of using insertWithOnConflict:
public long createItem(String yourdata) {
ContentValues initialValues = new ContentValues();
initialValues.put(YOUR_COLUMN, yourdata);
return mDb.insertWithOnConflict(YOUR_TABLE, null, initialValues,
SQLiteDatabase.CONFLICT_IGNORE);
}
You can read up on the SQLiteDatabase class (which has the constants and methods) here

How to store bulk questions in android sqlite db?

I am working on quiz application. In my project I need to store huge number of questions to display on the screen. How can I do that? I have downloaded the sqlite browser and when I tried to import .sql file it is displaying error. Also I have kept the .sql file in assets folder in eclipse.
How to store those questions into my sqlite db?
The thing is that even if you port the .sql file to the assets folder in eclipse its not going to work like that when you are going to use it in a real android mobile rather that an emulator by using the final .apk file.
One method what i did was to enter all the entries using a method. In order not to do this at each load, i check if the number of entries is the same else i drop the table and then enter it new once again. Thats the option that i know of. Maybe there are better options. But this works for sure.
public long createValue(int semester, String subname, int credits)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_SEMESTER, semester);
initialValues.put(KEY_SUBNAME, subname);
initialValues.put(KEY_CREDITS, credits);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}
Create a method like the above to enter the values and then call this method with the values to enter. So you can just have n number of calls to this method with the values to enter.
mDb is a SQliteDatabase object
Maybe this will help you out.

Categories

Resources