Kotlin extensions to simplify Realm API.
Simplify your code to its minimum expression with this set of Kotlin extensions for Realm. Forget all boilerplate related with Realm API and perform database operations in one line of code with this lightweight library. Full test coverage.
Grab via Gradle:
repositories {
mavenCentral()
}
compile "com.github.vicpinm:krealmextensions:2.0.0"
//For Single and Flowable queries:
compile 'io.reactivex.rxjava2:rxjava:2.1.4'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
Grab via Gradle:
repositories {
mavenCentral()
}
compile "com.github.vicpinm:krealmextensions:1.2.0"
//For Observable queries:
compile 'com.github.vicpinm:krealmextensions-rxjava:1.2.0'
//For Single and Flowable queries:
compile 'com.github.vicpinm:krealmextensions-rxjava2:1.2.0'
Grab via Gradle:
repositories {
mavenCentral()
}
compile 'com.github.vicpinm:krealmextensions:1.0.9'
Grab via Gradle:
repositories {
mavenCentral()
}
compile 'com.github.vicpinm:krealmextensions:1.0.6'
Forget about:
- Realm instances management
- Transactions
- Threads limitations
- Boilerplate related with Realm API
- From 2.0 version, your database entities can either extend from RealmObject or implement RealmModule interface.
All methods below use Realm default configuration. You can use different Realm configurations per model with RealmConfigStore.init(Entity::class.java, myConfiguration). See application class from sample for details. Thanks to @magillus for its PR.
All your entities should extend RealmObject.
User user = new User("John");
Realm realm = Realm.getDefaultInstance();
try{
realm.executeTransaction(realm -> {
realm.copyToRealmOrUpdate(user);
});
} finally {
realm.close();
}
User("John").save()
Save method creates or updates your entity into database. You can also use create() method, which only create a new entity into database. If a previous one exists with the same primary key, it will throw an exception.
List<User> users = new ArrayList<User>(...);
Realm realm = Realm.getDefaultInstance();
try {
realm.executeTransaction(realm -> {
realm.copyToRealmOrUpdate(users);
});
} finally {
realm.close();
}
listOf<User>(...).saveAll()
If you need to provide your own Realm instance, you can use the saveManaged(Realm) and saveAllManaged(Realm) methods. These methods return managed objects. You should close manually your Realm instance when you finish with them.
All query extensions return detached realm objects, using copyFromRealm() method.
Realm realm = Realm.getDefaultInstance();
try {
Event firstEvent = realm.where(Event.class).findFirst();
firstEvent = realm.copyFromRealm(event);
} finally {
realm.close();
}
val firstEvent = Event().queryFirst()
You can use lastItem extension too.
Realm realm = Realm.getDefaultInstance();
try {
List<Event> events = realm.where(Event.class).findAll();
events = realm.copyFromRealm(event);
} finally {
realm.close();
}
val events = Event().queryAll()
Realm realm = Realm.getDefaultInstance();
try{
List<Event> events = realm.where(Event.class).equalTo("id",1).findAll();
events = realm.copyFromRealm(event);
} finally {
realm.close();
}
val events = Event().query { query -> query.equalTo("id",1) }
//NOTE: If you have a compilation problems in equalTo method (overload ambiguity error), you can use equalToValue("id",1) instead
If you only need the first or last result, you can also use:
val first = Event().queryFirst { query -> query.equalTo("id",1) }
val last = Event().queryLast { query -> query.equalTo("id",1) }
val sortedEvents = Event().querySorted("name",Sort.DESCENDING)
val sortedEvents = Event().querySorted("name",Sort.DESCENDING) { query -> query.equalTo("id",1) }
Realm realm = Realm.getDefaultInstance();
try{
List<Event> events = realm.where(Event.class).findAll();
realm.executeTransaction(realm -> {
events.deleteAllFromRealm();
});
} finally {
realm.close();
}
Event().deleteAll()
Realm realm = Realm.getDefaultInstance();
try{
List<Event> events = realm.where(Event.class).equalTo("id",1).findAll().deleteAllFromRealm();
events = realm.copyFromRealm(event);
} finally {
realm.close();
}
Event().delete { query -> query.equalTo("id", 1) }
Realm realm = Realm.getDefaultInstance();
Flowable<List<Event>> obs = realm.where(Event.class).findAllAsync()
.asFlowable()
.filter(RealmResults::isLoaded)
.map(realm::copyFromRealm)
.doOnUnsubscribe(() -> realm.close());
val obs = Event().queryAllAsFlowable()
Realm realm = Realm.getDefaultInstance();
Flowable<List<Event>> obs = realm.where(Event.class).equalTo("id",1).findAllAsync()
.asFlowable()
.filter(RealmResults::isLoaded)
.map(realm::copyFromRealm)
.doOnUnsubscribe(() -> realm.close());
val obs = Event().queryAsFlowable { query -> query.equalTo("id",1) }
These kind of observable queries have to be performed on a thread with a looper attached to it. If you perform an observable query on the main thread, it will run on this thread. If you perform the query on a background thread, a new thread with a looper attached will be created for you to perform the query. This thread will be listen for data changes and it will terminate when you call unsubscribe() on your subscription.
val single = Event().queryAllAsSingle()
val single = Event().queryAsSingle { query -> query.equalTo("id", 1) }
You need to add these rules if you use proguard, for rxjava and realm:
# rxjava
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-dontnote rx.internal.util.PlatformDependent
-keepnames public class * extends io.realm.RealmObject
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class *
-dontwarn io.realm.**