SQLite データベースにデータを保存するための以下のクラスを作成しました。ご覧のとおり、これは単なるキーと値のマッピングです。KEY は TEXT フィールドで、VALUE は BLOB です。
1 つのシナリオを除いて、完全に機能します。「add」を使用して、長さが約 2,500,000 文字の文字列を追加します。実際、これは JSON でエンコードされた文字列です (干渉する不正な文字がないことを確認するために、javascript スタイルの encodeURIComponent も適用しようとしました)。
このシナリオでは、値が正常に追加されます (エラーはスローされず、add() は true を返します)。しかし、その直後に get(key) を呼び出すと、cursor.getString(0) から IllegalStateException がスローされます。
具体的には:
"Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it." (id=830026207728)
カーソル オブジェクトを調べましたが、問題はありません (mCount==1、mColumns==String[1] など)。
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 });
}
}