trains-planes-and-automobiles-talk



trains-planes-and-automobiles-talk

0 0


trains-planes-and-automobiles-talk

DroidCon Talk on Local Storage and Cross Application Development

On Github ukmadlz / trains-planes-and-automobiles-talk

/ rhyshort / ukmadlz

Trains, Planes & Automobiles

The Secret To Making Mobile Apps ... Mobile

Legal Disclaimer

  • © IBM Corporation 2015. All Rights Reserved.
  • The information contained in this publication is provided for informational purposes only. While efforts were made to verify the completeness and accuracy of the information contained in this publication, it is provided AS IS without warranty of any kind, express or implied. In addition, this information is based on IBM’s current product plans and strategy, which are subject to change by IBM without notice. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, this publication or any other materials. Nothing contained in this publication is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software.
  • References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or capabilities referenced in this presentation may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way. Nothing contained in these materials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you will result in any specific sales, revenue growth or other results.
  • If the text contains performance statistics or references to benchmarks, insert the following language; otherwise delete: Performance is based on measurements and projections using standard IBM benchmarks in a controlled environment. The actual throughput or performance that any user will experience will vary depending upon many factors, including considerations such as the amount of multiprogramming in the user's job stream, the I/O configuration, the storage configuration, and the workload processed. Therefore, no assurance can be given that an individual user will achieve results similar to those stated here.
  • If the text includes any customer examples, please confirm we have prior written approval from such customer and insert the following language; otherwise delete: All customer examples described are presented as illustrations of how those customers have used IBM products and the results they may have achieved. Actual environmental costs and performance characteristics may vary by customer.
  • Please review text for proper trademark attribution of IBM products. At first use, each product name must be the full name and include appropriate trademark symbols (e.g., IBM Lotus® Sametime® Unyte™). Subsequent references can drop “IBM” but should include the proper branding (e.g., Lotus Sametime Gateway, or WebSphere Application Server). Please refer to http://www.ibm.com/legal/copytrade.shtml for guidance on which trademarks require the ® or ™ symbol. Do not use abbreviations for IBM product names in your presentation. All product names must be used as adjectives rather than nouns. Please list all of the trademarks that you use in your presentation as follows; delete any not included in your presentation. IBM, the IBM logo, Lotus, Lotus Notes, Notes, Domino, Quickr, Sametime, WebSphere, UC2, PartnerWorld and Lotusphere are trademarks of International Business Machines Corporation in the United States, other countries, or both. Unyte is a trademark of WebDialogs, Inc., in the United States, other countries, or both.
  • If you reference Adobe® in the text, please mark the first use and include the following; otherwise delete: Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States, and/or other countries.
  • If you reference Java™ in the text, please mark the first use and include the following; otherwise delete: Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
  • If you reference Microsoft® and/or Windows® in the text, please mark the first use and include the following, as applicable; otherwise delete: Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.
  • If you reference Intel® and/or any of the following Intel products in the text, please mark the first use and include those that you use as follows; otherwise delete: Intel, Intel Centrino, Celeron, Intel Xeon, Intel SpeedStep, Itanium, and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.
  • If you reference UNIX® in the text, please mark the first use and include the following; otherwise delete: UNIX is a registered trademark of The Open Group in the United States and other countries.
  • If you reference Linux® in your presentation, please mark the first use and include the following; otherwise delete: Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of others.
  • If the text/graphics include screenshots, no actual IBM employee names may be used (even your own), if your screenshots include fictitious company names (e.g., Renovations, Zeta Bank, Acme) please update and insert the following; otherwise delete: All references to [insert fictitious company name] refer to a fictitious company and are used for illustration purposes only.

Who Are We?

Rhys Short - Software Engineer

rhyshort@uk.ibm.com

Mike Elsmore - Developer Advocate

mike.elsmore@uk.ibm.com

IBM Cloud Data Services

Follow Along

http://elsmore.me/trains-planes-and-automobiles-talk/

Demo

http://r.elsmore.me/1Um9wtF

http://elsmore.me/droidconro

Offline Apps

Cross platform

Android | iOS | Web

  • Rolling your own
  • A database
  • Sync tech
  • abstaction layer
  • exhusted lennoard, sad lennoard little ball of pain

Cross platform

Android | iOS | Web

Only following Android and Web

Another way…

Cloudant Sync Android Datastore

Rhys representing sensible code and Android Mike representing hacky code and Javascript

Get started

Installing

Android:

compile 'com.cloudant:cloudant-sync-datastore-android:latest.release'

Javascript:

npm install --save pouchdb
bower install --save pouchdb

Instantiating

Android:

DatastoreManager manager = new DatastoreManager(
  ctx.getDir("cloudantsync", Context.MODE_PRIVATE)
);
Datastore ds = manmager.openDatastore("droidConRo16");

Javascript:

var db = new PouchDB('my_database');

JSON Document

Android:

