Using MergeCursor and a SimpleCursorAdapter, What's Missing? - android

No matter what I do, the following throws an error that one of the columns contained in the cursor_counterparty does not exist. When I checked the merge_cursor, I can find the column in there, here's my code, what am I doing wrong?
cursor_invoices = Invoices.getInvoicesCursor(counterparty.getId());
Cursor cursor_counterparty = Counterparties
.getCounterpartyCursor(counterparty.getId());
startManagingCursor(cursor_invoices);
startManagingCursor(cursor_counterparty);
/* Joins cursors akin to doing an SQL join */
MergeCursor merge_cursor = new MergeCursor(new Cursor[] {
cursor_invoices, cursor_counterparty });
merge_cursor.moveToFirst();
int[] listview_columns = new int[] { R.id.textview_invoice_number,
R.id.textview_counterparty_name, R.id.textview_amount,
R.id.textview_account_name, R.id.textview_invoice_date,
R.id.textview_date_paid };
String[] listview_fields = new String[] { App.INVOICENUMBER,
App.COUNTERPARTYNAME, counterparty_amount_field,
App.ACCOUNTNAME, App.INVOICEDATE, App.DATEPAID };
SimpleCursorAdapter cursor_adapter_invoices = new SimpleCursorAdapter(
this, R.layout.listview_invoice_item, merge_cursor,
listview_fields, listview_columns);
The error I get is:
java.lang.IllegalArgumentException: column 'counterparty_name' does not exist
When I debug the App, I can see 'counterparty_name' as a column in one of the cursors in the merge_cursor.
Any help would be great, thanks!

Are you wanting to join the cursors vertically (adding rows) or horizontally (adding columns)?
This is theory, as I haven't peeked at the code, but it makes sense to me...
MergeCursor concatenates cursors vertically (fact), one after another. So for part of the cursor you have one set of columns and for the other you have a different set of columns (supposition).
Your adapter is trying to find a column that doesn't exist in one portion or the other for the row being displayed.
If you changed to a CursorJoiner, which concatenates the columns, I think it would work more like you expect, although how you would line up the rows appropriately I don't know.
A good explanation here
EDIT
I see you use the same ID to fetch each cursor, so my concern about lining them up is irrelevant. I think you do want CursorJoiner rather than MergeCursor.

Related

SQLite how to sum the values of column in `GridView`

I've had a look around and found a few similar cases but none where there is a need for specificity in the entries to sum. So here I am.
I have a method filterPayments that returns all entries in my PayTable based on a specific GroupID and is then displayed in my GridView. From there I want to sum the values of 2 of the 5 columns in PayTable, specifically my Interest and Due columns. I'm not sure how to do this in a query, let alone do it only for specific columns.
Question
How do I add the values of all entries in a specific column.
Is it possible to do this in a SQLite query? If so how do I use the returned value of filterPayments and perform the summation only on specific columns? If it isn't then how can I do this?
Below are my code snippets.
filterPayments
Cursor filterPayments(String Payment) {
SQLiteDatabase db = this.getWritableDatabase();
String[] columns = new String[]{"_id", colGroupID, colPayBal, colInterest, colDue, colDateDue, colPaid};
Cursor c = db.query(viewPmnts, columns, colGroupID + "=?", new String[]{Payment}, null, null, null);
return c;
}
GridView
public void Paygrid() {
dbHelper = new DatabaseHelper(this);
String Payment = String.valueOf(txt.getText());
Cursor a = dbHelper.filterPayments(Payment);
startManagingCursor(a);
String[] from = new String[]{DatabaseHelper.colPayBal, DatabaseHelper.colInterest, DatabaseHelper.colDue, DatabaseHelper.colDateDue, DatabaseHelper.colPaid};
int[] to = new int[]{R.id.Amount, R.id.Interest, R.id.Due, R.id.DateDue, R.id.Paid};
SimpleCursorAdapter saa = new SimpleCursorAdapter(this, R.layout.paygrid, a, from, to);
intgrid.setAdapter(saa);
}
I suggest pulling all the data from column and then sum them in Java or android. That would be the simplest way.
There are no core sqlite functions that does it.
https://www.sqlite.org/lang_corefunc.html
You can however create custom sqlite functions. Look below.
How to create custom functions in SQLite
I hope I get your question right. But if you have two columns with the column names interest and due you can get the sum of both columns with the SQL query
SELECT interest + due FROM PayTable;
This also applies for multiplication (and its inverse counterparts). Unfortunately it gets more tricky for non-integer exponentiation (like square root). As far as I know, you need the already mentioned own SQLite function. If you are lucky you can load a module wrapping the math.h from the C standard lib (search for extension-functions.c)
For other ways of summing in tables look at this question for PostgreSQL (It's the same for SQLite)

Queue SUM of SQLite column - android

I have a listview populated from an SQLite database. I have several items that I successfully populate into the listview, however I'm having trouble with one last thing.
I'm trying to queue the sum total of the column KEY_CONTENT6 which is a string type, however it only contains numbers. I'd like to keep it as a string, so to add it up I'm using Double.valueOf(). The problem is this code force closes on queue and I cant figure out whats wrong:
public Cursor queueAll(){
String[] columns =
new String[]{KEY_ID, "sum("+ Double.valueOf(KEY_CONTENT6) +")",
KEY_CONTENT9, KEY_CONTENT10 };
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns,
null , null, KEY_CONTENT10, null, KEY_CONTENT9+ " DESC");
return cursor;
}
simply use SUM, no need to use anything else..
String[] columns =
new String[]{KEY_ID, "sum(KEY_CONTENT6)",
KEY_CONTENT9, KEY_CONTENT10 };
It is valid for SQLite. Because, no matter what you set data type in SQLite, it stores values as string. So, type conversion is somewhat built-in in SQLite.
You can't use java in a SQL statement, either stick to strait sql or iterate over the cursor and use java to do your calculation.
You can find everything there is to know about sqlite here http://www.sqlite.org/docs.html
SQLite is basically typeless, so you might be able to use SUM on your column even though it is a string. However, if it's meant to be a numeric column, why not give it a number type??

