@NonNull @Override public Person mapFromCursor(@NonNull Cursor cursor) { final StorIOSQLite storIOSQLite = storIOSQLiteFromPerformGet.get(); // BTW, you don't need a transaction here // StorIO will wrap mapFromCursor() into the transaction if needed final long personId = cursor.getLong(cursor.getColumnIndexOrThrow(PersonsTable.COLUMN_ID)); final String personUuid = cursor.getString(cursor.getColumnIndexOrThrow(PersonsTable.COLUMN_UUID)); final String personName = cursor.getString(cursor.getColumnIndexOrThrow(PersonsTable.COLUMN_NAME)); final List<Car> personCars = storIOSQLite .get() .listOfObjects(Car.class) .withQuery( Query.builder() .table(CarsTable.TABLE_NAME) // .where(CarsTable.COLUMN_PERSON_ID + "=?") // .whereArgs(personId) .where(CarsTable.COLUMN_PERSON_UUID + "=?") .whereArgs(personUuid) .build()) .prepare() .executeAsBlocking(); return new Person.Builder(personName).uuid(personUuid).cars(personCars).build(); }
void reloadData() { uiStateController.setUiStateLoading(); final Subscription subscription = storIOSQLite .get() .listOfObjects(Tweet.class) .withQuery(TweetsTable.QUERY_ALL) .prepare() .createObservable() // it will be subscribed to changes in tweets table! .delay( 1, SECONDS) // for better User Experience :) Actually, StorIO is so fast that we need // to delay emissions (it's a joke, or not) .observeOn(mainThread()) .subscribe( new Action1<List<Tweet>>() { @Override public void call(List<Tweet> tweets) { // Remember: subscriber will automatically receive updates // Of tables from Query (tweets table in our case) // This makes your code really Reactive and nice! // We guarantee, that list of objects will never be null (also we use // @NonNull/@Nullable) // So you just need to check if it's empty or not if (tweets.isEmpty()) { uiStateController.setUiStateEmpty(); tweetsAdapter.setTweets(null); } else { uiStateController.setUiStateContent(); tweetsAdapter.setTweets(tweets); } } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { // In cases when you are not sure that query will be successful // You can prevent crash of the application via error handler Timber.e(throwable, "reloadData()"); uiStateController.setUiStateError(); tweetsAdapter.setTweets(null); } }); // Preventing memory leak (other Observables: Put, Delete emit result once so memory leak won't // live long) // Because rx.Observable from Get Operation is endless (it watches for changes of tables from // query) // You can easily create memory leak (in this case you'll leak the Fragment and all it's fields) // So please, PLEASE manage your subscriptions // We suggest same mechanism via storing all subscriptions that you want to unsubscribe // In something like CompositeSubscription and unsubscribe them in appropriate moment of // component lifecycle unsubscribeOnStop(subscription); }
private GetObjectStub(boolean withTypeMapping) { this.withTypeMapping = withTypeMapping; storIOSQLite = mock(StorIOSQLite.class); internal = mock(StorIOSQLite.Internal.class); when(storIOSQLite.internal()).thenReturn(internal); query = Query.builder().table("test_table").build(); rawQuery = RawQuery.builder().query("select * from who_cares").observesTables("test_table").build(); //noinspection unchecked getResolver = mock(GetResolver.class); cursor = mock(Cursor.class); item = new TestItem(); when(cursor.getCount()).thenReturn(1); when(cursor.moveToNext()) .thenAnswer( new Answer<Boolean>() { int invocationsCount = 0; @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { return invocationsCount++ < 1; } }); when(storIOSQLite.get()).thenReturn(new PreparedGet.Builder(storIOSQLite)); when(storIOSQLite.observeChangesInTables(eq(singleton(query.table())))) .thenReturn(Observable.<Changes>empty()); assertThat(rawQuery.observesTables()).isNotNull(); when(storIOSQLite.observeChangesInTables(rawQuery.observesTables())) .thenReturn(Observable.<Changes>empty()); when(getResolver.performGet(storIOSQLite, query)).thenReturn(cursor); when(getResolver.performGet(storIOSQLite, rawQuery)).thenReturn(cursor); when(getResolver.mapFromCursor(cursor)).thenReturn(item); //noinspection unchecked typeMapping = mock(SQLiteTypeMapping.class); if (withTypeMapping) { when(internal.typeMapping(TestItem.class)).thenReturn(typeMapping); when(typeMapping.getResolver()).thenReturn(getResolver); } }