DZone
Database Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Database Zone > NoSQL on Android

NoSQL on Android

Tony Siciliani user avatar by
Tony Siciliani
·
Jun. 20, 14 · Database Zone · Tutorial
Like (7)
Save
Tweet
27.02K Views

Join the DZone community and get the full member experience.

Join For Free

There are various NoSQL solutions for mobile platforms such as the iOS and Android. Here, we will look at Couchbase Lite (CBL – the successor of TouchDB), a lightweight, full-featured, embedded JSON database.

Why a full-feature database instead of just a wrapper for a cloud service? Basically, responsiveness. The idea is that the application should always be available to users even when the network is down or slow. Of course, being able to work with data locally also means that we’ll have to sync with the server at some point.

Note that CBL is significantly different from Apache CouchDB despite the “Couch” part.

Now, let’s get down to business and create a small Android application (entire code available onGitHub) which sets up a database using CBL’s Native API, and run basic CRUD operations.

After going through a relatively easy setup ( this one is for good old Eclipse users, that one for Android Studio fans), let’s start by writing some code:

import com.couchbase.lite.*;
import com.couchbase.lite.android.AndroidContext;
/** Database wrapper*/
public class CbDatabase {
private Database database;
private Manager manager;
/** Ctor Setup */
public CbDatabase(String dbname)
throws IOException, CouchbaseLiteException {
// 1. use default settings (read/write access)
manager = new Manager( new AndroidContext(ctx), 
Manager.DEFAULT_OPTIONS );
// 2. Check database name given by user
// No upper case allowed in CBL!
// Only the following characters are valid:
// abcdefghijklmnopqrstuvwxyz0123456789_$()+-/
if ( ! Manager.isValidDatabaseName(dbname)) {
// report...
return;
} 
// 3. Get existing db with that name
// or create a new one if it doesn't exist
database = manager.getDatabase(dbname);
}
//...more methods to come
}

The code above uses a Manager to set up a database with a valid name. A CBL Database is basically a container for documents. A Manager can create several different databases, each with its own namespace. Here’s how to release all the resources:

/** */
public void close(){
if(manager != null){
manager.close();
}
}

Once given the Database object, we are now ready to do CRUD operations on it:

/** C-rud */
public String create( Map<String, Object> docContent )
throws CouchbaseLiteException {
// create an empty document
Document doc = database.createDocument();
// add content to document and save it
doc.putProperties(docContent);
return doc.getId();
}

A CBL Document is the primary entity stored in a database, and has the following attributes:

  • A unique ID (_id property) which can be automatically generated as a UUID
  • A revision ID (_rev property) to keep track of updates
  • A set of key/value pairs forming the body of the Document

Once created, we can retrieve a Document’s content by its id:

/** c-R-ud */
public Map<String, Object> retrieve(String docId){
return database.getDocument(docId)
.getProperties();
}

We can update an existing key/value pair entry in a Document by using a callback:

/** cr-U-d (auto-retry) */
public void update( final String key, final Object value,
String docId )
throws CouchbaseLiteException {
// retrieve the document from the database
Document doc = database.getDocument(docId);
doc.update(new Document.DocumentUpdater() {
@Override
/** This may be called more than once */
public boolean update(UnsavedRevision newRevision) {
Map<String, Object> properties = newRevision.getUserProperties();
properties.put(key, value);
newRevision.setUserProperties(properties);
return true;
}
});
}

The method retries automatically the update in case of write conflicts by re-reading the Document and re-calling the callback method. That process will continue until the write succeeds. As its name implies, UnsavedRevision is a mutable copy to work with until data is finally persisted to the database.
Deleting a Document is pretty straightforward. Here, we do it by its id:

/** cru-D */
public boolean delete(String docId)
throws CouchbaseLiteException {
// retrieve the document from the database
Document doc = database.getDocument(docId);
// delete the document
doc.delete();
return  doc.isDeleted();
}

Deleting the Document will create a new revision called the “tombstone” (no kidding). It will be marked as deleted so that its status can be replicated to a server when doing a sync. As for updates, this can lead to conflicts if other users made changes to the same Document. In that case, the decision to retry the delete is left to us.

We are now ready to use this wrapper class in our project. First, let’s define our use case: let’s say we need to store locally some user data for our mobile games, like the user email, when the user registered in our system, and a bunch of game scores. Here’s a quick test we can run in our main Activity’s onCreate() method. First, let’s input some data:

// get the current date and time
Date now = new Date();
String nowString = DateFormat.getDateTimeInstance(
DateFormat.LONG, DateFormat.LONG).format(now);
// game scores
List<Double> scores = new ArrayList<Double>();
scores.add(190.00);
scores.add(210.00);
scores.add(250.00);
scores.add(275.00);
// create an object that contains data for a document
Map<String, Object> docContent = new HashMap<String, Object>();
docContent.put("email", "Nomad@nomad.com");
docContent.put("registered", nowString);
docContent.put("scores", scores);

Now, the database operations:

try{
CbDatabase db = new CbDatabase("testdb");
// 1. Create
String docId = db.create(docContent);
// 2. Retrieve
Map<String, Object> docContent = db.retrieve(docId);
// 3. Update
scores.add(350.00);
db.update("scores", scores, docId);
// 4. Delete
boolean deleted = db.delete(docId);
assert(deleted == true);
}
catch (Exception e) {
// handle here...
}
finally{
if(db != null){
db.close();
}
}

Here are the corresponding JSON Documents for Retrieve and Update:

// retrieved
{
_rev=1-1ef4c4618a712cdf437d4b0c92594ddc,
_id=69fdcb83-1774-4a3f-9e88-b298d3c7304a,
scores=[190.0, 210.0, 250.0, 275.0],
email=Nomad@nomad.com,
registered=June 18, 2014 11:03:18 AM GMT+02:00
}
//--------------------------------------------
// updated scores: note the change in revision 
{
_rev=2-23e6d83d243f80c03b17c4160d511e16,
scores=[190.0, 210.0, 250.0, 275.0, 350.0],
_id=69fdcb83-1774-4a3f-9e88-b298d3c7304a,
email=Nomad@nomad.com,
registered=June 18, 2014 11:03:18 AM GMT+02:00
}

That’s it. Further code details are on GitHub. We just scratched the surface of CBL with this very basic introduction. Unfortunately, the CBL online documentation for Android is incomplete at this time, compared to the one for the iOS. Anyway, there are other important CBL features like adding attachments, Views & Queries, replication (Server & P2P), a REST API, etc. Those would be the subjects of future articles.

Database Android (robot) Document NoSQL

Published at DZone with permission of Tony Siciliani, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • DZone's Article Submission Guidelines
  • Spring, IoC Containers, and Static Code: Design Principles
  • Which Backend Frameworks Are Impacting Web App Development Immensely?
  • Open Source Monitoring and Metrics Landscape

Comments

Database Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo