• This repository has been archived on 11/Mar/2022
  • Stars
    star
    267
  • Rank 153,621 (Top 4 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created almost 11 years ago
  • Updated almost 3 years ago

Reviews

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

Repository Details

A JSON-based document datastore for Android applications

โš ๏ธ NO LONGER MAINTAINED โš ๏ธ

This library is end-of-life and no longer supported.

This repository will not be updated. The repository will be kept available in read-only mode. If you are interested in continuing development efforts please see the list of forks for alternatives.

For FAQs and additional information please refer to the Cloudant blog.

Cloudant Sync - Android Datastore

Build Status

Artifact Links
Core maven-central-core javadoc-core
Android maven-central-android javadoc-android
Android (encryption) maven-central-android-encryption javadoc-android-encryption
Java SE maven-central-javase javadoc-javase

Applications use Cloudant Sync to store, index and query local JSON data on a device and to synchronise data between many devices. Synchronisation is under the control of the application, rather than being controlled by the underlying system. Conflicts are also easy to manage and resolve, either on the local device or in the remote database.

Cloudant Sync is an Apache CouchDBโ„ข replication-protocol-compatible datastore for devices that don't want or need to run a full CouchDB instance. It's built by Cloudant, building on the work of many others, and is available under the Apache 2.0 licence.

The API is quite different from CouchDB's; we retain the MVCC data model but not the HTTP-centric API.

This library is for Android and Java SE; an iOS version is also available.

Using in your project

The library is published via Maven Central and using it in your project should be as simple as adding it as a dependency via maven or gradle.

There are currently four jar files for the datastore:

  • cloudant-sync-datastore-core: the main datastore classes.
  • cloudant-sync-datastore-android: Android specific classes.
  • cloudant-sync-datastore-android-encryption: Android encryption specific classes.
  • cloudant-sync-datastore-javase: Java SE specific classes.

Gradle or Maven

Add the maven repo and a compile time dependency on the appropriate datastore artifact. The datastore artifact dependency will include its other required dependencies and is different depending on the target use case as shown here:

  1. Target is Android. If you also want datastore encryption see 2.
    • Gradle
    repositories {
        mavenLocal()
        mavenCentral()
    }
    
    dependencies {
        compile group: 'com.cloudant', name: 'cloudant-sync-datastore-android', version:'latest.release'
    }
    • Maven
    <project>
        <repositories>
        ...
        </repositories>
    
        <dependencies>
            <dependency>
                <groupId>com.cloudant</groupId>
                <artifactId>cloudant-sync-datastore-android</artifactId>
                <version>latest.release</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </project>
  2. Target is Android and you want datastore encryption.
    • Gradle
    repositories {
        mavenLocal()
        mavenCentral()
    }
    
    dependencies {
        compile group: 'com.cloudant', name: 'cloudant-sync-datastore-android-encryption', version:'latest.release'
    }
    • Maven
    <project>
        <repositories>
        ...
        </repositories>
    
        <dependencies>
            <dependency>
                <groupId>com.cloudant</groupId>
                <artifactId>cloudant-sync-datastore-android-encryption</artifactId>
                <version>latest.release</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </project>
  3. Target is Java SE.
    • Gradle
    repositories {
        mavenLocal()
        mavenCentral()
    }
    
    dependencies {
        compile group: 'com.cloudant', name: 'cloudant-sync-datastore-javase', version:'latest.release'
    }
    • Maven
    <project>
        <repositories>
        ...
        </repositories>
    
        <dependencies>
            <dependency>
                <groupId>com.cloudant</groupId>
                <artifactId>cloudant-sync-datastore-javase</artifactId>
                <version>latest.release</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </project>

You can see a fuller example in the sample application's build.gradle.

Note: Older versions than 0.3.0 had a separate Mazha jar. This was rolled into the main jar for distribution simplicity. The dependency needs removing from gradle and maven build files.

Tested Platforms

The library is regularly tested on the following platforms:

Android (via emulator):

  • API Level 15
  • API Level 16
  • API Level 17
  • API Level 18
  • API Level 19
  • API Level 21

Java:

  • 1.8 (Java 8)

Example application

There is a sample Android application.

See the accompanying README.md for detailed instructions of how to run and build the sample.

Overview of the library

Once the libraries are added to a project, the basics of adding and reading a document are:

// Obtain storage path on Android
File path = getApplicationContext().getDir("documentstores", Context.MODE_PRIVATE);

try {
    // Obtain reference to DocumentStore instance, creating it if doesn't exist
    DocumentStore ds = DocumentStore.getInstance(new File(path, "my_document_store"));

    // Create a document
    DocumentRevision revision = new DocumentRevision();
    Map<String, Object> body = new HashMap<String, Object>();
    body.put("animal", "cat");
    revision.setBody(DocumentBodyFactory.create(body));
    DocumentRevision saved = ds.database().create(revision);

    // Add an attachment -- binary data like a JPEG
    UnsavedFileAttachment att1 =
            new UnsavedFileAttachment(new File("/path/to/image.jpg"), "image/jpeg");
    saved.getAttachments().put("image.jpg", att1);
    DocumentRevision updated = ds.database().update(saved);

    // Read a document
    DocumentRevision aRevision = ds.database().read(updated.getId());
} catch (DocumentStoreException dse) {
    System.err.println("Problem opening or accessing DocumentStore: "+dse);
}

Extensive code samples can be found in the CRUD samples class.

You can also subscribe for notifications of changes in the database, which is described in the events documentation.

The javadoc for the latest release version of the library is the definitive reference for the library. Each jar contains the full javadoc for itself and the other jars - this is for convenience at the slight expense of duplication.

All private API classes are in the com.cloudant.sync.internal package. API users should not use these classes as fields, method signatures, and implementation details may be subject to change. Directly using the classes in these packages or calling their methods is not supported.

Everything else under com.cloudant.sync is public API and subject to the usual versioning and deprecation practices. API users can expect this to be a stable API. This behaviour follows the Semantic Versioning 2.0.0 specification.

Classes in the com.cloudant.sync.internal package are not visible in javadoc.

Replicating Data Between Many Devices

Replication is used to synchronise data between the local datastore and a remote database, either a CouchDB instance or a Cloudant database. Many datastores can replicate with the same remote database, meaning that cross-device synchronisation is achieved by setting up replications from each device to the remote database.

Replication is simple to get started in the common cases:

URI uri = new URI("https://apikey:[email protected]/my_database");
DocumentStore ds = DocumentStore.getInstance(new File(path, "my_datastore"));

// Replicate from the local to remote database
Replicator replicator = ReplicatorBuilder.push().from(ds).to(uri).build();

// Fire-and-forget (there are easy ways to monitor the state too)
replicator.start();

Read more in the replication docs.

Authentication

Sync-android uses session cookies by default to authenticate with the server if credentials are provided with in the URL.

To use an IAM API key on IBM Bluemix, use the iamApiKey method when building the Replicator object:

Replicator replicator = ReplicatorBuilder.push()
  .from(ds)
  .to(uri)
  .iamApiKey("exampleApiKey")
  .build();

If you want more fine-grained control over authentication, provide an interceptor to perform the authentication for each request. For example, if you are using middleware such as Envoy, you can use the BasicAuthInterceptor to add basic authentication to requests.

Example:

Replicator replicator = ReplicatorBuilder.push()
  .from(ds)
  .to(uri)
  .addRequestInterceptors(new BasicAuthInterceptor("yourUsername:yourPassword"))
  .build();

Other authentication mechanisms such as proxy authentication can also used by either using the in built interceptors (see the com.cloudant.http.interceptors package) or by creating your own class which conforms to HttpConnectionRequestInterceptor or HttpConnectionResponseInterceptor.

Finding data

Once you have thousands of documents in a database, it's important to have efficient ways of finding them. We've added an easy-to-use querying API. Once the appropriate indexes are set up, querying is as follows:

DocumentStore ds; // instance obtained previously
Map<String, Object> query = new HashMap<String, Object>();
query.put("name", "mike");
query.put("pet", "cat");
QueryResult result = ds.query().find(query);

for (DocumentRevision revision : result) {
    // do something
}

See Index and Querying Data.

Conflicts

An obvious repercussion of being able to replicate documents about the place is that sometimes you might edit them in more than one place at the same time. When the databases containing these concurrent edits replicate, there needs to be some way to bring these divergent documents back together. Cloudant's MVCC data-model is used to do this.

A document is really a tree of the document and its history. This is neat because it allows us to store multiple versions of a document. In the main, there's a single, linear tree -- just a single branch -- running from the creation of the document to the current revision. It's possible, however, to create further branches in the tree. At this point your document is conflicted and needs some surgery to resolve the conflicts and bring it back to full health.

Learn more about this essential process in the conflicts documentation.

Issues

Before opening a new issue please consider the following:

  • Only the latest release is supported. If at all possible please try to reproduce the issue using the latest version.
  • Please check the existing issues to see if the problem has already been reported. Note that the default search includes only open issues, but it may already have been closed.
  • Cloudant customers should contact Cloudant support for urgent issues.
  • When opening a new issue here in github please complete the template fully.

Known Issues

Some users on certain older versions of Android have reported the following exception:

java.lang.NoClassDefFoundError: javax/annotation/Nullable

To fix this issue, add the following dependency to your application's build.gradle:

compile 'com.google.code.findbugs:jsr305:3.0.0'

Related documentation

Development

For information about contributing, building, and running tests see the CONTRIBUTING.md.

Contributors

See CONTRIBUTORS.

License

See LICENSE.

More Repositories

1

bigcouch

Putting the 'C' back in CouchDB
Python
565
star
2

nodejs-cloudant

Cloudant Node.js client library
JavaScript
255
star
3

mango

MongoDB API layer for CouchDB
Erlang
200
star
4

CDTDatastore

Cloudant Sync iOS datastore library.
Objective-C
175
star
5

python-cloudant

A Python library for Cloudant and CouchDB
Python
163
star
6

java-cloudant

A Java client for Cloudant
Java
79
star
7

meteor-couchdb

Meteor database driver for CouchDB and Cloudant
JavaScript
53
star
8

haengematte

example applications for basic crud features in different languages
Java
45
star
9

swift-cloudant

A Swift Lang client for Cloudant and CouchDB
Swift
42
star
10

sabisu

A sensu web UI powered by Cloudant
JavaScript
31
star
11

cloudant_cookbooks

Cloudant's Chef Cookbooks
Ruby
27
star
12

fabric

Routing and proxying library app for BigCouch
Erlang
20
star
13

mem3

BigCouch cluster membership layer
Erlang
18
star
14

rexi

Lightweight RPC server
Erlang
17
star
15

couch_replicator

Erlang
16
star
16

sensu-trapd

snmp trap to sensu event
Python
15
star
17

jsindexer

An example CouchApp based CouchDB javascript view that creates and inverted index using CouchDB map-reduce
JavaScript
15
star
18

openxc-js

Chrome App for OpenXC
JavaScript
13
star
19

chttpd

A cluster-aware httpd layer for CouchDB
Erlang
12
star
20

twig

Logger
Erlang
12
star
21

monic

Erlang
7
star
22

sensu-run

Execute sensu checks locally on demand
Ruby
6
star
23

sync-cordova-plugin

Cordova plugin for Cloudant Sync for Android and iOS
Objective-C
6
star
24

ilcli

I like command-line interfaces
Python
5
star
25

couch

Erlang
4
star
26

nifile

NIF based POSIX file IO for Erlang
C
4
star
27

lager_rsyslog

An Rsyslog backend for Lager
Erlang
4
star
28

jwtf

JSON Web Token Functions
Erlang
3
star
29

ets_lru

LRU implementation using ETS
Erlang
3
star
30

sobhuza

Implementation of Stable Leader Election algorithm
Erlang
3
star
31

objective-cloudant

Objective-C Cloudant client library
Objective-C
3
star
32

pouch_gpkg

OWS10 GeoPackage to Pouch
JavaScript
3
star
33

hdfs

Open source, first hackish pass at exporting to Hadoop using the _changes feed.
Python
3
star
34

erl_spatial

a wrapper around libspatialindex
C++
2
star
35

ohai_plugins

Plugins for Opscode's ohai, a part of chef.
Ruby
2
star
36

delegated_auth

Allow an external service to choose name and roles for A/A.
Erlang
2
star
37

ddoc_cache

Cache design docs on each node
Erlang
2
star
38

porkrind

Hamcrest matchers for Erlang
Erlang
1
star
39

public-examples

Public Examples
Python
1
star
40

config

CouchDB config layer
Erlang
1
star
41

changes-feeds-example

Shell
1
star
42

fdblucene-perf

Performance tests for fdblucene
Java
1
star
43

gambrelli

Erlang term encoder and decoder for Akka
Scala
1
star
44

wkb_writer

OGC Well Known Binary (WKB) writer in Erlang
Erlang
1
star
45

knit

Erlang tool for generating release and upgrade packages
Erlang
1
star