MutableDocumentRevision revision = new MutableDocumentRevision();
Map<String,String> body = new HashMap<String, String>();
body.put("event", "droidcon";
body.put("type", "conference");
body.put("date", "2016-03-12");
revision.body = DocumentBodyFactory.create(body);

Javascript:

var doc = {
  event: "droidcon",
  type: "conference",
  date: "2016-03-12"
}

Create

Android:

DocumentRevision rev = datastore.createDocumentFromRevision(revision);

Javascript:

db.post(doc, [options], [callback]);

db.post(doc, function (err, response) {
  if (err) { return console.log(err); }
  // handle response
});

Read

Android:

datastore.getDocument("droidcon");

Javascript:

db.get(docId, [options], [callback]);

db.get('droidcon', function(err, doc) {
  if (err) { return console.log(err); }
  // handle doc
});
Skip conflicts Don't talk too much detail on interceptors keep it simple talk more about arch in the round about here's how it all looks.

Update

Android:

DocumentRevision rev = datastore.getDocument("droidcon");
MutableDocumentRevision mutable = rev.mutableCopy();
Map<String,Object> body = rev.body.asMap();
body.put("talk","Planes, Trains & Automobiles");
mutable.body = DocumentBodyFactory.create(body);

rev = datastore.updateDocumentFromRevision(mutable);

Javascript:

db.put(doc, [docId], [docRev], [options], [callback]);

db.get('droidcon', function(err, doc) {
  if (err) { return console.log(err); }
  db.put({
    _id: 'droidcon',
    _rev: doc._rev,
    talk: "Planes, Trains & Automobiles"
  }, function(err, response) {
    if (err) { return console.log(err); }
    // handle response
  });
});

Delete / Destroy

Android:

datastore.deleteDocumentRevision(rev);

// Or

datastore.deleteDocument("droidcon");

Javascript:

db.remove(docId, [docRev], [options], [callback]);

db.get('droidcon', function(err, doc) {
  if (err) { return console.log(err); }
  db.remove(doc, function(err, response) {
    if (err) { return console.log(err); }
    // handle response
  });
});

That's the basics…now what?

Query

Android:

IndexManager indexManager = new IndexManager(datastore);

Object[] fields = {"conference"};
indexManager.ensureIndexed(Arrays.toList(fields), "conference");

Map<String,Object> selector = new HashMap<String,Object>();
selector.put("conference","droidcon");
QueryResult result = indexManager.find(selector);

for(DocumentRevision rev:result){
    // do something with the found document.
}

Query

Javascript Design Doc:

db.query(fun, [options], [callback]);

// create a design doc
var ddoc = {
  _id: '_design/index',
  views: {
    index: {
      map: function mapFun(doc) {
        if (doc.type) {
          emit(doc.type);
        }
      }.toString()
    }
  }
}

Query

Javascript MapReduce:

// save the design doc
db.put(ddoc, function (err) {
  if (err && err.status !== 409) {
    return console.log(err);
  }
  // ignore if doc already exists
  // find docs where type === 'conference'
  db.query('index', {
    key: 'conference',
    include_docs: true
  }, function (err, result) {
    if (err) { return console.log(err); }
    // handle result
  });
});

// Or use existing DDoc

Replication

Android:

URL remoteDB = new URL("http://example.com/db");

// pull
Replicator pull = ReplicatorBuilder.pull().from(remoteDB).to(datastore).build();
pull.start();

// push
Replicator push = ReplicatorBuilder.push().from(datastore).to(remoteDB).build();
push.start();

Javascript:

PouchDB.replicate(source, target, [options]);

db.replicate.to(remoteDB, [options]);
// or
db.replicate.from(remoteDB, [options]);

Changes

Android:

Changes changes = datastore.changes(0, 25);

for (DocumentRevision rev : changes.getResults()){
    // do something with the change
}

// get the next set of changes
changes = datastore.changes(changes.getLastSequence(),25);

//process those changes.

Changes

Javascript:

db.changes(options);

var changes = db.changes({
  since: 'now',
  live: true,
  include_docs: true
}).on('change', function(change) {
  // handle change
}).on('complete', function(info) {
  // changes() was canceled
}).on('error', function (err) {
  console.log(err);
});

changes.cancel();

Interceptors

public class LoggingInterceptor implements HttpConnectionRequestInterceptor,
    HttpConnectionResponseInterceptor {

    Logger logger = Logger.getLogger(LoggingInterceptor.class.getCanonicalName());

    @Override
    public HttpConnectionInterceptorContext interceptRequest(
        HttpConnectionInterceptorContext context) {

        HttpURLConnection connection = context.connection.getConnection();
        logger.info("Making request to "+connection.getURL();
        return context;

    }

    @Override
    public HttpConnectionInterceptorContext interceptResponse(
        HttpConnectionInterceptorContext context) {

        HttpURLConnection connection = context.connection.getConnection();

        String msg = "Request Complete: "+ connection.getURL()
        + "/" + connection.getResponseCode();

        logger.info(msg);
        return context;
}

Magic bit

CouchDB

- mention MVCC as part of replication.

Codez!

Android APK: https://github.com/rhyshort/droidcon.ro16 PouchDB WebApp: https://github.com/ukmadlz/droidconro App for API Keys: https://github.com/ukmadlz/apikeyapp

Round Up

Rhys Short

/rhyshort

rhyshort@uk.ibm.com

Mike Elsmore

/ukmadlz

mike.elsmore@uk.ibm.com

Questions?

Appendix

Replication Diagram

Conflicts

Caused By replication or cluster partition.

More detail: Blog post by Glynn Bird DevAdv @ IBM CDS https://cloudant.com/blog/introduction-to-document-conflicts-part-one

Create Exception

DocumentException

Primary Cause: - Document exists (Conflict)

Read Exception

DocumentNotFoundException

Update Exception

DocumentException

Casues:

  • Document not found (missing)
  • Conflict

Delete Destroy Exception

DocumentException

causes:

  • Document not found, missing
  • Conflict
© IBM Corporation 2015. All Rights Reserved.
0