CouchDB Mobile - From Couch to 5K in 1 Hour

8,730 views
8,036 views

Published on

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

Published in: Technology, Business
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
8,730
On SlideShare
0
From Embeds
0
Number of Embeds
316
Actions
Shares
0
Downloads
61
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

CouchDB Mobile - From Couch to 5K in 1 Hour

  1. 44Peter Friese / Stefan Reichert, Zühlke EngineeringCouchDB mobileFrom Couch To 5k in 1 Hour
  2. Peter Friese @peterfriese peter.friese@zuehlke.com xing.to/peter http://peterfriese.de
  3. Stefan Reichert @stefanreichertstefan.reichert@zuehlke.com xing.to/stefanreicherthttp://blog.wickedshell.net/
  4. What we will cover today 1 What is CouchDB? 2 Serious amount of demos! 3 Couch25K - A Runner’s App
  5. What is CouchDB? 1
  6. CouchDB is...CouchDB is... A NoSQL Database.
  7. CouchDB is... Document-Oriented. { ! "name": "Peter", ! "company": "Zühlke Engineering", ! "email": "peter.friese@zuehlke.com", ! "languages": [ ! ! "Objective-C", ! ! "Java", ! ! "C#", ! ! "JavaScript" ! ] }
  8. CouchDB is... Schema-Free. Put anything you like into your CouchDB. Really.
  9. CouchDB is... Erlang-Powered.
  10. CouchDB is... RESTful. GET PUT Fully embraces POST HTTP verbs DELETE
  11. CouchDB uses...http://research.google.com/archive/mapreduce.html Map/Reduce (JavaScript).
  12. 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”}
  13. 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
  14. 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
  15. CouchDB features... Robust Replication.
  16. CouchDB features... Robust Replication. Laptop Phone Server
  17. Demos 2
  18. Calling Home curl localhost:5984{"couchdb":"Welcome","version":"1.1.0"}
  19. Creating a New DB curl -X PUT localhost:5984/helloworld {"ok":true}
  20. Deleting a Database curl -X DELETE http:// localhost:5984/helloworld {"ok":true}
  21. 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"}
  22. 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" }
  23. Anatomy of a Document{ "_id": "f8e42aaa4bc77124c286be13f000054e", "_rev": "1-4dc37117e0da26d9c50dc92d4cbb04cc", "name": "Peter", "company": "Zühlke Engineering", "email": "peter.friese@zuehlke.com"} UUID - very unique identifier
  24. 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)
  25. Welcome to Futon! Admin interface for CouchDB CRUD for Documents Manage Views Manage Replication
  26. Couch25K - A Runner’s App 3
  27. Basic Idea 2-way 2-way Phone IrisCouch Phone
  28. CouchDB Mobile n e ? P h o o u r n y o
  29. CouchDB MobileYour app CouchCocoa lib Ektorp lib Your app CouchDB CouchDB
  30. CouchDB Mobile Your app CouchCocoa lib Ektorp lib Your app TouchDB lib TouchDB lib SQlite SQlite
  31. 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
  32. 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; }
  33. 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);}
  34. Trackpoints { "run": "run-peterfriese-19", "user": "peterfriese", "lon": "9.990512659959458", "time": "2012-03-24 07:39:27 +0000", "lat": "53.73176022303823" }
  35. 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];
  36. 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);
  37. Sync with the ServerNSURL *url = [NSURL URLWithString: @"http://peterfriese.iriscouch.com/couch25k"];[self.database replicateWithURL:url exclusively: YES];
  38. 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); }
  39. 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); }
  40. Demo
  41. 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
  42. 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];})
  43. 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")); } }}
  44. 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(); }};
  45. Filtering Peter Stefan Filter by name sync 2-way sync 2-wayPhone IrisCouch Phone 2
  46. FilteringCouchDBby_user: function(doc, rq) { if(doc.user == rq.query.username) { return true; } return false; }
  47. 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;
  48. 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);}
  49. Maps, please!
  50. 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:...}
  51. 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]];
  52. Query Trackpoints by RunMapnew TDViewMapBlock() { public void map(Map<String, Object> document, TDViewMapEmitBlock emitter) { if (document.containsKey("run")) { document.get("run"), document.get("_id")); }}
  53. 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;
  54. And finally... http://josephta.me/about-joseph-tame/
  55. ... a Tribute to Steve Jobs GPX of J cou rtes ose y ph - T Tam han e ks! http://bit.ly/HbDRod
  56. Relax! 44
  57. 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...

×