CouchDB Mobile - From Couch to 5K in 1 Hour
Upcoming SlideShare
Loading in...5
×
 

CouchDB Mobile - From Couch to 5K in 1 Hour

on

  • 7,006 views

In this talk, I explain how to use CouchDB mobile to connect your iPhone or Android phone with a a remote ChouchDB to build a RunKeeper clone. The code for this talk is available at ...

In this talk, I explain how to use CouchDB mobile to connect your iPhone or Android phone with a a remote ChouchDB to build a RunKeeper clone. The code for this talk is available at https://github.com/peterfriese/CouchTo5K

Statistics

Views

Total Views
7,006
Views on SlideShare
6,696
Embed Views
310

Actions

Likes
3
Downloads
53
Comments
0

8 Embeds 310

http://lanyrd.com 263
https://twitter.com 26
http://www.flashquix.com 7
https://si0.twimg.com 5
http://coderwall.com 3
http://www.linkedin.com 3
http://us-w1.rockmelt.com 2
http://zootool.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

CouchDB Mobile - From Couch to 5K in 1 Hour CouchDB Mobile - From Couch to 5K in 1 Hour Presentation Transcript

  • 44Peter Friese / Stefan Reichert, Zühlke EngineeringCouchDB mobileFrom Couch To 5k in 1 Hour
  • Peter Friese @peterfriese peter.friese@zuehlke.com xing.to/peter http://peterfriese.de
  • Stefan Reichert @stefanreichertstefan.reichert@zuehlke.com xing.to/stefanreicherthttp://blog.wickedshell.net/
  • What we will cover today 1 What is CouchDB? 2 Serious amount of demos! 3 Couch25K - A Runner’s App
  • What is CouchDB? 1
  • CouchDB is...CouchDB is... A NoSQL Database.
  • CouchDB is... Document-Oriented. { ! "name": "Peter", ! "company": "Zühlke Engineering", ! "email": "peter.friese@zuehlke.com", ! "languages": [ ! ! "Objective-C", ! ! "Java", ! ! "C#", ! ! "JavaScript" ! ] }
  • CouchDB is... Schema-Free. Put anything you like into your CouchDB. Really.
  • CouchDB is... Erlang-Powered.
  • CouchDB is... RESTful. GET PUT Fully embraces POST HTTP verbs DELETE
  • CouchDB uses...http://research.google.com/archive/mapreduce.html Map/Reduce (JavaScript).
  • CouchDB uses... Map/Reduce (JavaScript).Input{"ip": "212.23.45.12","traffic": “18278", date: “2012-03-11”},{"ip": "74.12.345.1","traffic": “345", date: “2012-03-11”},{"ip": "212.23.45.12","traffic": “112244", date: “2012-03-12”},{"ip": "212.23.45.12","traffic": “8657", date: “2012-03-13”},{"ip": "74.12.345.12","traffic": “12", date: “2012-03-12”},{"ip": "10.122.111.22","traffic": “122222", date: “2012-03-11”}
  • CouchDB uses... Map/Reduce (JavaScript).Mapper Input for Reducer212.23.45.12 18278 212.23.45.12 1827874.12.345.1 345 212.23.45.12 112244212.23.45.12 112244 212.23.45.12 8657212.23.45.12 865774.12.345.1 12 74.12.345.1 1210.122.111.22 122222 74.12.345.1 345 10.122.111.22 122222
  • CouchDB uses... Map/Reduce (JavaScript).Input for Reducer After Reduce212.23.45.12 18278 212.23.45.12 139179212.23.45.12 112244212.23.45.12 865774.12.345.1 12 74.12.345.1 35774.12.345.1 34510.122.111.22 122222 10.122.111.22 122222
  • CouchDB features... Robust Replication.
  • CouchDB features... Robust Replication. Laptop Phone Server
  • Demos 2
  • Calling Home curl localhost:5984{"couchdb":"Welcome","version":"1.1.0"}
  • Creating a New DB curl -X PUT localhost:5984/helloworld {"ok":true}
  • Deleting a Database curl -X DELETE http:// localhost:5984/helloworld {"ok":true}
  • Creating a New Document curl -X POST -H "Content-Type: application/json" localhost:5984/helloworld -d @peter.json {"ok":true,"id":"f8e42aaa4bc77124c28 6be13f000054e","rev":"1-4dc37117e0da 26d9c50dc92d4cbb04cc"}
  • Curious? GET Your Document! curl http://localhost:5984/helloworld/ f8e42aaa4bc77124c286be13f000054e { "_id": "f8e42aaa4bc77124c286be13f000054e", "_rev": "1-4dc37117e0da26d9c50dc92d4cbb04cc", "name": "Peter", "company": "Zühlke Engineering", "email": "peter.friese@zuehlke.com" }
  • Anatomy of a Document{ "_id": "f8e42aaa4bc77124c286be13f000054e", "_rev": "1-4dc37117e0da26d9c50dc92d4cbb04cc", "name": "Peter", "company": "Zühlke Engineering", "email": "peter.friese@zuehlke.com"} UUID - very unique identifier
  • Anatomy of a Document { "_id": "f8e42aaa4bc77124c286be13f000054e", "_rev": "1-4dc37117e0da26d9c50dc92d4cbb04cc", "name": "Peter", "company": "Zühlke Engineering", "email": "peter.friese@zuehlke.com" }revision revision hash (body,number counter attachment, _deleted flag)
  • Welcome to Futon! Admin interface for CouchDB CRUD for Documents Manage Views Manage Replication
  • Couch25K - A Runner’s App 3
  • Basic Idea 2-way 2-way Phone IrisCouch Phone
  • CouchDB Mobile n e ? P h o o u r n y o
  • CouchDB MobileYour app CouchCocoa lib Ektorp lib Your app CouchDB CouchDB
  • CouchDB Mobile Your app CouchCocoa lib Ektorp lib Your app TouchDB lib TouchDB lib SQlite SQlite
  • CouchDB Mobile “TouchDB is a lightweight CouchDB- compatible database engine suitable for embedding into mobile or desktop apps. Think of it this way: If CouchDB is MySQL, then TouchDB is SQLite.” - Jens Alfke, Couchbase Labs
  • Start a Local Couch CouchTouchDBServer *server = [CouchTouchDBServer sharedInstance]; NSAssert(!server.error, @"Error initializing TouchDB server: %@", server.error); self.database = [server databaseNamed:@"couch25k"]; NSError *error; if (! [self.database ensureCreated:&error]) { // raise error self.connected = false; }
  • Start a Local Couchtry { TDServer touchDBServer = new TDServer(filesDir);! HttpClient httpClient = new TouchDBHttpClient(touchDBServer); CouchDbInstance couchDBInstance = new StdCouchDbInstance(httpClient);! CouchDbConnector couchDBConnector = couchDBInstance.createConnector(COUCH25K_DB,true);! ...} catch (IOException e) {! Log.e(TAG, "Error starting TDServer", e);}
  • Trackpoints { "run": "run-peterfriese-19", "user": "peterfriese", "lon": "9.990512659959458", "time": "2012-03-24 07:39:27 +0000", "lat": "53.73176022303823" }
  • Saving a TrackpointNSDictionary *trackpointProperties = [NSDictionary dictionaryWithObjectsAndKeys: (...)CouchDocument *trackpointDocument = [database untitledDocument];RESTOperation* op = [trackpointDocument putProperties:trackpointProperties];[op onCompletion: ^{ if (op.error) NSLog(@"Couldnt save the new item"); }];[op start];
  • Saving a TrackpointEktorp: JPA for CouchDB public class TrackPoint extends CouchDbDocumentRepository Support public class TrackPointRepository extends ! CouchDbRepositorySupport<TrackPoint>... so saving a TrackPoint is pretty easy trackPointRepository.add(trackPoint);
  • Sync with the ServerNSURL *url = [NSURL URLWithString: @"http://peterfriese.iriscouch.com/couch25k"];[self.database replicateWithURL:url exclusively: YES];
  • Sync with the ServerPull from Server ReplicationCommand commandPull = new ReplicationCommand.Builder() .source(COUCH25K_REMOTE_DB) .target(COUCH25K_DB) .continuous(true).build(); try { couchDBInstance.replicate(commandPull); } catch (Exception exception) { Log.e(TAG, exception.getMessage(), exception); }
  • Sync with the ServerPush to Server ReplicationCommand commandPush = new ReplicationCommand.Builder() .source(COUCH25K_DB) .target(COUCH25K_REMOTE_DB) .continuous(true).build(); try { couchDBInstance.replicate(commandPush); } catch (Exception exception) { Log.e(TAG, exception.getMessage(), exception); }
  • Demo
  • Display List of Runs (JavaScript) Map Reduce function(keys, values) function(doc) { { emit(doc.run, 1); return sum(values); } } run-1 1 run-1 1 run-1 3 run-1 1 run-2 2 run-2 1 run-2 1
  • Display List of Runs (Obj-C)Map[design defineViewNamed: @"runs" mapBlock: MAPBLOCK({ id run = [doc objectForKey:@"run"]; if (run) emit(run, nil);})ReducereduceBlock:REDUCEBLOCK({ return [NSNumber numberWithInt:values.count];})
  • Display List of Runs (Java)Mapnew TDViewMapBlock() { public void map(Map<String, Object> doc, TDViewMapEmitBlock emitter) { if (doc.containsKey("run")) { emitter.emit(doc.get("run"), doc.get("_id")); } }}
  • Display List of Runs (Java)(Re-) reducenew TDViewReduceBlock() { public Object reduce(List<Object> keys, List<Object> values, boolean rereduce) { if (rereduce) { int sum = 0; for (Object object : values) { sum += (Integer) object; } return sum; } return values.size(); }};
  • Filtering Peter Stefan Filter by name sync 2-way sync 2-wayPhone IrisCouch Phone 2
  • FilteringCouchDBby_user: function(doc, rq) { if(doc.user == rq.query.username) { return true; } return false; }
  • FilteringNSArray *replications = [self.database replicateWithURL:url exclusively: YES];CouchPersistentReplication *from = [replications objectAtIndex:0];from.continuous = YES;from.filter = @"couch25k/by_user";NSDictionary *filterParams = [NSDictionary dictionaryWithObjectsAndKeys: @"peterfriese", @"username", nil];from.query_params = filterParams;
  • FilteringMap<String, Object> queryParams = new HashMap<String, Object>();queryParams.put("username", "stefanreichert");ReplicationCommand commandPull = new ReplicationCommand.Builder() .source(COUCH25K_REMOTE_DB) .target(COUCH25K_DB).continuous(true) .filter("by_user") .queryParams(queryParams).build();try {! couchDBInstance.replicate(commandPull);} catch (Exception e) {! Log.e(TAG, exception.getMessage(), e);}
  • Maps, please!
  • Query Trackpoints by RunMapmapBlock: MAPBLOCK({ NSString *run = (NSString *)[doc objectForKey:@"run"]; id time = [doc objectForKey:@"time"]; NSMutableArray *key = [[NSMutableArray alloc] init]; [key addObject:run]; [key addObject:time]; emit(key, doc);})[run-peter-1, 2012-03-23 10:10] {lat:..., lon:...}[run-peter-1, 2012-03-23 10:11] {lat:..., lon:...}[run-peter-2, 2012-03-26 20:05] {lat:..., lon:...}[run-peter-2, 2012-03-26 20:06] {lat:..., lon:...}[run-peter-2, 2012-03-26 10:07] {lat:..., lon:...}
  • Query Trackpoints by RunQueryCouchQuery *query = [[self.database designDocumentWithName: @"couch25k"] queryViewNamed: @"waypoints_by_run"];CouchLiveQuery *livequery = [query asLiveQuery];[livequery setStartKey: [NSArray arrayWithObjects:self.runKey, nil]];[query setEndKey: [NSArray arrayWithObjects:self.runKey, @"ZZZ", nil]];
  • Query Trackpoints by RunMapnew TDViewMapBlock() { public void map(Map<String, Object> document, TDViewMapEmitBlock emitter) { if (document.containsKey("run")) { document.get("run"), document.get("_id")); }}
  • Query Trackpoints by RunQueryViewQuery viewQuery = new ViewQuery().designDocId("_design/TrackPoint") .viewName("trackpoint_by_run") .key(runId);ViewResult result = db.queryView(viewQuery);List<TrackPoint> trackPoints = new ArrayList<TrackPoint>();for (Row row : result.getRows()) { TrackPoint trackPoint = get(row.getValue()); trackPoints.add(trackPoint);}return trackPoints;
  • And finally... http://josephta.me/about-joseph-tame/
  • ... a Tribute to Steve Jobs GPX of J cou rtes ose y ph - T Tam han e ks! http://bit.ly/HbDRod
  • Relax! 44
  • Thanks!Peter FriesePrincipal Consultant rt @peterfrZühlke Engineering GmbH @stef anreiche ieseAm Sandtorkai 6620457 Hamburg Availa ble fo+49 151 108 604 72 discu r con ssing sultin all th g, rt Reiche Engineer mobil ings Stefan Software e and Senior H frost nginee rin g Gmb y beve E Zühlke torkai 66 rages nd Am Sa rg Hambu 20457 6 961 43 3 + 49 173 PS: we’re hiring...