• Stars
    star
    100
  • Rank 340,703 (Top 7 %)
  • Language
    Java
  • License
    MIT License
  • Created almost 8 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

NoSQL storage with RxJava2 bindings [STABLE]

RxPaper2

RxPaper is a RxJava wrapper for the cool Paper library. It's a clean rewrite of the original RxPaper library by CΓ©sar Ferreira.

Paper icon

For the RxJava1 version, please go to RxPaper.

Rationale

Sometimes you need storage for arbitrary objects on disk, but do not want to store them in a relational database with all the associated problems: writing ORMs, composing the queries, updating scripts. For this purpose NoSQL data storages were created: schemaless document repositories where to store arbitrary data that's not structured.

RxPaper allows access to Paper, which is a NoSQL data storage for Android that allows you to save arbitrary objects in system files called Books. Serialization and deserialization is done using efficient Kryo.

The Paper/Kryo combination supports some partial data structure changes. Check Paper's README for more information.

Usage

Object model handling

RxPaper is subject to the same restrictions as the current version of Paper when the library was last updated. As of Paper 1.5, the library can work with empty constructors and all-arg constructors. Some other combinations would need to be tested by the library user.

I personally recommend using immutable objects, as it makes data handling way simpler on both sides. An immutable object has an all-args constructor, doesn't allow any null fields, and keeps all fields public and final. Like any other dto in Java, it is recommended to implement your own version of equals, hashCode and toString.

As of Paper 1.5 you can also add your own serializers by calling Paper.addSerializer(). Partial structure changes are supported too, as described on Paper's README.

Threading

All operations are run on the Scheduler provided on the constructor, or Schedulers.io() by default. When subscribing to them, specially if using the data to be applied to UI; it's recommended to use the operator observeOn(Scheduler) to see the changes on any desired thread, i.e. Android's main thread.

Initialization

Before the library is usable it requires initializing the underlying Paper library. You only have to initialize RxPaper by calling:

RxPaperBook.init(context);

Working on a book

RxPaper works on books, and each is a folder on the system. A book is only opened and closed on an operation, but you can check the Paper repository for specifics. To make sure no operations are done on the main thread, any operations done on a book can be executed on one Scheduler provided in the constructor. To create an instance of RxPaper the library provides several flavours.

RxPaperBook.with();

Works with the default book, and executes operations on Schedulers.io().

RxPaperBook.with(Schedulers.newThread());

Works with the default book, and executes operations on any provided scheduler.

RxPaperBook.with("my_book_name");

Works with a custom book with the provided id/name, and executes operations on Schedulers.io().

RxPaperBook.with("my_book_name", Schedulers.newThread());

Works with a custom book with the provided id/name, and executes operations on any provided scheduler.

RxPaperBook.withPath(myPath);
RxPaperBook.withPath(myPath, scheduler);
RxPaperBook.withPath(myPath, "my_book_name");

Works with a custom storage location.

Writing a value

Write is a Completable operation, a subset of Observable<T> without a return value, just success/error. Completables can be converted back to Observables by using the operator toObservable().

RxPaperBook book = RxPaperBook.with("my-book");
Completable write = book.write(key, value);
// Because RxJava is lazily evaluated, the operation is not executed until the Observable is subscribed.
write.subscribe(new CompletableObserver() {
            @Override
            public void onCompleted() {
                // Operation suceeded
            }

            @Override
            public void onError(Throwable e) {
                // Operation failed
            }

            @Override
            public void onSubscribe(Subscription d) {
                // Called once on creation
            }
        });

Every key written is stored as a file on the system under the folder specified by the book.

Reading a value

Reading is a Single<T> operation, a subset of Observable<T> that returns just a single element and then completes. Singles can be converted back to Observables by using the operator toObservable(). Reading comes in two flavours:

Single<ComplexObject> read = book.read(key);
read.subscribe(new SingleSubscriber<ComplexObject>() {
            @Override
            public void onSuccess(ComplexObject value) {
                // Operation succeeded and returned a value
            }

            @Override
            public void onError(Throwable error) {
                // Operation failed
            }
        });

ComplexObject defaultValue = new ComplexObject();
Single<ComplexObject> readOrDefault = book.read(key, defaultValue);
readOrDefault.subscribe(new SingleSubscriber<ComplexObject>() {
            @Override
            public void onSuccess(ComplexObject value) {
                // Operation succeeded and returned a value
            }

            @Override
            public void onError(Throwable error) {
                // Operation failed
            }
        });

read(key) fails with IllegalArgumentException if the key is not found. read(key, defaultValue) returns a default value if the key is not found.

If the subscriber is not of the same type as the value stored expect a ClassCastException.

Make sure to read the rules on how object models are handled on the section above.

Observing changes on a key

All write operations are naively forwarded into a PublishSubject<?> by default, which makes it possible to observe all changes for a specific key. Observing is a Flowable<T> operation that never completes.

Flowable<ComplexObject> observe = book.observe(key, ComplexObject.class);
observe.subscribe(new Subscriber() { /* ... */ });

Observe filters on both the key and the type. Another version of observe that filters only on key and casts any values unsafely is provided under the name observeUnsafe(). It's recommended to use it with strict care.

Contains

Contains is a Single<Boolean> operation that returns true if the key is on the current book, or false otherwise.

Single<Boolean> contains = book.contains(key);
contains.subscribe(new SingleSubscriber<Boolean>() { /* ... */ });

Delete

Delete is a Completable operation. Deletes data stored for a key on the current book. It will still succeed even if the key is not found.

Completable delete = book.delete(key);
delete.subscribe(new CompletableObserver() { /* ... */ });

Keys

