I am working on a standalone library project that requires persisting a simple model. Here is what my SugarRecord
looks like:
/**
* Keeping track of previously received messages by ID
*/
public class MessageRequestIdModel extends SugarRecord {
protected String messageRequestId;
public MessageRequestIdModel() {
}
public MessageRequestIdModel(String messageRequestId) {
this.messageRequestId = messageRequestId;
}
public String getMessageRequestId() {
return this.messageRequestId;
}
public static boolean exists(String id) {
return MessageRequestIdModel.find(
MessageRequestIdModel.class,
"messageRequestId = ?",
id
).size() != 0;
}
}
In a repository class, I am attempting to persist it by calling this method:
@Override
public void save(MessageRequestId messageRequestId) {
new MessageRequestIdModel(messageRequestId.getId()).save();
}
I now attempt to test this by using an android.test.InstrumentationTestCase
where I pass a Context
to Sugar like so:
SugarContext.init(getInstrumentation().getContext());
This results in this error when I run the test: (truncating to keep this question a succinct read)
android.database.sqlite.SQLiteException: no such table: MESSAGE_REQUEST_ID_MODEL (code 1): , while compiling: INSERT or REPLACE...
.test
package name to SugarORM. No change in behaviourAdding a MessageRequestIdModel.findById(MessageRequestIdModel.class, (long) 1);
like in the other SO posts. Changes error to itself (Showing full stack-trace here in case it helps):
android.database.sqlite.SQLiteException: no such table: MESSAGE_REQUEST_ID_MODEL (code 1): , while compiling: SELECT * FROM MESSAGE_REQUEST_ID_MODEL WHERE id=? LIMIT 1
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1240)
at com.orm.SugarRecord.find(SugarRecord.java:192)
at com.orm.SugarRecord.findById(SugarRecord.java:102)
at pm.tin.apprise.entities.message_request_ids.MessageRequestIdModelRepository.save(MessageRequestIdModelRepository.java:19)
I've tried removing all Sugar ORM config from the Manifest like suggested by many - this changes nothing
I've tried creating a Sample App module and tried running it as a test-case for that app, in case Standalone apps didn't get the right resources on the emulator/device (I've tested on both)
I've tried incrementing the VERSION
number for the database
I've tried switching to an ActivityTestCase
and using getActivity().getApplicationContext()
. This essentially fails with an error that suggests that this Context is incomplete to be able to setup SQLite
As you can see, I have pushed hard at this boulder all night long, but at this point it is seeming Sisyphean and I have absolutely no lead for my next debug attempt other than to use a different ORM than Sugar (which doesn't really seem to be the problem). There is nothing more emasculating that not being able to run SQLite in a Test Case and I cry to the Holy Programmer Consciousness in you for help :-'(
This issue has been observed in Android Studio 2.x.x-beta versions (most notably 2.0.0-beta6) and has its root cause in the 'Instant Run' feature.
I imagine this may be fixed shortly, but for this to work in the meantime, you should disable the feature in the following menu
File | Settings | Build, Execution, Deployment | Instant Run
Cleaning and then building the application should resolve these issues.
You can see the related Sugar bug report here.
This should conclusively solve this problem for all the folks out there struggling to get Sugar ORM to work out of the box - use the SQL versioning system to manually fire creation SQL.
In the above use-case, here is how you do it:
1.) Change Sugar ORM config's DB version to a new number (say N
) such that it is greater than the current version OR change database name
2.) Create a file ModuleName/src/main/assets/sugar_upgrades/<N>.sql
with your SQL; showing mine, in case it helps:
DROP TABLE MESSAGE_REQUEST_ID_MODEL;
CREATE TABLE MESSAGE_REQUEST_ID_MODEL(ID INTEGER PRIMARY KEY AUTOINCREMENT, MESSAGE_REQUEST_ID CHAR(128));
This will force Sugar to fire your SQL to create the table for you (albeit manually).
Additional Notes
InstrumentationTestCase
, simply do SugarContext.init(getInstrumentation().getTargetContext())
as shown in the original questionyour problem may be creation of class...
public class MessageRequestIdModel extends SugarRecord<MessageRequestIdModel> {
protected String messageRequestId;
public MessageRequestIdModel() {
}
public MessageRequestIdModel(String messageRequestId) {
this.messageRequestId = messageRequestId;
}
public String getMessageRequestId() {
return this.messageRequestId;
}
public static boolean exists(String id) {
return MessageRequestIdModel.find(
MessageRequestIdModel.class,
"messageRequestId = ?",
id
).size() != 0;
}
}
please recheck with my code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With