Skip to content

Commit a9b0af5

Browse files
Merge branch '43-rxjava3' into release-3.0.0-alpha2
2 parents a3aea9a + a0a4502 commit a9b0af5

File tree

13 files changed

+609
-5
lines changed

13 files changed

+609
-5
lines changed

Jenkinsfile

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pipeline {
5454
"--tests io.objectbox.FunctionalTestSuite " +
5555
"--tests io.objectbox.test.proguard.ObfuscatedEntityTest " +
5656
"--tests io.objectbox.rx.QueryObserverTest " +
57+
"--tests io.objectbox.rx3.QueryObserverTest " +
5758
"assemble"
5859
}
5960
}

build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ def projectNamesToPublish = [
7373
'objectbox-java-api',
7474
'objectbox-java',
7575
'objectbox-kotlin',
76-
'objectbox-rxjava'
76+
'objectbox-rxjava',
77+
'objectbox-rxjava3'
7778
]
7879

7980
configure(subprojects.findAll { projectNamesToPublish.contains(it.name) }) {

objectbox-kotlin/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buildscript {
88
apply plugin: 'kotlin'
99
apply plugin: 'org.jetbrains.dokka'
1010

11-
sourceCompatibility = 1.7
11+
sourceCompatibility = 1.8
1212

1313
dokka {
1414
outputFormat = 'html'
@@ -46,6 +46,7 @@ dependencies {
4646
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
4747

4848
compile project(':objectbox-java')
49+
compileOnly project(':objectbox-rxjava3')
4950
}
5051

5152

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.objectbox.kotlin
2+
3+
import io.objectbox.query.Query
4+
import io.objectbox.rx3.RxQuery
5+
import io.reactivex.rxjava3.core.BackpressureStrategy
6+
import io.reactivex.rxjava3.core.Flowable
7+
import io.reactivex.rxjava3.core.Observable
8+
import io.reactivex.rxjava3.core.Single
9+
10+
/**
11+
* Shortcut for [`RxQuery.flowableOneByOne(query, strategy)`][RxQuery.flowableOneByOne].
12+
*/
13+
fun <T> Query<T>.flowableOneByOne(strategy: BackpressureStrategy = BackpressureStrategy.BUFFER): Flowable<T> {
14+
return RxQuery.flowableOneByOne(this, strategy)
15+
}
16+
17+
/**
18+
* Shortcut for [`RxQuery.observable(query)`][RxQuery.observable].
19+
*/
20+
fun <T> Query<T>.observable(): Observable<MutableList<T>> {
21+
return RxQuery.observable(this)
22+
}
23+
24+
/**
25+
* Shortcut for [`RxQuery.single(query)`][RxQuery.single].
26+
*/
27+
fun <T> Query<T>.single(): Single<MutableList<T>> {
28+
return RxQuery.single(this)
29+
}

objectbox-rxjava/README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
:information_source: This library will receive no new features.
2+
Development will continue with the [RxJava 3 APIs for ObjectBox](/objectbox-rxjava3).
3+
14
RxJava 2 APIs for ObjectBox
25
===========================
36
While ObjectBox has [data observers and reactive extensions](https://docs.objectbox.io/data-observers-and-rx) built-in,
@@ -13,7 +16,7 @@ For general object changes, you can use `RxBoxStore` to create an `Observable`.
1316
For example to get query results and subscribe to future updates (Object changes will automatically emmit new data):
1417

1518
```java
16-
Query query = box.query().build();
19+
Query<User> query = box.query().build();
1720
RxQuery.observable(query).subscribe(this);
1821
```
1922

@@ -27,5 +30,3 @@ implementation "io.objectbox:objectbox-rxjava:$objectboxVersion"
2730
Links
2831
-----
2932
[Data Observers and Rx Documentation](https://docs.objectbox.io/data-observers-and-rx)
30-
31-
[Note App example](https://github.com/objectbox/objectbox-examples/blob/master/objectbox-example/src/main/java/io/objectbox/example/ReactiveNoteActivity.java)

objectbox-rxjava3/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
RxJava 3 APIs for ObjectBox
2+
===========================
3+
While ObjectBox has [data observers and reactive extensions](https://docs.objectbox.io/data-observers-and-rx) built-in,
4+
this project adds RxJava 3 support.
5+
6+
For general object changes, you can use `RxBoxStore` to create an `Observable`.
7+
8+
`RxQuery` allows you to interact with ObjectBox `Query` objects using:
9+
* Flowable
10+
* Observable
11+
* Single
12+
13+
For example to get query results and subscribe to future updates (Object changes will automatically emmit new data):
14+
15+
```java
16+
Query<User> query = box.query().build();
17+
RxQuery.observable(query).subscribe(this);
18+
```
19+
20+
Adding the library to your project
21+
-----------------
22+
Grab via Gradle:
23+
```gradle
24+
implementation "io.objectbox:objectbox-rxjava3:$objectboxVersion"
25+
```
26+
27+
Migrating from RxJava 2
28+
-----------------------
29+
30+
If you have previously used the ObjectBox RxJava library note the following changes:
31+
32+
- The location of the dependency has changed to `objectbox-rxjava3` (see above).
33+
- The package name has changed to `io.objectbox.rx3` (from `io.objectbox.rx`).
34+
35+
This should allow using both versions side-by-side while you migrate your code to RxJava 3.
36+
37+
Links
38+
-----
39+
[Data Observers and Rx Documentation](https://docs.objectbox.io/data-observers-and-rx)

objectbox-rxjava3/build.gradle

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
apply plugin: 'java'
2+
3+
group = 'io.objectbox'
4+
version= rootProject.version
5+
6+
sourceCompatibility = 1.8
7+
8+
dependencies {
9+
compile project(':objectbox-java')
10+
compile 'io.reactivex.rxjava3:rxjava:3.0.1'
11+
12+
testCompile "junit:junit:$junit_version"
13+
testCompile 'org.mockito:mockito-core:3.3.3'
14+
}
15+
16+
task javadocJar(type: Jar, dependsOn: javadoc) {
17+
classifier = 'javadoc'
18+
from 'build/docs/javadoc'
19+
}
20+
21+
task sourcesJar(type: Jar) {
22+
from sourceSets.main.allSource
23+
classifier = 'sources'
24+
}
25+
26+
artifacts {
27+
// java plugin adds jar.
28+
archives javadocJar
29+
archives sourcesJar
30+
}
31+
32+
uploadArchives {
33+
repositories {
34+
mavenDeployer {
35+
// Basic definitions are defined in root project
36+
pom.project {
37+
name 'ObjectBox RxJava 3 API'
38+
description 'RxJava 3 extensions for ObjectBox'
39+
40+
licenses {
41+
license {
42+
name 'The Apache Software License, Version 2.0'
43+
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
44+
distribution 'repo'
45+
}
46+
}
47+
}
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2017 ObjectBox Ltd. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.objectbox.rx3;
18+
19+
import io.objectbox.BoxStore;
20+
import io.objectbox.reactive.DataSubscription;
21+
import io.reactivex.rxjava3.core.Observable;
22+
23+
/**
24+
* Static methods to Rx-ify ObjectBox queries.
25+
*/
26+
public abstract class RxBoxStore {
27+
/**
28+
* Using the returned Observable, you can be notified about data changes.
29+
* Once a transaction is committed, you will get info on classes with changed Objects.
30+
*/
31+
@SuppressWarnings("rawtypes") // BoxStore observer may return any (entity) type.
32+
public static Observable<Class> observable(BoxStore boxStore) {
33+
return Observable.create(emitter -> {
34+
final DataSubscription dataSubscription = boxStore.subscribe().observer(data -> {
35+
if (!emitter.isDisposed()) {
36+
emitter.onNext(data);
37+
}
38+
});
39+
emitter.setCancellable(dataSubscription::cancel);
40+
});
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2017 ObjectBox Ltd. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.objectbox.rx3;
18+
19+
import java.util.List;
20+
21+
import io.objectbox.query.Query;
22+
import io.objectbox.reactive.DataSubscription;
23+
import io.reactivex.rxjava3.core.BackpressureStrategy;
24+
import io.reactivex.rxjava3.core.Flowable;
25+
import io.reactivex.rxjava3.core.FlowableEmitter;
26+
import io.reactivex.rxjava3.core.Observable;
27+
import io.reactivex.rxjava3.core.Single;
28+
29+
/**
30+
* Static methods to Rx-ify ObjectBox queries.
31+
*/
32+
public abstract class RxQuery {
33+
/**
34+
* The returned Flowable emits Query results one by one. Once all results have been processed, onComplete is called.
35+
* Uses BackpressureStrategy.BUFFER.
36+
*/
37+
public static <T> Flowable<T> flowableOneByOne(final Query<T> query) {
38+
return flowableOneByOne(query, BackpressureStrategy.BUFFER);
39+
}
40+
41+
/**
42+
* The returned Flowable emits Query results one by one. Once all results have been processed, onComplete is called.
43+
* Uses given BackpressureStrategy.
44+
*/
45+
public static <T> Flowable<T> flowableOneByOne(final Query<T> query, BackpressureStrategy strategy) {
46+
return Flowable.create(emitter -> createListItemEmitter(query, emitter), strategy);
47+
}
48+
49+
static <T> void createListItemEmitter(final Query<T> query, final FlowableEmitter<T> emitter) {
50+
final DataSubscription dataSubscription = query.subscribe().observer(data -> {
51+
for (T datum : data) {
52+
if (emitter.isCancelled()) {
53+
return;
54+
} else {
55+
emitter.onNext(datum);
56+
}
57+
}
58+
if (!emitter.isCancelled()) {
59+
emitter.onComplete();
60+
}
61+
});
62+
emitter.setCancellable(dataSubscription::cancel);
63+
}
64+
65+
/**
66+
* The returned Observable emits Query results as Lists.
67+
* Never completes, so you will get updates when underlying data changes
68+
* (see {@link Query#subscribe()} for details).
69+
*/
70+
public static <T> Observable<List<T>> observable(final Query<T> query) {
71+
return Observable.create(emitter -> {
72+
final DataSubscription dataSubscription = query.subscribe().observer(data -> {
73+
if (!emitter.isDisposed()) {
74+
emitter.onNext(data);
75+
}
76+
});
77+
emitter.setCancellable(dataSubscription::cancel);
78+
});
79+
}
80+
81+
/**
82+
* The returned Single emits one Query result as a List.
83+
*/
84+
public static <T> Single<List<T>> single(final Query<T> query) {
85+
return Single.create(emitter -> {
86+
query.subscribe().single().observer(data -> {
87+
if (!emitter.isDisposed()) {
88+
emitter.onSuccess(data);
89+
}
90+
});
91+
// no need to cancel, single never subscribes
92+
});
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2017 ObjectBox Ltd. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.objectbox.query;
18+
19+
import io.objectbox.reactive.DataObserver;
20+
import io.objectbox.reactive.DataPublisher;
21+
import io.objectbox.reactive.DataPublisherUtils;
22+
import java.util.Collections;
23+
import java.util.List;
24+
import java.util.Set;
25+
import java.util.concurrent.CopyOnWriteArraySet;
26+
27+
import javax.annotation.Nullable;
28+
29+
public class FakeQueryPublisher<T> implements DataPublisher<List<T>> {
30+
31+
private final Set<DataObserver<List<T>>> observers = new CopyOnWriteArraySet<>();
32+
33+
private List<T> queryResult = Collections.emptyList();
34+
35+
public List<T> getQueryResult() {
36+
return queryResult;
37+
}
38+
39+
public void setQueryResult(List<T> queryResult) {
40+
this.queryResult = queryResult;
41+
}
42+
43+
@Override
44+
public synchronized void subscribe(DataObserver<List<T>> observer, @Nullable Object param) {
45+
observers.add(observer);
46+
}
47+
48+
@Override
49+
public void publishSingle(final DataObserver<List<T>> observer, @Nullable Object param) {
50+
observer.onData(queryResult);
51+
}
52+
53+
public void publish() {
54+
for (DataObserver<List<T>> observer : observers) {
55+
observer.onData(queryResult);
56+
}
57+
}
58+
59+
@Override
60+
public synchronized void unsubscribe(DataObserver<List<T>> observer, @Nullable Object param) {
61+
DataPublisherUtils.removeObserverFromCopyOnWriteSet(observers, observer);
62+
}
63+
64+
}

0 commit comments

Comments
 (0)