Дело в том что я до этого удалял и обновлял записи в Realm
таким образом:
public <T extends RealmObject> void deleteDataById(String publicId, Class<T> clazz){
Realm realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmResults<T> result = realm.where(clazz).equalTo("publicId", publicId).findAll();
result.deleteAllFromRealm();
}
});
}
public <T extends RealmObject> void updateData(T object) {
try (Realm realmInstance = Realm.getDefaultInstance()) {
realmInstance.executeTransaction(realm -> {
Log.d(LOG_TAG, "updateData");
realm.insertOrUpdate(object);
});
}
}
Но так как я изучаю RXJava
, решил переделать CRUD
операции под RX
.
Вот как я делаю запись в базу:
public <T extends RealmObject> Flowable<RealmResults<T>> getAllData(Class<T> clazz) {
Realm realm = Realm.getDefaultInstance();
RealmQuery<T> query = realm.where(clazz);
if(realm.isAutoRefresh()) {
Log.d(LOG_TAG, "getData isAutoRefresh()");
return query.findAllAsync().asFlowable().filter(RealmResults::isLoaded);
} else {
Log.d(LOG_TAG, "getData, !isAutoRefresh()");
return Flowable.just(query.findAll());
}
}
С одной стороны подумываю так и оставить Update
и Delete
операции, так как они ничего не возвращают, но и с другой, мне кажется они хотя бы должны возвращать результат операции. Может я не правильно представляю.
Попробовал с Flowable.defer()
, Flowable.just()
, но все равно ошибка в flatMap()
:
flatMap (io.reactivex.functions.Function>) in Flowable cannot be applied to (anonymous io.reactivex.functions.Function)
Вот как я пытался сделать:
public Flowable deleteDataById(String publicId) {
Realm realm = Realm.getDefaultInstance();
return realm.asFlowable()
.flatMap(new Function<Realm, Boolean>() {
@Override
public Boolean apply(Realm realm) throws Exception {
return realm.where(ServiceModel.class)
.equalTo("publicId", publicId)
.findAll()
.deleteAllFromRealm();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
Вопрос:
Правильны ли мои представления касательно Update
и Delete
.
Как правильно переделать Update
и Delete
под RX
?
Не совсем понимаю, зачем реализовывать прям CRUD, я делал вот так, пример на котлине, но думаю суть будет понятна.
Чтобы можно было использовать вместе с Observable и Flowable
fun <T : RealmModel> queryFromRealm(func: (Realm) -> T?): Observable<T> {
return queryFromRealmFlowable(func).toObservable()
}
fun <T : RealmModel> queryFromRealmFlowable(func: (Realm) -> T?): Flowable<T> {
return Flowable.defer<T> {
val realm = Realm.getDefaultInstance()
try {
realm.beginTransaction()
val result = func(realm)
var resultCloned: T? = null
if (RealmObject.isValid(result)) {
resultCloned = realm.copyFromRealm(result)
}
realm.commitTransaction()
if (resultCloned == null) {
return@defer Flowable.empty()
} else
return@defer Flowable.just<T>(resultCloned)
} catch (e: Exception) {
realm.cancelTransaction()
Flowable.error<T>(e)
} finally {
realm.close()
}
}
}
И для списков объектов
fun <T : RealmModel> queryListFromRealm(func: (Realm) -> List<T>): Single<List<T>> {
return Single.defer<List<T>> {
val realm = Realm.getDefaultInstance()
try {
realm.beginTransaction()
val result = func(realm)
val resultCloned = result.map { realm.copyFromRealm(it) }
realm.commitTransaction()
return@defer Single.just<List<T>>(resultCloned)
} catch (e: Exception) {
realm.cancelTransaction()
Single.error<List<T>>(e)
} finally {
realm.close()
}
}
}
Дальше я это использую уже в репозиториях, т.е. так называемые crud операции все идут там.
fun fetchPhotoList(): Single<List<Photo>> {
return RealmProvider.queryListFromRealm { realm -> realm.where(Photo::class.java).findAllSorted("date") }
}
так же можно использовать и в цепочке операторов
fun loadHouseList(limit: Int, offset: Int, query: String): Single<List<House>> {
return api.loadHouseList(limit, offset, query)
.flatMap { list -> RealmProvider.queryListFromRealm {realm -> realm.copyToRealmOrUpdate(list) } }
}
Плюс моего подхода в том, что я отвязываю объекты от Realm, т.е. они перестают быть active record. С этим решается проблема, что такие объекты можно передавать между потоками, а значит инстанс realm можно использовать только в том потоке, в котором он был создан.
На всякий случай покажу весь класс c extention func, вдруг будет полезно кому-то
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Нужно найти в заданном с клавиатуры шестизначном числе, цифры 0
Имеется приложение, которое работает с локальной базой данных SQLiteВ этой БД хранятся ссылки на файлы и ключевые слова, по которым можно найти...
чтобы по нажатию добавлялся только один экземпляр в ArrayList например