How to select data from arrayList - android

I'm new to android. And I have an issue (noob question), could you help?
I have a database method getAllQuests() to fetch all records from the table into ArrayList. The code is below. I assume it works.
Next step is to fetch specific data from ArrayList. Question is: how to do this?
I assume i could use indexOf() or get(). But still i don't get how to fetch a proper row. The output is below.
So i need to put 1 row from a table into ArrayList? Or I need to use another approach?
// Getting All Quests
public List<Quest> getAllQuests() {
List<Quest> questList = new ArrayList<Quest>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_QUEST;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Quest quest = new Quest();
quest.setID(Integer.parseInt(cursor.getString(0)));
quest.setQuestName(cursor.getString(1));
quest.setQuestPlayer(cursor.getString(2));
quest.setStatus(cursor.getInt(3));
// Adding quest to list
questList.add(quest);
} while (cursor.moveToNext());
}
// return quest list
return questList;
}
// I try to figure out what to do
List<Quest> questList = db.getAllQuests();
int index = questList.indexOf(1);
Log.d(LOG_TAG, "--- index of Quest= " + index);
Log.d(LOG_TAG, "--- element of " + index + " is " + questList.get(1));
The output of that code is:
10-20 08:39:30.210 D/myLogs: --- index of Quest= -1
10-20 08:39:30.210 D/myLogs: --- element of -1 is com.homemade.saga.Quest#41b10288

You can iterate through a list of objects using the for each construct
for (Quest q: questlist) {
Log.d(LOG_TAG,"--- index of Quest= " + String.valueOf(q.getIndex));
...... etc
}
Note this assumes the getIndex getter method has been setup in the Quest class.

Related

Checking if Cursor contains row results?

I'm having a lot of trouble with checking if a cursor contains any results.
I have a method that "removes" all rows from a given table which is here:
Chevron.class
public void deleteAllRecords(){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME,null,null);
}
I then call a method which adds the SUM of the first row of the database which is here:
public Cursor getRecalculate(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select SUM (" + SECOND_FIELD + ") FROM " + TABLE_NAME, null);
return res;
}
My major issue is that if I remove all records from the database, res.getCount() still equals 1 but contains no information but then the method only returns 1 row anyway. So I'm stuck with how to check if the cursor has actual table data or just empty table data.
I've tried stuff like
if(res.getString(0) == null){
.. Do code
}
but that doesn't work.
I get the error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ceri.twostep_onecheck/com.example.ceri.twostep_onecheck.ShowGraph}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
If you want to know how many rows there are that match your query constraints, add COUNT(*) to the SELECT statement:
SELECT COUNT(*), SUM(whatever) FROM other_thing;
Then, move the Cursor to the first row via moveToFirst(), and examine the two values (getInt(0) for the count and getInt(1) for the sum).
Use getReadableDatabase() instead of getWritableDatabase().
Try this:
public Cursor getRecalculate() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select SUM (" + SECOND_FIELD + ") FROM " + TABLE_NAME, null);
return res;
}
Read cursor value:
// Move the cursor to the first row if cursor is not empty
if(res.moveToFirst())
{
do
{
// Do something with cursor
}while(res.moveToNext()); // Move cursor to next row until it pass last entry
}
// Close
res.close();
Hope this will help~
Try this
cursor.getCount();
This should return at least one if cursor reads something or it will return zero.

How to efficiently query sqlite database multiple times on Android

