Insert data to sqlite database from json parsing - android

I want to insert data to sqLite database in Android data parsing form json array data.
My code is as follow:
1) DBHelperClass - database creation
public class DueAmountDataBHelper extends SQLiteOpenHelper {
public DueAmountDataBHelper(Context context) {
super(context, "abc.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_PRODUCT_DUE_AMT =
"create table due_amt_tab(" +
"shopId text primary key, " +
"shopName text NOT NULL, " +
"teluguName text NOT NULL, " +
"place text NOT NULL, " +
"dueAmount text NOT NULL " +
")";
db.execSQL(CREATE_TABLE_PRODUCT_DUE_AMT);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public List<DueAmtDBModel> getShopdata() {
List<DueAmtDBModel> data = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("select * from due_amt_tab", null);
StringBuffer stringBuffer = new StringBuffer();
DueAmtDBModel dataModel = null;
while (cursor.moveToNext()) {
dataModel = new DueAmtDBModel();
String shopId, shopName, teluguName, place, dueAmount;
shopId = cursor.getString(cursor.getColumnIndexOrThrow("shopId"));
shopName = cursor.getString(cursor.getColumnIndexOrThrow("shopName"));
teluguName = cursor.getString(cursor.getColumnIndexOrThrow("teluguName"));
place = cursor.getString(cursor.getColumnIndexOrThrow("place"));
dueAmount = cursor.getString(cursor.getColumnIndexOrThrow("dueAmount"));
dataModel.setShopId(shopId);
dataModel.setShopName(shopName);
dataModel.setTeluguName(teluguName);
dataModel.setPlace(place);
dataModel.setDueAmount(dueAmount);
stringBuffer.append(dataModel);
data.add(dataModel);
}
return data;
}
}
to this table i need to insert this json data
APi - http://demo4896782.mockable.io/shops
[
{
"shopName": "Hello World.",
"shopTeluguName": "శరవాన గుడ్డు పంపిణీదారులు",
"shopAddress": "Bomanahalli",
"previousDues": 0,
"shopID": 1
},
{
"shopName": "Hello World.",
"shopTeluguName": "శరవాన గుడ్డు పంపిణీదారులు",
"shopAddress": "Bomanahalli",
"previousDues": 20,
"shopID": 2
},
{
"shopName": "Hello World.",
"shopTeluguName": "శరవాన గుడ్డు పంపిణీదారులు",
"shopAddress": "Bomanahalli",
"previousDues": 400,
"shopID": 3
}
]
Thank you in advance.

The code below assumes you can parse the json data from the server.
public void insert(JsonObject jsonObject){
ContentValues values = new ContentValues();
SQLiteDatabase db = this.getWritableDatabase();
values.put("shopName", jsonObject.getString('Hello World'));
values.put("shopTeluguName", jsonObject.getString('shopTeluguName'));
values.put("shopAddress", jsonObject.getString('shopAddress'));
values.put("previousDues", jsonObject.getString('previousDues'));
values.put("shopID", jsonObject.getString('shopID'));
db.insert("YOUR TABLE NAME", null, values);
}
Now simply iterate over the JSON Array and call this function in the loop

First of all, the table structure should be:
CREATE TABLE IF NOT EXISTS "TABLE_NAME" + "(" + JSON_STRING_KEY + " TEXT ")
Now, make a model class for the json-array you're getting from api.
Now, to insert this json-array in the table, you can do something like this:
void insertJsonArrayAsStringToTable(ArrayList<Model> modelList) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, null, null); // delete previous data
ContentValues contentValues = new ContentValues();
// array list as a string; or you can directly put the string you got from
// onResponse(String response) of your volley StringRequest--if you're using it
contentValues.put(JSON_STRING_KEY, new Gson().toJsonTree(modelList).toString());
db.insert(TABLE_NAME, null, contentValues);
db.close();
}
Until now, we have the json-array data from the api stored in the table as a string.
Now, we can use a query to retrieve the string from table and again use Gson to convert it into an object( here, an ArrayList of Model):
public ArrayList<Model> loadData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("SELECT * FROM " + TABLE_NAME, null); // now where-clause, so we simply use null as an argument
res.moveToFirst();
ArrayList<Model> modelList= null;
while (!res.isAfterLast()) { // traverse the table
Type listType = new TypeToken<ArrayList<Model>>() {
}.getType();
modelList= new Gson().fromJson(res.getString(res.getColumnIndex(JSON_STRING_KEY)), listType);
res.moveToNext();
}
res.close();
db.close();
return modelList;
}
PS: How you manage to store other possible responses coming from api into the db, totally depends on you, whether make separate tables or something like that.

