I'm need to increment some integer in table. Instead of making select and consecutive update, i'm want to do this by single query. But out of luck.
Following code returns 0:
final SQLiteStatement stmt = helper.getWritableDatabase().
compileStatement("update my_table set my_count = my_count + 1 where _id = ?");
try
{
stmt.bindLong(1, id);
return stmt.executeUpdateDelete();
}
finally
{
stmt.close();
}
And, of course, no record is updated.
But this returns 1:
final ContentValues v = new ContentValues();
v.put("my_count", 1);
return helper.getWritableDatabase().
update("my_table", v, "_id=?", new String[]{String.valueOf(id)});
Record with specified id is 100% exists. Tried to make this within or without transaction - result is same. Didn't test on real SQLiteStatement, probably Robolectric bug.
Anybody has any assumptions regarding this effect?
Or suggestions about how to get around this problem (may be without usage of SQLiteStatement
)?
Thanks.
Update 1.
I'm also roll some simple test:
@RunWith(RobolectricTestRunner.class)
public class SQLiteStatementTest
{
private static class TestOpenHelper extends SQLiteOpenHelper
{
public TestOpenHelper(Context context)
{
super(context, "test", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT, count INTEGER)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
}
}
@Test
public void testExecuteUpdateDeleteModifiesRow() throws Exception
{
final int initialCount = 6;
final TestOpenHelper helper = new TestOpenHelper(Robolectric.application);
final ContentValues v = new ContentValues();
v.put("count", initialCount);
final long id = helper.getWritableDatabase().insert("test", null, v);
final SQLiteStatement stmt = helper.getWritableDatabase().
compileStatement("update test set count = count + 1 where _id=?");
stmt.bindLong(1, id);
assertThat(stmt.executeUpdateDelete(), is(1));
}
}
According to following sources:
https://github.com/pivotal/robolectric/blob/master/src/main/java/org/robolectric/shadows/ShadowSQLiteStatement.java
executeUpdateDelete()
isn't implemented.Since
callThroughByDefault = false
this method is shadowed by default empty implementation. This is why i don't getRuntimeException("Stub!")
.It should be very easy to shadow this method, but i found a more general problem (with
Uri.parse
method) in robolectric2.0-alpha-2
Update 1.
Pull requests to shadow
executeUpdateDelete()
:https://github.com/pivotal/robolectric/pull/450
https://github.com/pivotal/robolectric/pull/451