fakataha
fakataha

Reputation: 800

Cursors, SQLite, and queries

I have a sqlitedatabase I'm implementing within my app and I keep receiving an IllegalStateException when launching.

09-21 22:48:26.749  15762-16277/nz.co.exium.panther E/AndroidRuntime﹕ FATAL EXCEPTION: SyncAdapterThread-2
java.lang.IllegalStateException: Couldn't read row 0, col 4 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:438)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at android.database.CursorWrapper.getString(CursorWrapper.java:114)
        at nz.co.exium.panther.sync.PantherSyncAdapter.getRegistrationId(PantherSyncAdapter.java:269)
        at nz.co.exium.panther.sync.PantherSyncAdapter.onPerformSync(PantherSyncAdapter.java:64)
        at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:254)

I believe this is caused by the query returning a fairly empty table (except for _ID that is autoincremented) and then when I attempt to get a String from the cursor.

String registrationID = "";
    Uri uri = CustomerEntry.CONTENT_URI;
    Cursor cursor = mContext.getContentResolver().query(uri, CUSTOMER_PROJECTION, null, null, null);
    if (cursor.moveToFirst())   {

        registrationID = cursor.getString(INDEX_CUST_REGID);
    }

SQL create table call:

final String SQL_CREATE_CUSTOMER_TABLE = "CREATE TABLE " + CustomerEntry.TABLE_NAME + " (" +
            CustomerEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            CustomerEntry.COLUMN_CUST_NAME + " TEXT NOT NULL, " +
            CustomerEntry.COLUMN_CUST_EMAIL + " TEXT NOT NULL, " +
            CustomerEntry.COLUMN_CUST_QRHASH + " TEXT NOT NULL," +
            CustomerEntry.COLUMN_CUST_REGID + " TEXT NOT NULL)";

In this case, the INDEX_CUST_REGID is a final static int related to the position in the String[] projection, 3rd position in this case. It makes sense this would throw but is there a method or way to query the SyncAdapter for a specific column like the CUST_REGID or a method to check if the Column requested was returned before attempting a cursor.getString()?

This also might solve another problem I have with saving the Reg ID before knowing the EMAIL, NAME, QRHASH. Can't insert just one column without the rest having a value as well (NOT NULL), even though it would be worthless data and overwritten asap.

Method attempting to store Reg ID.

private void storeRegistrationID(Context context, String regID) {
    //DB insert regid
    ContentValues cValues = new ContentValues();
    cValues.put(CustomerEntry.COLUMN_CUST_NAME, "");
    cValues.put(CustomerEntry.COLUMN_CUST_EMAIL, "");
    cValues.put(CustomerEntry.COLUMN_CUST_QRHASH, "");
    cValues.put(CustomerEntry.COLUMN_CUST_REGID, regID);
    mContext.getContentResolver().insert(CustomerEntry.CONTENT_URI, cValues);
}

projection as requested:

 String[] CUSTOMER_PROJECTION = new String[]{
        CustomerEntry._ID,
        CustomerEntry.COLUMN_CUST_NAME,
        CustomerEntry.COLUMN_CUST_EMAIL,
        CustomerEntry.COLUMN_CUST_QRHASH,
        CustomerEntry.COLUMN_CUST_REGID
};

Upvotes: 0

Views: 1334

Answers (1)

John J Smith
John J Smith

Reputation: 11923

Are you certain the table was actually created? There's a semi-colon mising from the end of your SQL_CREATE_CUSTOMER_TABLE text string - although I'm not sure if it is mandatory to run the sql for creating the table. I would suggest running it on the Eclipse emulator, then from the DDMS perspective, take a copy of the database somewhere where you can open it with the SQLite Manager plugin for Firefox - this will show you the database tables.

Upvotes: 1

Related Questions