Android: Add column to already populated Cursor

1.4k views Asked by At

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?

1

There are 1 answers

0
Leo supports Monica Cellio On BEST ANSWER

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);
    }
}