Search code examples
androidrx-javaandroid-room

2 Maybe queries in ROOM+RXJAVA


I use ROOM + RXJAVA for SQLITE database in ANDROID application.

I have a problem. I need to insert a new record, but before that make a query for more information.

I use Maybe, Single and Completable.

I need to do the following:

1 query. Need to find out the ID of the cow:

@Query("SELECT " + COW_COLUMN_ID + " FROM " + TABLE_COW
        + " WHERE " + COW_COLUMN_RFID + " = :rfid ")
Maybe<Integer> getIdCowByRFID(String rfid);

2 query. I need to create a weighting and add the resulting cow ID to it

@Insert
Maybe<Long> insert(WeightingDbEntity weighting);

How to do it correctly? Making an asynchronous query nested in another asynchronous query is not entirely correct. Tell me please.

If you make synchronous query, then there are no problems, since the result of 1 query is already available, if necessary, execute 2 query. In this case, do I need to add synchronous query (allowMainThreadQueries) to the ROOM? Or should I do it differently? How can 2 Maybe queries be combined into one and executed in transaction mode (@Transaction)?

I read here: https://developer.android.com/reference/android/arch/persistence/room/Transaction

But this example is about synchronous queries. And how to do it correctly with Maybe?


Solution

  • Using an @Dao annotated abstract class rather than an interface (as the latter does not allow methods with a body).

    If you then use the @Query("") along with the @Transaction annotations to precede the method that has the body which can invoke the previously defined methods.

    • The @Query with an empty query fools (if that is the correct word) Room into thinking that the database is being accessed and thus wraps the method within a transaction.

    So if insert and getIdCowByRFID are in the same abstract class (simplifies matters) then you could have something along the lines of (noting that I've never used RXJava):-

    @Query("")
    @Transaction
    Maybe<Long> doBoth(String rfid, WeightingDbEntity w) {
        Maybe<Integer> id = getIdCowByRFID;
        .... do whatever needs to be done/checked
        return insert(w);
    }
    

    The following is a screen shot showing the above technique with the @Dao annotated class, the @Database abstract class which includes the method to retrieve the @Dao class (so that the compile will check the methods). Albeit that the underlying @Entity annotated class is different:-

    enter image description here