It looks to me like you're making the classic beginner mistake -- one
that even bites experienced database programmers if we're at all
inattentive...

Cursors start out positioned *before* the first row. You have to
actually position them to the first row before you try to access data.
c.moveToFirst() will position you there -- but check the return value;
if it is false, you actually got an empty result, and there IS no
first row.

In other words, to access database data, you always have to position-
and-check first.

On Apr 15, 10:06 am, kc2uno_CMU <[email protected]> wrote:
> Hi all,
>
> I just wrote my own DbAdapter by modifying the example DbAdapter in
> Notepad tutorial. The problem came when I tried to fetch data from the
> Database using my DbAdapter. I got :
> "android.database.CursorIndexOutOfBoundsException: Index -1 requested,
> with a size of 1." Below is a snippet of my code that I was trying to
> play around with the DB:
>
>                         //rep,index are both some random integers that
> I'm trying to store in a row
>                         ex_rowId = mDbHelper.createExSet(rep, index,
> 1);
>                         if(D)   Log.d(TAG, "rowid that was used for insertion:
> " + ex_rowId);
>
>                         Cursor c = mDbHelper.fetchExRow(ex_rowId);
>                         if(c == null)
>                                 Log.d(TAG, "HOLY-cursor null");
>                         //a cursor's lifecycle is automatically taken care of
>                         startManagingCursor(c);
>                         int repIndex =
> c.getColumnIndex(BtDbAdapter.KEY_EX_REP);
>                         if(D)
>                         {
>                                 Log.d(TAG,"HOLY-column rep index: "+repIndex);
>                                 Log.d(TAG,"HOLY_column count: 
> "+c.getColumnCount()+
> "row count: "+c.getCount());
>                         }
>                         int i=0;
>                         for(;i<c.getColumnCount();i++)
>                         {
>                                 Log.d(TAG,"Column names:
> "+c.getColumnName(i).toString());
>                         }
>
>                         int repCount = c.getInt(repIndex);
>                         if(D)   Log.d(TAG, "HOLY-rep count: "+repCount);
>
> In summary, the code above first creates a new row, which stores some
> values into a row. Then it fetches the same row by using the returned
> row id. At last I am trying to retrieve the values from the cursor.
> Below is the debug print log:
>
> 04-14 19:14:11.896: DEBUG/BluetoothChat(710): rowid that was used for
> insertion: 3
> 04-14 19:14:11.906: DEBUG/BluetoothChat(710): HOLY-column rep index: 1
> 04-14 19:14:11.906: DEBUG/BluetoothChat(710): HOLY_column count: 4 row
> count: 1
>
> 04-14 19:14:11.906: DEBUG/BluetoothChat(710): Column names: _id
> 04-14 19:14:11.916: DEBUG/BluetoothChat(710): Column names: repetition
> 04-14 19:14:11.916: DEBUG/BluetoothChat(710): Column names:
> ex_timestamp
> 04-14 19:14:11.916: DEBUG/BluetoothChat(710): Column names: ex_unique
>
> 04-14 19:14:11.916: DEBUG/AndroidRuntime(710): Shutting down VM
> 04-14 19:14:11.916: WARN/dalvikvm(710): threadid=3: thread exiting
> with uncaught exception (group=0x4001da28)
> 04-14 19:14:11.916: ERROR/AndroidRuntime(710): Uncaught handler:
> thread main exiting due to uncaught exception
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):
> android.database.CursorIndexOutOfBoundsException: Index -1 requested,
> with a size of 1
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCurso 
> r.java:
> 172)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:
> 84)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> com.example.android.BluetoothChat.BluetoothChat
> $1.handleMessage(BluetoothChat.java:325)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> android.os.Handler.dispatchMessage(Handler.java:99)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> android.os.Looper.loop(Looper.java:123)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> android.app.ActivityThread.main(ActivityThread.java:4203)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> java.lang.reflect.Method.invokeNative(Native Method)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> java.lang.reflect.Method.invoke(Method.java:521)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> com.android.internal.os.ZygoteInit
> $MethodAndArgsCaller.run(ZygoteInit.java:791)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
> 04-14 19:14:11.926: ERROR/AndroidRuntime(710):     at
> dalvik.system.NativeStart.main(Native Method)
> 04-14 19:14:11.936: INFO/Process(76): Sending signal. PID: 710 SIG: 3
> 04-14 19:14:11.936: INFO/dalvikvm(710): threadid=7: reacting to signal
> 3
> 04-14 19:14:11.966: INFO/dalvikvm(710): Wrote stack trace to '/data/
> anr/traces.txt'
> 04-14 19:14:15.696: DEBUG/dalvikvm(370): GC freed 43 objects / 2112
> bytes in 94ms
> 04-14 19:14:20.766: DEBUG/dalvikvm(150): GC freed 4543 objects /
> 253432 bytes in 161ms
> 04-14 19:14:24.676: INFO/Process(710): Sending signal. PID: 710 SIG: 9
> 04-14 19:14:24.706: ERROR/JavaBinder(76): !!! FAILED BINDER
> TRANSACTION !!!
>
> As anyone can see, the row count is 1 !!!!! Therefore I am not exactly
> sure what the bug is. Part of my DB code is also shown below:
>
>         public static final String KEY_EX_ROWID = "_id";
>         public static final String KEY_EX_REP = "repetition";
>         public static final String KEY_EX_TIMESTAMP = "ex_timestamp";
>         //this identifies the particular set of exercise the user was doing
>         public static final String KEY_EX_UNIQUE_ID = "ex_unique";
>
>         private static final String DATABASE_CREATE_EX =
>             "create table exsetTable (_id integer primary key
> autoincrement, "
>             + "repetition integer not null, ex_timestamp integer not
> null, ex_unique integer not null);";
>         private static final String DATABASE_TABLE_EXSET =
> "exsetTable";
>         @Override
>         public void onCreate(SQLiteDatabase db) {
>                 //create tables-exec can only take one query at a time.
> Creating 2 different tables
>
>             db.execSQL(DATABASE_CREATE_EX);
>             db.execSQL(DATABASE_CREATE_HR);
>             Log.d(TAG,"DB CREATION DONE");
>         }
>     public long createExSet(int rep, int timestamp, int ex_uniqueId) {
>         ContentValues initialValues = new ContentValues();
>         initialValues.put(KEY_EX_REP, rep);
>         initialValues.put(KEY_EX_TIMESTAMP, timestamp);
>         initialValues.put(KEY_EX_UNIQUE_ID, ex_uniqueId);
>
>         return mDb.insert(DATABASE_TABLE_EXSET, null, initialValues);
>     }
>     public Cursor fetchExRow(long ex_rowId) {
>         Cursor mCursor = mDb.query(DATABASE_TABLE_EXSET,
>                         new String[]
> {KEY_EX_ROWID,KEY_EX_REP,KEY_EX_TIMESTAMP,KEY_EX_UNIQUE_ID},
>                         KEY_EX_ROWID + "=" + ex_rowId, null, null, null, 
> null);
>         return mCursor;
>     }
>
> I am not sure if the cursor returned from fetchExRow is valid. Would
> it still give me row count 1 if it's invalid(empty)? The bug is either
> in the way I am trying to retrieve data using getInt or my
> databaseadapter's code. Is there a way to view the databases and
> tables I created using some tools?
> Thank you so much!

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

To unsubscribe, reply using "remove me" as the subject.

Reply via email to