I have created the class below for saving data to a SQLite database. It is simply a key/value mapping, as you can see. The KEY is a TEXT field and the VALUE is a BLOB.
It works perfectly except in one scenario: I use "add" to add a String which is approximately 2,500,000 characters in length. In fact, it is a JSON-encoded string (which I have also tried applying a javascript-style encodeURIComponent to, as well, in attempts to make sure that there are no illegal characters interfering).
In this scenario, the value gets added successfully (no errors thrown, add() returns true). However, when I call get(key) immediately afterwards, the IllegalStateException is thrown from the cursor.getString(0).
Specifically:
"Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it." (id=830026207728)
I have inspected the cursor object and don't see anything wrong with it (mCount==1, mColumns==String[1], etc).
class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 2;
// Contacts Table Columns names
private static final String KEY_KEY = "key";
private static final String KEY_VAL = "value";
public DatabaseHandler(Context context) {
super(context, Defines.DATA_PREFIX, null, DATABASE_VERSION);
}
public String getTableName() {
return "storage";
}
// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String q = "CREATE TABLE " + this.getTableName() + "(" + KEY_KEY + " TEXT PRIMARY KEY," + KEY_VAL + " BLOB" + ")";
db.execSQL(q);
}
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + this.getTableName());
// Create tables again
onCreate(db);
}
boolean add(String key, String value) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_KEY, key); // Contact Name
values.put(KEY_VAL, value); // Contact Phone
// Inserting Row
long res = db.insertOrThrow(this.getTableName(), null, values);
db.close(); // Closing database connection
return res >= 0;
}
String get(String key) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(this.getTableName(), new String[] { KEY_VAL }, KEY_KEY + "=?", new String[] { key }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
if(cursor == null)
return null;
String ret = null;
try {
ret = cursor.getString(0);
} catch(CursorIndexOutOfBoundsException e) {
ret = null;
} catch(IllegalStateException e) {
ret = null;
}
cursor.close();
return ret;
}
int count(String key) {
String countQuery = "SELECT * FROM " + this.getTableName()+" WHERE "+KEY_KEY+" = ?";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, new String[] { key });
int ret = cursor.getCount();;
cursor.close();
// return count
return ret;
}
void delete(String key) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(this.getTableName(), KEY_KEY + " = ?", new String[] { key });
db.close();
}
int update(String key, String value)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_KEY, key);
values.put(KEY_VAL, value);
// updating row
return db.update(this.getTableName(), values, KEY_KEY + " = ?", new String[] { key });
}
}