Related

Structuring an SQLite database to separate readable/writeabale data

I'm writing an app that will allow users to read short stories that are stored in an SQLite database.
So far so good.
But now I want to add features that involve writing to the database (saving the Y location of a ScrollView so the user can pick up where they left off, bookmarking stories, etc).
Should I add these values to the books table, or should I create a separate table user_settings with columns like id (int), story_id (int), y_position (int), bookmarked (boolean)?
Note: I'm also thinking ahead to the possibility of storing stories on a non-local database in the future.
My other question is: do I need to move the database somewhere to be able to write to it? I'm using SQLiteAssetHelper and the database is currently at /assets/databases/database.db. I'm hearing some talk of a /data/data/mypackage folder but I can't see it in my project.
My database setup is currently as follows:
authors
id
name
name_alphanumeric
books
id
title
author_id
collection
body
If it's useful, here's my DatabaseHelper so far:
public class DatabaseHelper extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "database9.db";
private static final String BOOKS = "books";
private static final String AUTHORS = "authors";
public DatabaseHelper (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// setForcedUpgrade();
}
// Getting all books
public ArrayList<Author> getAllAuthors() {
ArrayList<Author> authorList = new ArrayList<>();
// Select all query
String selectQuery = "SELECT id, name FROM " + AUTHORS + " ORDER BY name_alphabetic";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
// create new author object
Author author = new Author();
// set ID and name of author object
author.setID(Integer.parseInt(cursor.getString(0)));
author.setName(cursor.getString(1));
// pass author object to authorList array
authorList.add(author);
} while (cursor.moveToNext());
}
// return author list
return authorList;
}
// Getting all stories
public List<Book> getAllStories(int authorID) {
List<Book> storyList = new ArrayList<>();
// Select all query
String selectQuery = "SELECT id, title FROM " + BOOKS + " WHERE author_id = " + authorID;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Book book = new Book();
book.setStoryID(Integer.parseInt(cursor.getString(0)));
book.setTitle(cursor.getString(1));
storyList.add(book);
} while (cursor.moveToNext());
}
// return contact list
return storyList;
}
// Get all collections
public List<Book> getAllCollections(int authorID) {
List<Book> collectionsList = new ArrayList<>();
// Select all query
String selectQuery = "SELECT DISTINCT collection FROM " + BOOKS + " WHERE author_id = " + authorID;
Log.i("stories", selectQuery);
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Book book = new Book();
book.setCollection(cursor.getString(0));
// Log.i("stories", cursor.getString(0));
collectionsList.add(book);
} while (cursor.moveToNext());
}
return collectionsList;
// not sure how to log collectionsList here
}
// Get story
public String getStoryBody(int storyID) {
// Log.i("stories", Integer.toString(storyID));
String storyBody = "";
// String storyBody();
// Select all query
String selectQuery = "SELECT body FROM " + BOOKS + " WHERE id = " + storyID;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
storyBody = cursor.getString(0);
} while (cursor.moveToNext());
}
return storyBody;
}
public int setScrollPosition(int scrollY, int storyID) {
String insertQuery = "UPDATE " + BOOKS + " SET scroll_position = " + scrollY + " WHERE id = " + storyID;
Log.i("insert", insertQuery);
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL(insertQuery);
return 0;
}
public int getScrollPosition(int storyID) {
int scrollPosition = 0;
String selectQuery = "SELECT scroll_position FROM " + BOOKS + " WHERE id = " + storyID;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
scrollPosition = cursor.getInt(0);
} while (cursor.moveToNext());
}
return scrollPosition;
}
}
But now I want to add features that involve writing to the database
(saving the Y location of a ScrollView so the user can pick up where
they left off, bookmarking stories, etc).
Should I add these values to the books table, or should I create a
separate table user_settings with columns like id (int), story_id
(int), y_position (int), bookmarked (boolean)?
I think you have made it clear that they are USER values, so it is very likely that a separate user table would be the better more manageable solution.
My other question is: do I need to move the database somewhere to be
able to write to it? I'm using SQLiteAssetHelper and the database is
currently at /assets/databases/database.db. I'm hearing some talk of a
/data/data/mypackage folder but I can't see it in my project.
In all likeliehood the database has been copied from the assets folder into data/data/yourpackage/databases/dbfilename by SQLiteAssetHelper (as I understand that's primarily what it's for. However I've never used it.) Such folders have limited access (normally only the Application (rooted device an exception)) so that could well be why you can't see it.
As such there is likely nothing required in the way of permissions for writing to/updating the database.

Deleting data from SQLite Database is not working

I am working with SQLite and I am having trouble deleting data.
First and foremost, this is how I add data to the database:
public void addRecipe (QueryVars Recipee){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_Recipe, Recipee.getRecipe());
db.insert(TABLE_Recipes, null, values);
db.close();
}
And this is how I get data from the database:
public List<QueryVars> getAllBooks() {
List<QueryVars> recipes = new LinkedList<QueryVars>();
String query = "SELECT * FROM " + TABLE_Recipes;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
QueryVars Recipe = null;
if (cursor.moveToFirst()) {
do {
Recipe = new QueryVars();
// Recipe.setId(Integer.parseInt(cursor.getString(0)));
Recipe.setRecipe(cursor.getString(1));
recipes.add(Recipe);
} while (cursor.moveToNext());
}
return recipes;
}
Saving and querying for data is working perfectly fine, but when I try to delete rows with the following code it just doesn't work.
public void deleteRecipes(QueryVars Recipe) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_Recipes, KEY_ID + " = ?", new String[] { String.valueOf(Recipe.getId()) });
db.close();
}
This is the query I use to create the table:
private static final String CREATE_BOOK_TABLE =
"CREATE TABLE Recipes ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "Recipe TEXT"
+ ")";
And the constants I use in my code above are defined like this:
private static final TABLE_Recipes = "Recipes";
private static final String KEY_ID = "id";
private static final String KEY_Recipe = "Recipe";
private static final String[] COLUMNS = {KEY_ID,KEY_Recipe};
There are two issues in your code which could potentially be the source of the error, but both have the same cause: You are letting SQLite generate the ids of your Recipe objects but you are never setting that id to your objects.
When you add something to the database the add() method returns the id which was generated for that row. You can just set this id to the Recipe object otherwise that Recipe object won't have an id until you reload it from the database.
public void addRecipe (QueryVars Recipee){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_Recipe, Recipee.getRecipe());
final long id = db.insert(TABLE_Recipes, null, values);
Recipee.setId(id);
db.close();
}
When you are reading the Recipe objects from the database you are not setting the id value on the object, so no Recipe object you read from the database has an id which means you cannot delete them from the database. The fix is again pretty simple:
public List<QueryVars> getAllBooks() {
List<QueryVars> recipes = new LinkedList<QueryVars>();
String query = "SELECT * FROM " + TABLE_Recipes;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
final int idIndex = cursor.getColumnIndex(KEY_ID);
final int recipeIndex = cursor.getColumnIndex(KEY_Recipe);
QueryVars Recipe = null;
if (cursor.moveToFirst()) {
do {
Recipe = new QueryVars();
Recipe.setId(cursor.getLong(idIndex));
Recipe.setRecipe(cursor.getString(recipeIndex));
recipes.add(Recipe);
} while (cursor.moveToNext());
}
return recipes;
}
This uses getColumnIndex() to reliably get the correct index of each column and then reads the id and the recipe from the cursor and sets them to the Recipe object.
Please note that your Recipe object needs to have a long id! int ids are not compatible with the SQLiteDatabase!
You don't capture the database-generated id of your recipes and the id is zero. It doesn't match any rows in the delete.
Uncomment the
// Recipe.setId(Integer.parseInt(cursor.getString(0)));
(consider using cursor.getInt() instead)
Possibly also store the return value of insert() as the recipe id.