For my application, I need to query a sqlite database around 40-50 times. I am sure that the code I wrote is very inefficient. Unfortunately, I cannot find many examples online that involves querying the database many times.
String[] entryValArray = new String[indicesList.size()];
DBHelper dbHelper = new DBHelper(MainActivity.context);
SQLiteDatabase db = dbHelper.getReadableDatabase();
for (int i = 0; i < indicesList.size(); i++) {
int moddedIndex = Integer.parseInt(indicesList.get(i), 16) % DBHelper.numEntries;
String queryStr = "select * from " + DBHelper.TBL_NAME + " where " + DBHelper.IDStr +
" = " + Integer.toString(moddedIndex);
Cursor cursor = db.rawQuery(queryStr, null);
if (cursor.moveToFirst())
entryValArray[i] = cursor.getString(1);
cursor.close();
}
Basically, I am taking a list of strings, converting them to hex values, and then modding the value to get an index into a sqlite database. This is for a password generator application.
Is there a better way to do this, especially regarding creating a cursor and then closing it in every iteration.
First of all you have to change your query string as you need only one column value but you are using
Select *
instead of
Select yourColumn
. Secondly if your indices list size is not very large you can use
IN(values ) function of db instead of
" where " + DBHelper.IDStr +" = " + Integer.toString(moddedIndex);
this will return the result in only one query you don't have to run a whole loop.

How to set an ID to return the row position in SQlite

I would like to know, if it is possible get the row position from ID in SQLite. I have a method that return an ID when I click on listView item, but there is a gap in the IDs when I delete an item from table and the method is not effective in this case. I found this code below that returns the position row in order, but I don't know how to implement it programmatically in my class and move the cursor and to get CTN.
SELECT _id, PRODUCER,
(SELECT COUNT(*) FROM DATA B WHERE A._id >= B._id) AS CTN FROM DATA A
_id.........PRODUCER..............CTN
1............FIAT...........................1
2............FORD.........................2
3............RENAULT...................3
5............MWM..........................4
As I said, I can get the ID with a click on listView, my question is. if is possible any way to set this ID to return the position of the row. if possible show me with an example please.
thank you :)
it's working
public static long getRowFromId(Context context, int id) {
DataBase dataBase = new DataBase(context);
SQLiteDatabase conn = dataBase.getWritableDatabase();
String query = "SELECT COUNT (*) FROM " + Data.TABLE + " WHERE " + Data.ID + " <= " + id;
return conn.compileStatement(query).simpleQueryForLong();
}

Cursor Index Out of Bounds Exception: Index -1 requested with size 0

I am just trying to search for the data in multiple table.If the where condition data is not present in first table(tab1) then it has to search in the second table(tab2) but I am getting the exception showing that
Cursor Index Out of Bounds Exception: Index -1 requested with size 0
Here is my code
SQLiteDatabase db=openOrCreateDatabase("train",SQLiteDatabase.CREATE_IF_NECESSARY, null);
Cursor c1;
String[] table={"tab1","tab2","tab3","tab4"};
int i=0;
do {
c1 = db.rawQuery("select * from '"+table[i]+"' where name='Triplicane'", null);
i++;
} while(c1 == null);
int id1=c1.getInt(0);
String nam1=c1.getString(1);
Toast.makeText(fare.this,"ID no:"+id1, Toast.LENGTH_LONG).show();
Toast.makeText(fare.this,"name"+nam1, Toast.LENGTH_LONG).show();
So from the beginning. Implicitly, each Cursor is positioned before first row so if you want to work with it you need to call
cursor.moveToFirst()
that moves Cursor to first row if is not empty and then is ready for work. If Cursor is empty simply it returns false. So how i mentioned now this method is very handy indicator whether your Cursor is valid or not.
And as my recommendation i suggest you to change your code because i think is broken and it sounds like "spaghetti code"
Cursor c = null;
String[] tables = {"tab1", "tab2", "tab3", "tab4"};
for (String table: tables) {
String query = "select * from '" + table + "' where name = 'Triplicane'";
c = db.rawQuery(query, null);
if (c != null) {
if (c.moveToFirst()) { // if Cursor is not empty
int id = c.getInt(0);
String name = c.getString(1);
Toast.makeText(fare.this, "ID: " + id, Toast.LENGTH_LONG).show();
Toast.makeText(fare.this, "Name: " + name, Toast.LENGTH_LONG).show();
}
else {
// Cursor is empty
}
}
else {
// Cursor is null
}
}
Notes:
Now i want to tell you some suggestions:
An usage of parametrized statements is very good practise so in a
future if you will work with statements, use placeholders in them. Then your statements becomes more human-readable, safer(SQL Injection) and faster.
It's also a very good practise to create static final fields that will hold
your column names, table names etc. and to use
getColumnIndex(<columnName>) method to avoid "typo errors" which are looking for very bad.
Your Cursor flag to empty row , On Sqlite cursor pointed to row number -1 ,
then if you use c.moveNext() or c.moveToFirst() you'll be able to read rows "row by row "
write cursor.movetoFirst() before getting data from cursor.