Android Multiple SimpleCursorAdapter

I'm working on a little App which works with a SQLite Database... i'm showing a picture (green, yellow or red) which depends on a priority.
i have 3 priorities (high, medium and low...) and i'm getting those cursors as following:
cursorh = dbAdapter.fetchAllHighPrio();
cursorm = dbAdapter.fetchAllMedPrio();
cursorl = dbAdapter.fetchAllLowPrio();
Then i'm calling some other stuff like this:
startManagingCursor(cursorh);
startManagingCursor(cursorm);
startManagingCursor(cursorl);
String[] from = new String[] { TodoDbAdapter.KEY_SUMMARY };
int[] to = new int[] { R.id.label };
SimpleCursorAdapter noteh = new SimpleCursorAdapter(this,
R.layout.todo_row_high, cursorh, from, to);
SimpleCursorAdapter notem = new SimpleCursorAdapter(this,
R.layout.todo_row_med, cursorm, from, to);
SimpleCursorAdapter notel = new SimpleCursorAdapter(this,
R.layout.todo_row_low, cursorl, from, to);
so then i have all of my stuff prepared to show on my list... but if i use setListAdapter i can only use 1 of them. since i have 3 different layouts with the different cursors, this is really pretty hard to do.
How can i get all those 3 SimpleCursorAdapters to show in my list now?
EDIT: Maybe i wasnt clear enough... All of this data is in only one table... but since i have 3 different layouts (because of the different priority colors) i need to add them seperately... or is there any other way of just saying like if the priority equals 'high' put this image in layout so i only need one SimpleCursorAdapter?
You can create a VIEW that would combine data from all 3 tables + an extra column to tell which table the data came from. Then you query from it and return appropriate row Views in a custom CursorAdapter.
To my knowledge, you would be unable to attach more than one adapter to a ListView. Unfortunately, I think you may need to approach this in a little different way.
You could stick with one adapter and make sure your sorting is correct in your database query.
You could create one adapter and loop through each cursor, adding items to that single adapter (probably not a Cursor Adapter but more like an ArrayAdapter).
You could, I suppose, Use a LinearLayout with 3 ListViews weighted to 1 each and have 3 separately scrolling lists on the screen at one time...
Depending on how you actually want the application to work, there could be several different approaches.

Android question: When using SimpleCursorAdapter, how can I format one of the columns

I'm trying to create a list that is mapped to a database query, however, one of the fields in the database is a timestamp which when displayed should be displayed as a date like "Wednesday, March 2" instead of the actual value in the database which is something like 1299517239487...
I can solve this by rephrasing the query or by decorating the cursor after I do the query, but I would much rather have the simple cursor adapter display this column in that specific way.
Does anyone have any idea on how to do it?
some code:
// the desired columns to be bound
String[] columns = new String[] { DBHelper.COL_START_TIME, DBHelper.COL_AMOUNT};
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.dayMonthDate, R.id.amount};
// create the adapter using the cursor pointing to the desired data as well as the layout information
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.single_activity,cursor, columns, to);
I would like to be able to add some kind of post processor to the adapter in order to fix that.
Thanks!
You can use the setViewBinder() method of SimpleCursorAdapter to have a ViewBinder manually set the values for the views but that will get called for every column.

Displaying results of a SQL join in a ListActivity

I need to display results from a SQL join in a ListView/ListActivity.
I've created a cursor:
Cursor cursor = db.rawQuery(LIST_JOIN_SQL, null);
and if I iterate through the cursor, the results are exactly what I expect. However when I try and use a SimpleCursorAdapter to display these results in a ListView I get a runtime exception because there is no column called ' id'.
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.item, cursor, FROM, TO);
Where FROM and TO are defined as:
private static String[] FROM = { "name", };
private static int[] TO = { R.id.name, };
Now I figure I'm probably using the wrong approach here, as it seems SimpleCursorAdapters aren't meant for displaying results of joins.
What approach would you recommend here? I'm restricted to using Android 1.6 APIs.
Try selecting one of your columns as _ID alias
select col1 as _id from table
To use CursorAdapter (or any of its subclasses) you're required to have the "_id" column; it's explicitly stated in the documentation. That's because CursorAdapter uses this column heavily.
What I recommend is whatever you think (based on your project) to be the easier of these two paths:
Create an _id field in one of the tables so that when you join, you end up with an _id field.
Implement your own ListAdapter (starting from BaseAdapter) that is essentially a CursorAdapter but doesn't require an _id field.
I suspect #1 would be easier to do if you control the database, but that you'd have to do #2 if you cannot change the databases' schema.

Categories

Resources