5

I'm confused about whether to use MergeCursor or CursorJoiner.

I have a Cursor (A) with a load of data in it. Lets say there are 100 rows in Cursor (A) and 3 columns. What I want to do is insert (append) a new column to the Cursor so the resulting Cursor (B) has 100 rows but 4 columns.

At this moment in time I would like the 4th column to contain a default value for the 100 rows.

How would I do this?

SparkyNZ
  • 6,266
  • 7
  • 39
  • 80
  • 1
    This may help http://stackoverflow.com/a/10415123/1230782 – gnuanu Jul 09 '14 at 10:01
  • @gnuanu: Thanks. It doesn't really help though as they talk about requerying etc - something I don't want to do. I probably just need to take some time out and experiment with MergeCursor and CursorJoiner. I'm not expecting to modify the Cursor that I have - I just want to use it to create another Cursor (quickly) with an extra column. – SparkyNZ Jul 09 '14 at 20:45
  • @SparkyNZ Any thoughts on how to achieve adding column to cursor. I'm stuck in exactly same situation and searching for the way out. Thanks. – abhy Apr 09 '15 at 15:14
  • 1
    @abhy: Sorry it was ages since I had this problem and I can't remember what I did. I suspect I ended up adding a dummy column to Cursor (A) so it matched the column format of (B). – SparkyNZ Apr 14 '15 at 22:37

1 Answers1

3

You can use the Decorator pattern here.

For this, Android has CursorWrapper , which is a...

Wrapper class for Cursor that delegates all calls to the actual cursor object. The primary use for this class is to extend a cursor while overriding only a subset of its methods.

Suppose your new column is called newColumn, and that it is of type String then you can do something along these lines:

class MyCursorWrapper extends CursorWrapper {
    private final String NEW_COLUMN = "newColumn";

    @Override
    public int getColumnCount() {
        // Count the virtual column in
        return getWrappedCursor().getColumnCount() + 1;
    }

    @Override
    public int getColumnIndex(String columnName) {
        // Return the virtual column if they are asking for it,
        // otherwise just use the original 
        if (columnName != null && columnName.equals("newColumn") {
            return getWrappedCursor().getColumnCount();
        }
        return mCursor.getColumnIndex(columnName);
    }

    public int getColumnIndexOrThrow(String columnName)
            throws IllegalArgumentException {
        // Same logic as getColumnIndex()
        if (columnName != null && columnName.equals(NEW_COLUMN) {
            return getWrappedCursor().getColumnCount();
        }
        return getWrappedCursor.getColumnIndexOrThrow(columnName);
    }

    @Override
    public String getColumnName(int columnIndex) {
         if (columnIndex == getWrappedCursor.getColumnCount()) {
             return NEW_COLUMN;
         }
         return getWrappedCursor().getColumnName(columnIndex);
    }

    @Override
    public String[] getColumnNames() {
        // Add our virtual column to the result from the original Cursor
        String original = getWrappedCursor().getColumnNames()
        String result = new String[original.length + 1];
        System.arrayCopy(original, 0, result, 0, original.length);
        result[original.length] = NEW_COLUMN;
        return result;
    }

    @Override
    public String getString(int columnIndex) {
        // For the last column, return whatever you need to return here
        // For real columns, just delegate to the original Cursor
        if (columnIndex == getWrappedCursor().getColumnCount()) {
            return yourResultHere();
        }
        return getWrappedCursor().getString(columnIndex);
    }
}