Deleting data from SQLite Database is not working - android

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.

Related

How to customize Room Database Query results that we can achieve in normal SQLite Open helper class

In Room database we write queries as DAO to get results from database. In normal SQLite OpenHelper class we can customize the query results as per our need.
public ArrayList<MyData> getMyData(String id) {
ArrayList<MyData> entries=new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + MYDATA + " WHERE " + ID + " = ?";
Cursor c1 = db.rawQuery(query, new String[]{id});
List<String> business=new ArrayList<>();
if(c2.moveToFirst()){
MyData entry=new MyData();
entry.setId(c2.getString(0));
String dataValue=c2.getString(1);
String val="";
if(dataValue.contains("__")){
String[] valueSplit =dataValue.split("__");
if(valueSplit[0]!=null){
val=address[0];
}
}else{
val="";
}
entries.add(entry);
}
return entries;
}
In this query, results obtained from Database is customized based on some condition, added in ArrayList MyData object and then final result is returned. How it can be done in Room Database
If i understand your question correctly you can use #query in your DAO like this
#Query("SELECT * FROM MYDATA WHERE id = :id")
public ArrayList<MyData> getMyData(String id);
Then in your database view model expose getMyData(String id) and process your data

Insert data to sqlite database from json parsing

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.

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.

Android SQLite: Spinner + select sql methods

I have a Spinner which is showing SQLite data. For that I am using this select method:
public List<String> getAllProductsName(int id)
{
String buildSQL = "SELECT nome FROM " + DatabaseHelper.Produtos.TABELA + " WHERE id =" + id;
List<String> nomes = new ArrayList<String>();
SQLiteDatabase db = this.getDatabase();
Cursor cursor = database.rawQuery(buildSQL, null);
if (cursor.moveToFirst()) {
do {
nomes.add(cursor.getString(0));
} while (cursor.moveToNext());
}
return nomes;
}
The thing is, I am getting only the names but I need the ID as well. I know i could use "SELECT nome, _id FROM ", but how would I return that? Could i possibly return 2 lists (one with IDS and the other one with the Names) in the same method?
Or maybe I should create a new method that show the Names only (when i give the ID as a parameter)? Please help! thanks in advance! :)
How about something like this ... using and returning HashMap that contains ID as keys and nome as values
public HashMap<Integer,String> getAllProductsName(int id)
{
String buildSQL = "SELECT nome,_id FROM " + DatabaseHelper.Produtos.TABELA + " WHERE id =" + id;
HashMap<Integer,String> idAndNomes = new HashMap<Integer,String>();
SQLiteDatabase db = this.getDatabase();
Cursor cursor = database.rawQuery(buildSQL, null);
if (cursor.moveToFirst()) {
do {
idAndNomes.put(cursor.getInt(1), cursor.getString(0)));
} while (cursor.moveToNext());
}
return idAndNomes;
}
Then you can use:
idAndNomes.keySet() - Returns a set of the keys contained in this map. In our case ID.
idAndNomes.values() - Returns a collection of the values contained in this map. In our case nomes.

Get data from database Android

I have a page which can retrieve user data from database
but after whole day of trying, I am only able to get the table column name but not the value inside.
this is my code to create database
public static final String LASTLOGIN = "lastuser";
public static final String USER_ID = "suser_id";
public static final String USER_NAME = "suser_name";
public static final String USER_PASSWORD = "spassword";
public static final String PRIME_ID = "id";
private static final String TABLE_USER =
"create table "+ LASTLOGIN+" ("
+PRIME_ID+" integer primary key autoincrement, "
+ USER_ID + " text, "
+ USER_NAME +" text, "
+USER_PASSWORD+" text); ";
and here is the function implemented to get user data
public Cursor getuser()
{
String[] columns = new String[]{PRIME_ID, USER_NAME, USER_PASSWORD};
Cursor cursor = sqLiteDatabase.query(
LASTLOGIN, columns, null, null, null, null, PRIME_ID +" DESC");
Log.d("TAG", columns[1]);
return cursor;
}
and here is my code to display the result
mySQLiteAdapter = new SQLiteAdapter(this);
mySQLiteAdapter.openToWrite();
cursor = mySQLiteAdapter.getuser();
String[] resultvalue = new String{
SQLiteAdapter.PRIME_ID,SQLiteAdapter.USER_NAME, SQLiteAdapter.USER_PASSWORD};
Toast.makeText(this, resultvalue[0]+resultvalue[1], Toast.LENGTH_LONG).show();
and the toast result only show the column name but not the value inside, is there any mistake i made? and I want to set limit to 1, but where to set it?
Thanks for helping me
the way you try reading the values is completly wrong.
you create an array
String[] resultvalue = new String[]{
SQLiteAdapter.PRIME_ID,
SQLiteAdapter.USER_NAME,
SQLiteAdapter.USER_PASSWORD};
after that you read the values 0 and 1 from this array.
Your toast works absolutly correctly becouse inside this array you define the column names!
If you want to show the values from your query do it this way:
while(cursor.moveToNext()){
Integer str1 = str 1 + cursor.getInteger(1);
String str2 =str2 + cursor.getString(2);
Toast.makeText(this, str1 + str2, Toast.LENGTH_LONG).show();
}
or a better way receiving the correct index:
cursor.getInteger( cursor.getColumnIndex(SQLiteAdapter.PRIME_ID) );
cursor.getString( cursor.getColumnIndex(SQLiteAdapter.USER_NAME) );
Please note when retrieving data from a database, you store it in a Cursor in the memory and hence can only access it using that particular Cursor object, which you have used in the following line of code.
Cursor cursor = mySQLiteAdapter.getuser();
The Following line retrieves the column names and not the values.
String[] resultvalue = new String[]{SQLiteAdapter.PRIME_ID,SQLiteAdapter.USER_NAME, SQLiteAdapter.USER_PASSWORD};
So the following is doing what you have asked it to do, retrieve column names not values
Toast.makeText(this, resultvalue[0]+resultvalue[1], Toast.LENGTH_LONG).show();
You need something like following:
if(cursor.getCount() != 0)
{
while(cursor.moveToNext())
{
resultvalue [0] = csr.getString(0);
resultvalue [1] = csr.getString(1);
//....
}
}
Hope this helps
here is my solution:
final String TABLE_NAME = "table_name";
String selectQuery = "SELECT Column FROM "+TABLE_NAME+" WHERE column='"+some_value+"'";
SQLiteDatabase db = this.openDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String[] data = new String[cursor.getCount()];;
int i = 0;
if (cursor.moveToFirst()) {
do {
i=Integer.parseInt(cursor.getString(cursor.getColumnIndex("value")));
} while (cursor.moveToNext());
}
cursor.close();

Categories

Resources