Search code examples
androidsqliteandroid-contentproviderdatabase-performance

Is it possible to get the last "N" IDs from a ContentProvider bulkInsert?


The problem

Say that I want to insert 1000 elements on a table using a ContentProvider. I'd normally use bulkInsert for that.

But what if I want the IDs of the successful insert operations? I can't get that information through the bulkInsert method, since it only returns a long.

So I wonder, is there a way to do a bulk insert and get the newly inserted IDs?

What I'm doing now

The solution that came up on my mind was to either get the last "N" inserted rows and get the IDs after the bulkInsert, or to make a query based on a column of the inserted rows (Let's say, column 'name').

Either way works, but do I really need to take this extra step? It feels a little redundant...

Example of my bulkInsert:

final SQLiteDatabase db = mOpenHelper.getWritableDatabase();

    switch (sUriMatcher.match(uri)) {
        case BLAH: {
            db.beginTransaction();
            int rCount = 0;
            for (ContentValues value : values) {
                long _id = db.insert(SaiteContract.BlahEntry.TABLE_NAME, null, value);
                if (_id != -1) {
                    rCount++;
                }
            }
            db.setTransactionSuccessful();
            db.endTransaction();

            Context context = getContext();
            if (context != null) {
                context.getContentResolver().notifyChange(uri,null);
            }

            return rCount;
        }
        // Other tables
        default:
            return super.bulkInsert(uri,values);
    }
}

Solution

  • The contract of bulkInsert is to return the number of affected rows, so I wouldn't recommend changing that. If you need to make an arbitrary call, you can use ContentResolver.call(), which returns a Bundle. For example, in your provider implementation:

    @Override
    public Bundle call(String method, String args, Bundle extras) {
        if (method.equals("customInsert")) {
            ContentValues[] values = extras.getParcelableArray("contentValues")
            // do bulk insert and return list of ids in a new Bundle
        }
    }
    

    Then simply call

    Bundle result = getContentResolver().call(...);
    List<Long> ids = result.getLongArray("ids");