Keys is a Single<List<String>> operation that returns a list of all keys stored on the current book.

Single<List<String>> keys = book.keys();
exists.subscribe(new SingleSubscriber<List<String>>() { /* ... */ });

GetPath

Returns the path to the current book. Note that the path will not exist until any value is saved in the book.

Single<String> path = book.getPath();
path.subscribe(new SingleSubscriber<String>() { /* ... */ });

Returns the path to the key in the current book. Note that the path will not exist until a value is saved for that key.

Single<String> pathKey = book.getPath("my_key");
pathKey.subscribe(new SingleSubscriber<String>() { /* ... */ });

Destroy

Destroy is a Completable operation that deletes all keys and values on the current book.

Completable destroy = book.destroy();
destroy.subscribe(new CompletableObserver() { /* ... */ });

Distribution

Add as a dependency to your build.gradle

    repositories {
        ...
        maven { url "https://jitpack.io" }
        ...
    }
    
    dependencies {
        ...
        compile 'com.github.pakoito:RxPaper2:1.6.0'
        ...
    }

or to your pom.xml

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
    
    <dependency>
        <groupId>com.github.pakoito</groupId>
        <artifactId>RxPaper2</artifactId>
        <version>1.6.0</version>
    </dependency>

License

Copyright (c) 2019 pakoito & 2015 CΓ©sar Ferreira

The MIT License (MIT)

See LICENSE.md

More Repositories

1

FunctionalAndroidReference

Showcase project of Functional Reactive Programming on Android, using RxJava.
Kotlin
276
star
2

MarI-O

Github clone of MarI/O by SethBling
224
star
3

RxSealedUnions

Compile-time checked Unions of different types for Domain Modeling [STABLE]
Java
127
star
4

Komprehensions

Do comprehensions for Kotlin and 3rd party libraries [STABLE]
Kotlin
114
star
5

RxTuples

Simple tuples to use with RxJava [STABLE]
Java
112
star
6

RxPaper

NoSQL storage with RxJava bindings [STABLE]
Java
88
star
7

RxComprehensions

Reduce boilerplate in RxJava by abstracting chained operators like flatMap, concatMap, switchMap, or compose [STABLE]
Java
86
star
8

RxObservableDiskCache

Simple NoSQL disk cache for network responses [STABLE]
Java
86
star
9

FunctionalRx2

FunctionalRx2 is a collection of constructs to simplify a functional programming approach to Java and Android [STABLE]
83
star
10

JavaSealedUnions

Tagged Unions for the Java 8 connoisseur
Java
54
star
11

SongkickInterview

App handed in as part of Songkick's interview process
Java
51
star
12

RxFunctions

Advanced Function composition to use with RxJava [STABLE]
Java
49
star
13

FunctionalRx

FunctionalRx is a collection of constructs to simplify a functional programming approach to Java and [STABLE]
48
star
14

RxCurrying

Simple currying for FuncN and ActionN on RxJava [STABLE]
Java
38
star
15

RxSealedUnions2

Compile-time checked Unions of different types for Domain Modeling [STABLE]
Java
35
star
16

RxActions

Simple ActionN composition to use with RxJava [STABLE]
Java
33
star
17

RxPartialApplication

Simple partial application for FuncN and ActionN on RxJava [STABLE]
Java
30
star
18

RustyAndroid

Interoping Android's Java with Rust via JNA
C
28
star
19

RxTuples2

Simple tuples to use with RxJava2 [STABLE]
Java
22
star
20

RxMemoization

Simple Function result caching for RxJava [STABLE]
Java
20
star
21

RxObservableDiskCache2

Simple NoSQL disk cache for network responses [STABLE]
Java
14
star
22

javafxmobile-plugin-ensemble

Git clone of JavaFX on iOS and Android
Java
8
star
23

ToME---t-engine4

Github fork of ToME/TE4
Lua
8
star
24

CardGameFramework

Prototype framework to create card games on the fly
Java
6
star
25

RxCurrying2

Simple currying for FunctionN and ConsumerN on RxJava2 [STABLE]
Java
5
star
26

RxErrorAlgebra

Java
4
star
27

ggwp

A port of GGPO (https://github.com/pond3r/ggpo) to Rust
Rust
4
star
28

printableheroes

JavaScript
3
star
29

DT3

DT3 Game Engine by Smells Like Donkey Software Inc.
C
3
star
30

DOT

The open source version of the DOT AI Engine.
C++
3
star
31

react-jus

A React Component for polyominos on a grid
2
star
32

RxFunctions2

Advanced Function composition to use with RxJava2 [STABLE]
Java
2
star
33

RxMemoization2

Simple Function result caching for RxJava [Stable]
Java
2
star
34

RxPartialApplication2

Simple partial application for FuncN and ActionN on RxJava 2.X [STABLE]
Java
2
star
35

RxConsumers

Simple Consumer composition to use with RxJava [STABLE]
Java
2
star
36

RxJava2Consumers

Copy of the missing Consumer interfaces in RxJava2 available in RxJava2Extensions [Stable]
Java
2
star
37

pnpcut

Q&D script to process cards in bulk to 3x3 A4
JavaScript
2
star
38

ludumdare31

Project for LD31
Java
1
star
39

Gameroom

Test room for github development
1
star
40

buildmancer

A build theorycrafting boadgame you can play offline!
TypeScript
1
star
41

byuu

byuu is a multi-system emulator focused on performance, features, and ease of use.
1
star
42

HexUtils

Some utilities for working with hexagons, mostly based on http://www.redblobgames.com/grids/hexagons/
Java
1
star
43

2DEngine

2d engine for iphone games
1
star