Reputation: 401
I'm trying to isolate my layers when building out an application that is going to be maintained for several years. I'm using Realm as a database, Retrofit as a networking layer, and RxJava/RxAndroid as the communication layer in the MVP/MVVM architecture. In the future, I want whoever takes up this project to be able to simply swap out Realm or swap out Retrofit, say if a better library comes out that lends itself to future improvements.
So, to that end, I'm trying to build a generic database interface, and then build my concrete Realm implementation on top of it.
I have a IDatabaseManager interface defined as follows:
public interface IDatabaseManager<E extends AbstractList<? extends T>, T> {
void save(T object);
Observable<E> getAsObservable(Class<?> type);
}
The idea being, I want the database manager to have type E which is some list/collection of some class '?' which extends some base object (for those ORMs which require you to extends some base class).
Then, I have my concrete implementation, which utilizes realm:
public class RealmManager implements IDatabaseManager<RealmResults<? extends RealmObject>, RealmObject> {
@Override
void save(RealmObject object) {
//implementation works
}
@Override
Observable<RealmResults<? extends RealmObject>> getAsObservable(Class<?> type) {
Realm realm = realm.getDefaultInstance();
return realm.where(type).findAllAsync().asObservable();
}
}
However, I'm getting an error on "type" that:
where (java.lang.Class<E>) in Realm cannot be applied
to (java.lang.Class<capture<?>>)
reason: inference variable E has incompatible bounds:
equality constraints: capture of ?
upper bounds: Realm Model
Realm performs queries by taking in a class of the object collection you're querying, where that object must extend RealmObject (abstract), or implement RealmModel (interface), but they are supposed to be interchangeable.
Any help here? I think I'm just messing up some syntax here and I just can't figure out how I can fix it =/
Upvotes: 1
Views: 637
Reputation: 81539
Your initial question is answered by
@Override
<T extends RealmModel> Observable<RealmResults<T> getAsObservable(Class<T> type) {
Realm realm = realm.getDefaultInstance();
return realm.where(type).findAllAsync().asObservable();
}
But in reality, if you want to be able to "simply swap out Realm", you'll have to give up zero-copy evaluation and live-autoupdate, in favor of copying out the Realm objects.
return Observable.defer(() -> {
try(Realm realm = Realm.getDefaultInstance()) {
return Observable.just(realm.copyFromRealm(realm.where(type).findAll()));
}
}).subscribeOn(Schedulers.io());
(although that kinda defeats the purpose if you ask me - after all, Realm was designed so that you don't need to copy everything out to memory)
Upvotes: 1