Fastest way to search through strings stored in sqlite database

I have large number of strings, approximately 15,000 that I stored in a SQLite database using the following code:
void addKey(String key, String value, String table) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_KEY, key); // Contact Name
values.put(KEY_VALUE, value); // Contact Phone
// Inserting Row
db.insert(table, null, values);
db.close(); // Closing database connection
}
And then i search through that database using the following method in order to pick out any strings that match the key im looking for:
public String searchKeyString(String key, String table){
String rtn = "";
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Log.d("searchKeyString","searching");
if(cursor.getString(1).equals(key))
rtn = rtn + "," + cursor.getString(2);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
Log.d("searchKeyString","finish search");
return rtn;
}
The goal is to do this in real time as the user is typing on the keep board so response time is key and the way it stands now it takes over a second to run through the search.
I considered reading all of the items into an array list initially and sorting through that which might be faster, but i thought an array list of that size might cause memory issues. What is the best way to search through these entries in my database?
A couple of things you can do...
Change the return to a StringBuilder until the end.
Only use a readable version of the database (that's probably not making much difference though)
Do not get a new instance of the database every time, keep it opened until you don't need it anymore
Query for only what you need with the "WHERE" argument in the SQL query.
See the code below with some changes:
// move this somewhere else in your Activity or such
SQLiteDatabase db = this.getReadableDatabase();
public String searchKeyString(String key, String table){
StringBuilder rtn = new StringBuilder();
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table + " WHERE KEY_KEY=?";
Cursor cursor = db.rawQuery(selectQuery, new String[] {key});
// you can change it to
// db.rawQuery("SELECT * FROM "+table+" WHERE KEY_KEY LIKE ?", new String[] {key+"%"});
// if you want to get everything starting with that key value
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Log.d("searchKeyString","searching");
rtn.append(",").append(cursor.getString(2));
} while (cursor.moveToNext());
}
cursor.close();
Log.d("searchKeyString","finish search");
return rtn.toString();
}
Note even if you want this to happen in "real-time" for the user, you will still need to move this to a separate Thread or ASyncTask or you are going to run into problems....
You should consider using SELECT * FROM your-table LIMIT 50, for example. And you can put two buttons "Back", "Next" on your view. If every page has max 50 items, the user is at page 1, and he taps "Next", then you can use this query:
SELECT * FROM your-table LIMIT 50 OFFSET 50
If your table contains most of text-data, and you want to integrate search deeply into your app, consider using virtual table with FTS.
Let sqlite do the hard lifting.
First off, add an index to the field you're searching for, if you don't have one already. Secondly, don't do a SELECT all with manual table scan, but rather use a query in the form
SELECT column_value
FROM my_table
WHERE column_key LIKE "ABC%"
This returns the least amount of data, and the sql engine uses the index.
i dunno about better but maybe it'd be faster to make queries for the selected strings one by one.
public String searchKeyString(String key, String table){
String rtn = "";
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table + "WHERE column_1 = " + key;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
rtn = rtn + "," + cursor.getString(2);
}
cursor.close();
db.close();
Log.d("searchKeyString","finish search");
return rtn;
}
EDIT:
Well i dunno how those custom keyboard apps do it, but those AutoCompleteTextViews are hooked up to adapters. you could just as easily make a cursorAdapter and hook your auto-complete view to it.
http://www.outofwhatbox.com/blog/2010/11/android-autocompletetextview-sqlite-and-dependent-fields/
http://www.opgenorth.net/blog/2011/09/06/using-autocompletetextview-and-simplecursoradapter-2/

Categories

Resources