Retrieving String Data incorrectly SQL Lite - Android - 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.

Related

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.

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.

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.

How can I use primary key instead of name in query for fetching data for a particular row?

This code works, but the query is based on name. How can I use primary key instead of name without showing the primary key in listview?
This code is in my database file:
public ArrayList<String> data() {
ArrayList<String> ar = new ArrayList<String>();
ArrayList<String> av = new ArrayList<String>();
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query(helper.TABLE_NAME, new String[] {helper.NAME,helper.DATE,helper.PEOPLE}, null, null, null, null,null );
c.moveToFirst();
do {
String db_name = c.getString(c.getColumnIndex(helper.NAME))+ " " + c.getString(c.getColumnIndex(helper.DATE))+" "+c.getString(c.getColumnIndex(helper.PEOPLE));
ar.add(db_name);//only ar will be show in listview
c.moveToNext();
} while (!c.isAfterLast());
return ar;
}
and The Activity code is:
lv = (ListView) findViewById(R.id.listView1);
ar = helper.data();
ArrayAdapter<String> ad = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, ar);
lv.setAdapter(ad);
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
String s = parent.getItemAtPosition(position).toString();
String k = "";
String p[] = s.split(" ");
for (int i = 0; i < p.length-7; i++)
k = k + " " + p[i];
k = k.trim();//k contains the name string
Intent i = new Intent(getApplicationContext(), Details.class);
i.putExtra("name", k);//next activity will fetch all the details with the help of name.
startActivity(i);
}
}
Your question isn't very clear to me. But if its what I think you want to do, you can try something like this, this fetches a book in the database based on its ID (the primary key)
public Book getBook(int id){
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TABLE_BOOKS, // a. table
COLUMNS, // b. column names
" id = ?", // c. selections
new String[] { String.valueOf(id) }, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
Book book = new Book();
book.setId(Integer.parseInt(cursor.getString(0)));
book.setTitle(cursor.getString(1));
book.setAuthor(cursor.getString(2));
//log
Log.d("getBook("+id+")", book.toString());
// 5. return book
return book;
}
Source
which was set using:
// SQL statement to create book table
String CREATE_BOOK_TABLE = "CREATE TABLE books ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"title TEXT, "+
"author TEXT )";
How can I use primary key instead of name without showing the primary key in listview?
Aren't you supposed to be in charge of what you show in your ListView?

Categories

Resources