{"id":17248946,"url":"https://github.com/pakoito/rxpaper2","last_synced_at":"2025-04-14T05:31:36.150Z","repository":{"id":48500916,"uuid":"82488211","full_name":"pakoito/RxPaper2","owner":"pakoito","description":"NoSQL storage with RxJava2 bindings [STABLE]","archived":false,"fork":false,"pushed_at":"2021-07-22T16:10:23.000Z","size":166,"stargazers_count":100,"open_issues_count":2,"forks_count":15,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-27T19:51:06.889Z","etag":null,"topics":["android","database","rxjava2"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pakoito.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-19T20:42:27.000Z","updated_at":"2023-03-04T14:48:36.000Z","dependencies_parsed_at":"2022-08-28T01:00:34.627Z","dependency_job_id":null,"html_url":"https://github.com/pakoito/RxPaper2","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakoito%2FRxPaper2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakoito%2FRxPaper2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakoito%2FRxPaper2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakoito%2FRxPaper2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pakoito","download_url":"https://codeload.github.com/pakoito/RxPaper2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248826595,"owners_count":21167718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","database","rxjava2"],"created_at":"2024-10-15T06:42:31.620Z","updated_at":"2025-04-14T05:31:35.866Z","avatar_url":"https://github.com/pakoito.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RxPaper2\n\n[![](https://jitpack.io/v/pakoito/RxPaper2.svg)](https://jitpack.io/#pakoito/RxPaper2)\n\nRxPaper is a [RxJava](https://github.com/ReactiveX/RxJava) wrapper for the cool [Paper](https://github.com/pilgr/Paper) library. It's a clean rewrite of the original [RxPaper](http://www.github.com/cesarferreira/rxpaper) library by [César Ferreira](http://www.github.com/cesarferreira).\n\n![Paper icon](https://raw.githubusercontent.com/pilgr/Paper/master/paper_icon.png)\n\nFor the RxJava1 version, please go to [RxPaper](https://www.github.com/pakoito/RxPaper).\n\n## Rationale\n\nSometimes 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.\n\nRxPaper 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](https://github.com/EsotericSoftware/kryo).\n\nThe Paper/Kryo combination supports some partial data structure changes. Check [Paper's README](https://github.com/pilgr/Paper#handle-data-structure-changes) for more information.\n\n## Usage\n\n### Object model handling\n\nRxPaper 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.\n\nI 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`.\n\nAs 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](https://github.com/pilgr/Paper#handle-data-structure-changes).\n\n### Threading\n\nAll operations are run on the [Scheduler](https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/1.%20Scheduling%20and%20threading.md#schedulers) 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.\n\n### Initialization\n\nBefore the library is usable it requires initializing the underlying Paper library. You only have to initialize RxPaper by calling:\n\n```java\nRxPaperBook.init(context);\n```\n\n### Working on a book\n\nRxPaper 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](https://github.com/pilgr/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](https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/1.%20Scheduling%20and%20threading.md#schedulers) provided in the constructor. To create an instance of RxPaper the library provides several flavours.\n\n```java\nRxPaperBook.with();\n```\n\nWorks with the default book, and executes operations on [`Schedulers.io()`](https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/1.%20Scheduling%20and%20threading.md#schedulers).\n\n```java\nRxPaperBook.with(Schedulers.newThread());\n```\n\nWorks with the default book, and executes operations on any provided scheduler.\n\n```java\nRxPaperBook.with(\"my_book_name\");\n```\n\nWorks with a custom book with the provided id/name, and executes operations on [`Schedulers.io()`](https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/1.%20Scheduling%20and%20threading.md#schedulers).\n\n```java\nRxPaperBook.with(\"my_book_name\", Schedulers.newThread());\n```\n\nWorks with a custom book with the provided id/name, and executes operations on any provided scheduler.\n\n```java\nRxPaperBook.withPath(myPath);\nRxPaperBook.withPath(myPath, scheduler);\nRxPaperBook.withPath(myPath, \"my_book_name\");\n```\n\nWorks with a custom storage location.\n\n### Writing a value\n\nWrite is a `Completable` operation, a subset of `Observable\u003cT\u003e` without a return value, just success/error. Completables can be converted back to Observables by using the operator `toObservable()`.\n\n```java\nRxPaperBook book = RxPaperBook.with(\"my-book\");\nCompletable write = book.write(key, value);\n// Because RxJava is lazily evaluated, the operation is not executed until the Observable is subscribed.\nwrite.subscribe(new CompletableObserver() {\n            @Override\n            public void onCompleted() {\n                // Operation suceeded\n            }\n\n            @Override\n            public void onError(Throwable e) {\n                // Operation failed\n            }\n\n            @Override\n            public void onSubscribe(Subscription d) {\n                // Called once on creation\n            }\n        });\n```\n\nEvery key written is stored as a file on the system under the folder specified by the book.\n\n### Reading a value\n\nReading is a `Single\u003cT\u003e` operation, a subset of `Observable\u003cT\u003e` 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:\n\n```java\nSingle\u003cComplexObject\u003e read = book.read(key);\nread.subscribe(new SingleSubscriber\u003cComplexObject\u003e() {\n            @Override\n            public void onSuccess(ComplexObject value) {\n                // Operation succeeded and returned a value\n            }\n\n            @Override\n            public void onError(Throwable error) {\n                // Operation failed\n            }\n        });\n\nComplexObject defaultValue = new ComplexObject();\nSingle\u003cComplexObject\u003e readOrDefault = book.read(key, defaultValue);\nreadOrDefault.subscribe(new SingleSubscriber\u003cComplexObject\u003e() {\n            @Override\n            public void onSuccess(ComplexObject value) {\n                // Operation succeeded and returned a value\n            }\n\n            @Override\n            public void onError(Throwable error) {\n                // Operation failed\n            }\n        });\n```\n\n`read(key)` fails with `IllegalArgumentException` if the key is not found. `read(key, defaultValue)` returns a default value if the key is not found.\n\nIf the subscriber is not of the same type as the value stored expect a `ClassCastException`.\n\nMake sure to read the rules on [how object models are handled](https://github.com/pakoito/RxPaper#object-model-handling) on the section above.\n\n#### Observing changes on a key\n\nAll write operations are naively forwarded into a `PublishSubject\u003c?\u003e` by default, which makes it possible to observe all changes for a specific key. Observing is a `Flowable\u003cT\u003e` operation that never completes.\n\n```java\nFlowable\u003cComplexObject\u003e observe = book.observe(key, ComplexObject.class);\nobserve.subscribe(new Subscriber() { /* ... */ });\n```\n\nObserve 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.\n\n#### Contains\n\nContains is a `Single\u003cBoolean\u003e` operation that returns true if the key is on the current book, or false otherwise.\n\n```java\nSingle\u003cBoolean\u003e contains = book.contains(key);\ncontains.subscribe(new SingleSubscriber\u003cBoolean\u003e() { /* ... */ });\n```\n\n#### Delete\n\nDelete 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.\n\n```java\nCompletable delete = book.delete(key);\ndelete.subscribe(new CompletableObserver() { /* ... */ });\n```\n\n#### Keys\n\nKeys is a `Single\u003cList\u003cString\u003e\u003e` operation that returns a list of all keys stored on the current book.\n\n```java\nSingle\u003cList\u003cString\u003e\u003e keys = book.keys();\nexists.subscribe(new SingleSubscriber\u003cList\u003cString\u003e\u003e() { /* ... */ });\n```\n\n#### GetPath\n\nReturns the path to the current book. Note that the path will not exist until any value is saved in the book. \n\n```java\nSingle\u003cString\u003e path = book.getPath();\npath.subscribe(new SingleSubscriber\u003cString\u003e() { /* ... */ });\n```\n\nReturns the path to the key in the current book. Note that the path will not exist until a value is saved for that key. \n\n```java\nSingle\u003cString\u003e pathKey = book.getPath(\"my_key\");\npathKey.subscribe(new SingleSubscriber\u003cString\u003e() { /* ... */ });\n```\n\n#### Destroy\n\nDestroy is a `Completable` operation that deletes all keys and values on the current book.\n\n```java\nCompletable destroy = book.destroy();\ndestroy.subscribe(new CompletableObserver() { /* ... */ });\n```\n\n## Distribution\n\nAdd as a dependency to your `build.gradle`\n\n```groovy\n    repositories {\n        ...\n        maven { url \"https://jitpack.io\" }\n        ...\n    }\n    \n    dependencies {\n        ...\n        compile 'com.github.pakoito:RxPaper2:1.6.0'\n        ...\n    }\n```\n\nor to your `pom.xml`\n\n```xml\n    \u003crepositories\u003e\n        \u003crepository\u003e\n            \u003cid\u003ejitpack.io\u003c/id\u003e\n            \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n        \u003c/repository\u003e\n    \u003c/repositories\u003e\n    \n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.pakoito\u003c/groupId\u003e\n        \u003cartifactId\u003eRxPaper2\u003c/artifactId\u003e\n        \u003cversion\u003e1.6.0\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\n## License\n\nCopyright (c) 2019 pakoito \u0026 2015 César Ferreira\n\nThe MIT License (MIT)\n\nSee LICENSE.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpakoito%2Frxpaper2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpakoito%2Frxpaper2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpakoito%2Frxpaper2/lists"}