How to put and get the current date by using simple database

I'm a beginner and don't know how to insert and get the current date by using database.
For an insert into the database, I use a button for adding the information. Here is the full code:
public void Badd_Click(View view) {
db.execSQL("INSERT INTO Demo (event, venue, amount, textView) VALUES ('" + tEvent.getText().toString() + "'," + "'" + tLocation.getText().toString() + "'," + "'" + tAmount.getText().toString() +"' )");
Toast.makeText(this, "Create record successfully...", Toast.LENGTH_SHORT).show();
}
Then, for showing the information inserted into the database, I also use a button:
public void Btnshow_Click(View view){
String str = "";
Cursor c = db.rawQuery("SELECT * FROM "+DATABASE_TABLE,null);
c.moveToFirst();
for(int i = 0; i<c.getCount();i++){
str+="ID: "+c.getString(0)+"\n";
str+="Name : "+c.getString(1)+"\n";
str+="Location : "+c.getString(2)+"\n";
str+="Amount : "+c.getString(3)+"\n\n";
c.moveToNext();
}
I have searched for many solutions, but I am unable to do it successfully.
Please help :(
You can use below two methods to save and retrieve date from database in the format you want.
public static String getDbDateString(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
return sdf.format(date);
}
public static Date getDateFromDb(String dateText) {
SimpleDateFormat dbDateFormat = new SimpleDateFormat("yyyyMMdd");
try {
return dbDateFormat.parse(dateText);
} catch ( ParseException e ) {
e.printStackTrace();
return null;
}
}
You can get current date with below code:
Date date = new Date(System.currentTimeMillis());
To add to database:
public void addDate() {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("key", "value");
// Inserting Row
db.insert(table_name, null, values);
db.close(); // Closing database connection
}
To read from database:
public Date getDate(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(table_name,
new String[]{column_id,
column_date_value},
column_id + "=?",
new String[]{String.valueOf(id)}, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
assert cursor != null;
return new Date(cursor.getString(index_column_date));
}

Retrieving String Data incorrectly SQL Lite - Android

I am facing a problem when retrieving string types from my SQL Lite Db. When ever I store my Strings into the SQL Lite DB, the Strings store correctly, However when I try to retreive these Strings, it returns more than what I stored. If this is confusing here is my code db.storeNames(EVENTNAMES);
(EVENTNAMES is a List)
public void storeNames(List<String> names)
{
SQLiteDatabase db = this.getWritableDatabase();
for(int i = 0; i < names.size(); i++) {
ContentValues values = new ContentValues();
values.put(KEY_LABEL, names.get(i)); // Info Name
db.insert(TABLE_INFO, null, values);
// Closing database connection
}
Log.i("DB MESSAGE ", names.size() + " NAMES STORED");
db.close();
}
Then I retrieve
eventName = db.getEventName();
And here is the corresponding DB code.
public List<String> getEventName() {
List<String> nameList = new ArrayList<String>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_INFO;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(1);
nameList.add(name);
}
while (cursor.moveToNext());
Log.i("POSITION ", " NAMES "+ cursor.getPosition() + " RETRIEVED");
}
db.close();
// return info list
return nameList;
}`
Why is it retrieving more than it is supposed too. The Log message from the getNames() method prints out "NAMES (3x Number it should be) Retrieved.
**EDIT**
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main)
EVENTNAMES.add("EVENT 1");
EVENTNAMES.add("EVENT 2");
EVENTNAMES.add("EVENT 3");
EVENTNAMES.add("EVENT 4");
EVENTNAMES.add("EVENT 5");
db.storeNames(EVENTNAMES);
}
When the activity is opened multiple times for the same database, new events are added to any existing events already stored in the database.
If you want to replace all events in the database, you must delete any old ones before storing the new ones.

how to apply filters in inserting data to sqlite in android

I have created an application to insert data to sq-lite . i want if i enter same data again it should give e toast massage and then it only update that data not re-insert.
what should i do.....
now data is been re-inserted
method code of SQLiteOpenHelper.....
public void insertdata(String name,String ph,String area){
ContentValues cv=new ContentValues();
cv.put("name", name);
cv.put("phone", ph);
cv.put("area", area);
sd=this.getWritableDatabase();
sd.insert("location", null, cv);
sd.close();
method use in Activity class......
public void onClick(View v) {
// TODO Auto-generated method stub
help=new MyHelper(getApplicationContext());
help.getWritableDatabase();
String myname=name.getText().toString();
String call=phone.getText().toString();
String myarea=area.getText().toString().trim();
help.insertdata(myname, call, myarea);
Toast.makeText(getApplicationContext(), "data saved ", Toast.LENGTH_SHORT).show();
}
});
The data is being reinserted because you're methods never check to see if it already exists in the databse. You need to add a query for some unique combination - probably name and phone number. If that query returns a result you can prompt the user to enter the data.
String query = "SELECT * FROM " + TABLE_NAME + " WHERE name = " + name;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
if(cursor != null && cursor.moveToFirst()){ //if cursor has entry then don't reinsert
//prompt user with dialog
} else {
//insert data
}
Also you cannot use a Toast for this. What you want is a Dialog. If the data exists you can display a custom Dialog to the user that you could use to allow them to (1) enter new data (2) edit existing data (3) choose to reinsert the data they are posting. A Toast will just display a message to them like - "reinserting data". It does not sound like that is the functionalty you want to achieve.
To update the database you can just use an update statment depending on what fields you want to change.
String query = "UPDATE " + TABLE_NAME + " SET";
if(!name.isEmpty(){
query += " name = " + name;
}
if(!phone.isEmpty(){
query += " phone = " + phone;
}
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL(CREATE_CONTACTS_TABLE)
I put the if statments in to check for which fields are being changed and add them to the query accordingly. In the alternative you could use something like this
public int updateContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, contact.getName());
values.put(KEY_PH_NO, contact.getPhoneNumber());
// updating row
return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
new String[] { String.valueOf(contact.getID()) });
}
While I havnet modified it to fit your example you can see the basic approach. Hhere you can use conditionals to check if values are being supplied, if they are you add them to the ContentVlues list which will update them in the DB.
You can try something like this:
ContentValues values=new ContentValues();
cv.put("name", name);
cv.put("phone", ph);
cv.put("area", area);
if (db == null) {
db = getWritableDatabase();
}
if (isNameExists(name)) { //check if name exits
id = db.update(TABLE_NAME, values, name + " = ?",
new String[] {name});
} else {
id = db.insert(TABLE_NAME, null, values);
}
public boolean isNameExists(String name) {
Cursor cursor = null;
boolean result = false;
try {
String[] args = { "" + name };
StringBuffer sbQuery = new StringBuffer("SELECT * from ").append(
TABLE_NAME).append(" where name=?");
cursor = getReadableDatabase().rawQuery(sbQuery.toString(), args);
if (cursor != null && cursor.moveToFirst()) {
result = true;
}
} catch (Exception e) {
Log.e("AppoitnmentDBhelper", e.toString());
}
return result;

Categories

Resources