get dat from cursor to arraylist - android

I have a table with 10 columns.
String createQuery = " CREATE TABLE IF NOT EXISTS profile (
_id integer primary key autoincrement,
name text,
longi real,
lati real,
vibration integer,
sound integer,
brightness integer,
mdata,
bluetooth,
wifi);";
How can I get all table data in an ArrayList?

You need to do a few things. You need to create a sub-class of SQLiteDatabase. Once you have that, you can get run a query inside a method in this class like this:
Cursor cursor = getReadableDatabase().query("profile", // table name
new String[] { // columns
"_id",
"name",
"longi",
"lati",
"vibration",
"sound",
"brightness",
"mdata",
"bluetooth",
"wifi"
},
null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Long id = cursor.getLong("_id");
String name = cursor.getString("name");
// and so on, list of your columns you want to get.
cursor.moveToNext();
}
Obviously you won't be able to put one whole row into an array list because you have different column types. But you can process one row at a time inside the while loop after you get all the values.
Most of this info is taken from here, which is a great source of info:
http://www.vogella.com/articles/AndroidSQLite/article.html

Related

How to search for a number with a parameter?

I have two tables, created by the following statements:
create table maintable (_id integer primary key, name)
create table foreigntable (_id integer primary key, object, foreign key (object) references maintable(_id)
I'd like to query foreigntable for all items referencing a specific object in maintable. Let's say the id of interest in maintable is stored in objectId.
Why does the following code return no results?
Cursor dataCursor = database.query("foreigntable", null, "object=?", new String[] { Long.toString(objectId)}, null, null, null);
I get results with the following query:
Cursor dataCursor = database.rawQuery("select * from foreigntable where object=" + objectId, null);
What also works:
Cursor dataCursor = database.query("foreigntable", null, "object="+objectId, null, null, null, null);
"object=?", new String[] { Long.toString(objectId)}
This code compares the values in the object column against a string.
This comparison will always fail because numbers are not strings.
While using parameters is a good idea in general, Android's database API allows nothing but strings, and when you have a number, you should insert it directly into the SQL query string.

Android SQLite Join Query

I'm creating an app as a learning tool and am having difficulty with join queries.
I have a database with two tables- horses and covers- declared as follows;
private static final String HORSES_CREATE = "create table horses (_id integer primary key autoincrement, "
+ "name text not null, type integer not null, birthDate text not null, vaccineDate text not null, "
+ "inFoal integer not null, notes text not null);";
The 'type' field refers to stallion, mare, gelding etc and is selected from a spinner (populated from an XML String array).
private static final String COVERS_CREATE = "create table covers (_id integer primary key autoincrement, "
+ "stallionName integer not null, mareName integer not null, firstCoverDate text not null, lastCoverDate text not null, "
+ "scan14Date text not null, scan28Date text not null, foalingDate text not null, inFoal integer not null, notes text not null);";
stallionName is actually stored as the _id field of the horse from the horse table. It is selected from a spinner that only displays horses whose type defined as 'Stallion' in the horses table. (The same applies for Mare).
I have a class 'DatabaseHelper' to create and upgrade the tables, and each table has its own adapter class 'horsesDbAdapter' and 'coversDbAdapter' that contains the methods to add, edit and delete entries, and relevant queries. (fetchAllHorses(), fetchHorse(long rowId) )
eg:
public Cursor fetchAllHorses() {
return mDb.query(DATABASE_TABLE,
new String[] { KEY_ROWID, KEY_NAME, KEY_TYPE, KEY_BIRTHDATE,
KEY_VACCINEDATE, KEY_INFOAL, KEY_NOTES }, null, null,
null, null, null);
}
(It's all adapted from the Android notepad example)
I have the contents of the covers table displayed in a listview (just showing the stallionName and mareName). But as those fields just contain the unique reference to the horses table all that is displayed is the fairly uninformative _id field.
My question is; how can I get the relevant name for the horses to display in the listView? I've read up on join queries etc but get lost when I try implement them. I assume I have to join on horses._id and covers.stallionName (then make an almost-identical one for MareName) but I can't find a concrete example of how to do this.
Please let me know if any additional information/ code is needed.
Any help would be greatly appreciated, thankyou in advance.
EDIT:
I have made stallionName and mareName foreign keys referencing (_id) in the horses table, but am still unsure how and where to implement the join query; should it be in the horsesDbAdapter, coversDbAdapter or the coversList class? (coversList is the class that creates and populates the listView)
The covers table declaration now reads;
private static final String COVERS_CREATE = "create table covers (_id integer primary key autoincrement, "
+ "stallionName integer not null, mareName integer not null, firstCoverDate text not null, lastCoverDate text not null, "
+ "scan14Date text not null, scan28Date text not null, foalingDate text not null, inFoal integer not null, notes text not null," +
"FOREIGN KEY (stallionName) REFERENCES horses (_id), FOREIGN KEY (mareName) REFERENCES horses (_id));";
I'm a newbie to Android and SQLLiteHelper and was wondering about the same thing.
After reading this post, I found that the method to define joins between tables is done with the SQLLiteQueryBuilder.setTables method. See the reference here
I got this from this blog
Hope this helps pointing readers in the right direction.
I've managed to get it working. For anyone else who may have a similar problem I'll try detail what I did.
As #deceiver stated I should have made stallionName and mareName foreign keys referencing horses (see Edit).
In the coversList class (the class that implements the listView) I just needed to get an instance of the database and use a rawQuery to implement the SQL code directly (It may be possible to do it with Query but I'm not sure how)
The added code is as follows;
private Cursor coversCursor;
private void fillData() {
db = (new DatabaseHelper(this).getReadableDatabase());
coversCursor = db.rawQuery("SELECT horses1.name AS stallionNameText, covers.*, horses2.name AS mareNameText FROM horses horses1 JOIN covers ON horses1._id = covers.stallionName JOIN horses horses2 ON horses2._id = covers.MareName",
null);
startManagingCursor(coversCursor);
// Create an array to specify the fields we want to display in the list
// (the renamed fields from the above query)
String[] from = new String[] { "stallionNameText", "mareNameText" };
// and an array of the fields we want to bind those fields to (in this
// case just text1)
int[] to = new int[] { R.id.rowStallionName, R.id.rowMareName };
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter covers = new SimpleCursorAdapter(this,
R.layout.covers_list_row, coversCursor, from, to);
setListAdapter(covers);
}
FillData() is then called in the onCreate() method. Then just close the db in the onDestroy method.
(Selecting all columns from the covers table seems wasteful here but I will eventually show these columns in the listView aswell. I just wanted to answer this before continuing coding).
A tutorial I found helpful was http://coenraets.org/blog/android-samples/androidtutorial/
I had issues with the SQL query as there are 2 foreign keys referencing the same table and I wanted the listView to display both the stallion name and mare name, so had to join two horses table to a covers table. I just needed to rename the tables in the FROM section of the SQL query. Hopefully the above code is clear. If not, I found the following useful; http://www.bryantwebconsulting.com/blog/index.cfm/2005/3/11/join_a_table_to_itself_in_sql
Sorry if this explanation is too specific to my (unusual) example.
Thanks for reading.

NOT NULL columns in SQLite and error catching

I have a database that is being filled by user defined EditTexts. None of the edit texts should allow empty fields. I know that I can check for this with a couple simple if-statements: if myEditText.getText().toString().equals("") // display error. However I would perfer to use this opportunity to brush up on my SQLite and error catching (as demonstrated in my add method). How would I go about altering the columns in the table below to NOT NULL and generating/catching an error when a user attempts to add/update with empty fields?
My database table:
db.execSQL("CREATE TABLE inventory (category TEXT, itemNum TEXT, quantity INTEGER, price REAL, image INTEGER, UNIQUE(category, itemNum) ON CONFLICT FAIL);");
My add method:
... fill ContentValues values
try{
db.getWritableDatabase().insertWithOnConflict(DatabaseHelper.TABLE_NAME, DatabaseHelper.CATEGORY, values, SQLiteDatabase.CONFLICT_FAIL);
fillItemNumbers();
}
catch(SQLiteConstraintException e)
{
Toast
.makeText(MyActivity.this, etItemNum.getText().toString() + " already exists in " + catSpinner.getSelectedItem().toString() +". Consider using Update.",Toast.LENGTH_LONG)
.show();
}
My update method:
... fill ContentValues values
String[] args = {catSpinner.getSelectedItem().toString(), etItemNum.getText().toString()};
int rowsAffected = db.getWritableDatabase().update(DatabaseHelper.TABLE_NAME, values, DatabaseHelper.CATEGORY + "=? AND " + DatabaseHelper.ITEM_NUMBER + "=?" , args);
UPDATE:
I did a little digging and came up with this:
db.execSQL("CREATE TABLE inventory (category TEXT NOT NULL, itemNum TEXT NOT NULL, quantity INTEGER NOT NULL, price REAL NOT NULL, image INTEGER NOT NULL, UNIQUE(category, itemNum) ON CONFLICT FAIL);");
Is this what I am looking for? If so, how can I use this to my advantage (see above)?
I am not sure if you can actually Alter Column Definition for table. I know you can Alter Table itself, like adding new Column to Table. You might need little trick to modify your database if there is lot of data in it that you want to preserve.
One way to it to create new table and try copying data to new table and afterwards remove old table and rename new Table. It's not most efficient way to do it but it'll get the job done though.
http://www.sqlite.org/lang_altertable.html
EDIT
Here you go
CREATE TABLE inventory (category TEXT not null, itemNum TEXT not null, quantity INTEGER not null, price REAL not null, image INTEGER not null, UNIQUE(category, itemNum) ON CONFLICT FAIL);
EDIT 2
Try this
CREATE TABLE inventory (category TEXT not null ON CONFLICT FAIL, itemNum TEXT not null ON CONFLICT FAIL, quantity INTEGER not null ON CONFLICT FAIL, price REAL not null ON CONFLICT FAIL, image INTEGER not null ON CONFLICT FAIL, UNIQUE(category, itemNum) ON CONFLICT FAIL);
All you need to do is set the columns to NOT NULL.
Then use
insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm)
and
updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)`
There are several constants you can use for the conflictAlgorithm, depending on exactly what you want to happen. If you want to simply not enter the data into the table, CONFLICT_IGNORE will do the trick. If you want a return code letting you know so you can act on it (let the user know) then you might want CONFLICT_FAIL.
See this for further information.
Hope this helps.

Android SQLite Repeated Elements

I have an issue with SQLite on android. Right now, I'm pulling a JSON object from a server, parsing it, and putting each sub-object in a Table with things such as the Name, Row_ID, unique ID, etc. using this code:
public void fillTable(Object[] detailedList){
for(int i=0;i<detailedList.length;++i){
Log.w("MyApp", "Creating Entry: " + Integer.toString(i));
String[] article = (String[]) detailedList[i];
createEntry(article[0], article[1], article[2], article[3], article[4], article[5]);
}
}
createEntry does what it sounds like. It takes 6 strings, and uses cv.put to make an entry. No problems.
When I try to order them however, via:
public String[] getAllTitles(int m){
Log.w("MyApp", "getTitle1");
String[] columns = new String[]{KEY_ROWID, KEY_URLID, KEY_URL, KEY_TITLE, KEY_TIME, KEY_TAGS, KEY_STATE};
Log.w("MyApp", "getTitle2");
Cursor c = ourDatabase.query(DATABASE_TABLENAME, columns, null, null, null, null, KEY_TIME);
Log.w("MyApp", "getTitle3");
String title[] = new String[m];
Log.w("MyApp", "getTitle4");
int i = 0;
int rowTitle = c.getColumnIndex(KEY_TITLE);
Log.w("MyApp", "getTitle5");
for(c.moveToFirst();i<m;c.moveToNext()){
title[i++] = c.getString(rowTitle);
Log.w("MyApp", "getTitle " + Integer.toString(i));
}
return title;
}
Each entry actually has many duplicates. I'm assuming as many duplicates as times I have synced. Is there any way to manually call the onUpgrade method, which drops the table and creates a new one, or a better way to clear out duplicates?
Secondary question, is there any way to order by reverse? I'm ordering by time now, and the oldest added entries are first (smallest number). Is there a reverse to that?
If you don't want duplicates in one column then create that column with the UNIQUE keyword. Your database will then check that you don't insert duplicates and you can even specify what should happen in that case. I guess this would be good for you:
CREATE TABLE mytable (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
theone TEXT UNIQUE ON CONFLICT REPLACE
)
If you insert something into that table that already exists it will delete the row that already has that item and inserts your new row then. That also means that the replaced row gets a new _id (because _id is set to automatically grow - you must not insert that id yourself or it will not work)
Your second question: you can specify the direction of the order of if you append ASC (ascending) or DESC (descending). You want DESC probably.
Cursor c = ourDatabase.query(DATABASE_TABLENAME, columns, null, null, null, null, KEY_TIME + " DESC");

Android: SQLite, small issue with inserting and query

I am developing my first application which contains an SQLite database, containing table ANIMAL which has the columns _id, animal_name, animal_bio.
The user is presented with animal names in a ListView; selecting an animal will bring him/her to a page where he/she can view the animals bio.
The problem I'm having is:
When I add the bio of each animal to the DB - no errors.
However, running the app causes the ListView (previously working) to display a blank screen.
My Insertion code:
public long populateDB(){
ContentValues initialValues = new ContentValues();
long[] rowIds = new long[animalName.length];
// Populate the animal table
for(int i = 0; i < animalName.length; i++){
initialValues.put(KEY_ANIMALNAME, animalName[i]);
initialValues.put(KEY_BIOGRAPHY, bio[i]);
rowIds[i] = qmDB.insert(ANIMAL_TABLE, null, initialValues);
}
return rowIds[0];
}
And the create database statement
private static final String DATABASE_CREATE =
"create table " + ANIMAL_TABLE +
" (_id integer primary key autoincrement, " +
"animal_name text not null, " +
"biography text not null);";
I cannot see anything wrong with this code, so if anyone has any suggestions, I'd be very grateful.
EDIT: Retrieving animals code
public Cursor retrieveAnnimals(){
return qmDB.query(ANIMAL_TABLE, new String[] {
KEY_ROWID,
KEY_ANIMALNAME,
},
null,
null,
null,
null,
ORDER_BY_NAME);
}
Calling the create and insert from application, this takes place in the ListActivity, called ListAnimals:
dbm = new MyDBManager();
dbm.open();
dbm.deleteTable();
dbm.populateTable();
myCursor = dbm.retrieveAnimals();

Categories

Resources