KEMBAR78
Building .NET Apps using Couchbase Lite | PPTX
Building .NET Apps using Couchbase Lite 
Zack Gramana
About Me 
Zack Gramana 
Senior Software Engineer 
Mobile 
@zgramana
And, about me… 
Wayne Carter 
Architect 
Mobile 
@waynecarter
4 
Couchbase Lite 
On-device, lightweight, native 
embedded JSON database 
Sync Gateway 
Synchronize on-device 
Couchbase Lite with Couchbase 
Server in the cloud 
Couchbase Server 
High performance, scalable, 
always-on JSON database in 
the cloud 
Couchbase Mobile
5 
Couchbase Lite 
Couchbase Lite 
Full Featured 
JSON 
Native 
Lightweight 
Secure 
Beta
6 
Sync Gateway 
Sync Gateway 
Replication 
Authentication 
Data Partitioning 
Data Access Control
Authentication, Partitioning, Access Control 
7 
Pluggable Authentication 
JavaScript sync function runs on all mutations. 
Data Partitioning 
– channel(…): Routes the document to the named channel 
Data Access Control 
– Read 
– access(…): Grants access to a channel to a specified user, list of users, or a role 
– role(…): Grants a user a role 
– Write 
– throw(…): Prevents a document mutation from persisting 
– requireUser/Role/Access(…): Validates the user, their role assignments, or their 
access privileges.
8 
Couchbase Server 
Couchbase Server 
JSON 
Highly Scalable 
High Performance 
Always On
Couchbase Lite In A Nutshell
Highlights 
• Document Database 
• Map Reduce Queries 
• Sync 
• Small: Assembly is < 500KB
Document Database Overview 
• Semi-structured 
• Key-value pairs 
• Schemaless 
• JSON-backed 
• Very low-friction
Map Reduce Queries Overview 
• Functional queries, instead of set-theoretic 
• Write query logic in pure C#, not SQL 
• Can be one-off, or auto-updating as data changes 
• You probably already know how to use it: 
– Map is like LINQ’s Select method 
– Reduce is like LINQ’s Aggregate method
Sync Overview 
• Master-master replication 
• Uses HTTP + REST 
• Offline mode for free 
• Manual or continuous modes 
• Automatic retry on failure 
• Responds to network changes
Programming Model 
• You: make your changes to docs 
• Queries: will reflect those changes 
• Replicators: sync changes for you
Getting Started with Documents
Opening a Database 
var db = Manager.SharedInstance.GetDatabase("foo"); 
Debug.Assert(db != null); 
var db = Manager.SharedInstance.GetExistingDatabase("foo"); 
Debug.Assert(db == null);
Getting a Document 
var doc = db.GetDocument("foo-doc"); 
Debug.Assert(doc != null); 
var doc = db.GetExistingDocument("foo-doc"); 
Debug.Assert(doc == null);
Creating a Document 
var doc = db.CreateDocument(); 
Debug.Assert(doc.Id != null);
Deleting a Document 
doc.Delete(); 
Debug.Assert(doc.Deleted);
Updating a New Document 
var rev = doc.CreateRevision(); 
var props = new Dictionary<string, object> 
{ 
{ "foo", "bar"}, 
{ "fizz", "buzz"} 
}; 
rev.SetUserProperties(props); 
rev.Save();
Updating an Existing Document 
var props = doc.Properties; 
var newProps = new Dictionary<string, object>(props) 
{ 
{ "foo", "bar"} 
}; 
doc.PutProperties(newProps); // Saves a new revision
Dealing with Changes 
doc.Change += (sender, e) => 
{ 
// e.g. if we get a conflict... 
if (e.Change.IsConflict) 
{ 
// we can resolve it! 
} 
};
DocumentChange Members 
String 
Boolean 
Boolean 
String 
Uri 
RevisionInternal 
DocumentId 
IsConflict 
IsCurrentRevision 
RevisionId 
SourceUrl 
WinningRevision
Handling Conflicts 
var current = doc.CurrentRevision; 
foreach(var rev in doc.ConflictingRevisions) 
{ 
var newRev = rev.CreateRevision(); 
if (rev.Equals(current)) { 
newRev.SetProperties(mergedProps); 
} else { 
newRev.IsDeletion = true; 
} 
newRev.Save(); 
}
Auto-merging Properties using LINQ 
Dictionary<string, object> mergedProps; 
try 
{ 
mergedProps = doc.ConflictingRevisions 
.SelectMany(rev => rev.UserProperties) 
.Distinct() 
.ToDictionary( 
kvp => kvp.Key, 
kvp => kvp.Value 
); 
} catch (ArgumentException ex) { 
// Merge conflict requires manual resolution. 
}
Getting Started with Queries
Create a View 
var view = db.GetView("foo"); 
Debug.Assert(view != null); 
var view = db.GetExistingView("foo"); 
Debug.Assert(view == null);
Add a Map Function 
view.SetMap((doc, emit) => 
{ 
var foo = (String)doc["foo"]; 
if (foo.Equals("bar")) { 
emit ("text", doc["text"]); 
} 
}, "1");
Using a Reduce Function 
ReduceDelegate reducer = (keys, values, rereduce) => 
{ 
var i = 0; var wordCount = 0; 
foreach(var key in keys) { 
if (key == "text") { 
var str = (String)values[i]; 
wordCount += str.Split(' ').Length; 
} 
} 
return wordCount; 
}; 
view.SetMapReduce(mapper, reducer, "1");
Create a Query 
var query = view.CreateQuery(); 
// Options, like... 
query.Completed += (sender, e) => { 
Log("Results: {0}", e.Rows); 
}; 
query.Descending = true; 
// Get records... 
var rows = await query.RunAsync(); 
rows.Where(row => ...);
Create a LiveQuery 
var liveQuery = query.ToLiveQuery(); 
// Respond to changes in the view. 
liveQuery.Changed += (sender, e) => 
{ 
Log("Updates: {0}", e.Rows.Count); 
};
Getting Started with Replication
Pull Replicator 
var uri = new Uri(syncGatewayUrl); 
var pull = db.CreatePullReplication(uri); 
pull.Continuous = true; 
pull.Changed += ReplicationChanged; 
pull.Start();
Push Replicator 
var uri = new Uri(syncGatewayUrl); 
var push = db.CreatePushReplication(uri); 
push.Continuous = true; 
push.Changed += ReplicationChanged; 
push.Start();
Next Steps
Couchbase Developer Portal 
developer.couchbase.com/mobile
Xamarin Component Store 
components.xamarin.com/view/couchbase-lite-net
.:[coming soon]:. 
nuget.org
Couchbase Connect
Questions and Answers
Additional Resources
Mailing List 
groups.google.com/d/forum/mobile-couchbase
Contact Me 
zack@couchbase.com (email) 
@zgramana (twitter)

Building .NET Apps using Couchbase Lite

  • 1.
    Building .NET Appsusing Couchbase Lite Zack Gramana
  • 2.
    About Me ZackGramana Senior Software Engineer Mobile @zgramana
  • 3.
    And, about me… Wayne Carter Architect Mobile @waynecarter
  • 4.
    4 Couchbase Lite On-device, lightweight, native embedded JSON database Sync Gateway Synchronize on-device Couchbase Lite with Couchbase Server in the cloud Couchbase Server High performance, scalable, always-on JSON database in the cloud Couchbase Mobile
  • 5.
    5 Couchbase Lite Couchbase Lite Full Featured JSON Native Lightweight Secure Beta
  • 6.
    6 Sync Gateway Sync Gateway Replication Authentication Data Partitioning Data Access Control
  • 7.
    Authentication, Partitioning, AccessControl 7 Pluggable Authentication JavaScript sync function runs on all mutations. Data Partitioning – channel(…): Routes the document to the named channel Data Access Control – Read – access(…): Grants access to a channel to a specified user, list of users, or a role – role(…): Grants a user a role – Write – throw(…): Prevents a document mutation from persisting – requireUser/Role/Access(…): Validates the user, their role assignments, or their access privileges.
  • 8.
    8 Couchbase Server Couchbase Server JSON Highly Scalable High Performance Always On
  • 9.
  • 10.
    Highlights • DocumentDatabase • Map Reduce Queries • Sync • Small: Assembly is < 500KB
  • 11.
    Document Database Overview • Semi-structured • Key-value pairs • Schemaless • JSON-backed • Very low-friction
  • 12.
    Map Reduce QueriesOverview • Functional queries, instead of set-theoretic • Write query logic in pure C#, not SQL • Can be one-off, or auto-updating as data changes • You probably already know how to use it: – Map is like LINQ’s Select method – Reduce is like LINQ’s Aggregate method
  • 13.
    Sync Overview •Master-master replication • Uses HTTP + REST • Offline mode for free • Manual or continuous modes • Automatic retry on failure • Responds to network changes
  • 14.
    Programming Model •You: make your changes to docs • Queries: will reflect those changes • Replicators: sync changes for you
  • 15.
  • 16.
    Opening a Database var db = Manager.SharedInstance.GetDatabase("foo"); Debug.Assert(db != null); var db = Manager.SharedInstance.GetExistingDatabase("foo"); Debug.Assert(db == null);
  • 17.
    Getting a Document var doc = db.GetDocument("foo-doc"); Debug.Assert(doc != null); var doc = db.GetExistingDocument("foo-doc"); Debug.Assert(doc == null);
  • 18.
    Creating a Document var doc = db.CreateDocument(); Debug.Assert(doc.Id != null);
  • 19.
    Deleting a Document doc.Delete(); Debug.Assert(doc.Deleted);
  • 20.
    Updating a NewDocument var rev = doc.CreateRevision(); var props = new Dictionary<string, object> { { "foo", "bar"}, { "fizz", "buzz"} }; rev.SetUserProperties(props); rev.Save();
  • 21.
    Updating an ExistingDocument var props = doc.Properties; var newProps = new Dictionary<string, object>(props) { { "foo", "bar"} }; doc.PutProperties(newProps); // Saves a new revision
  • 22.
    Dealing with Changes doc.Change += (sender, e) => { // e.g. if we get a conflict... if (e.Change.IsConflict) { // we can resolve it! } };
  • 23.
    DocumentChange Members String Boolean Boolean String Uri RevisionInternal DocumentId IsConflict IsCurrentRevision RevisionId SourceUrl WinningRevision
  • 24.
    Handling Conflicts varcurrent = doc.CurrentRevision; foreach(var rev in doc.ConflictingRevisions) { var newRev = rev.CreateRevision(); if (rev.Equals(current)) { newRev.SetProperties(mergedProps); } else { newRev.IsDeletion = true; } newRev.Save(); }
  • 25.
    Auto-merging Properties usingLINQ Dictionary<string, object> mergedProps; try { mergedProps = doc.ConflictingRevisions .SelectMany(rev => rev.UserProperties) .Distinct() .ToDictionary( kvp => kvp.Key, kvp => kvp.Value ); } catch (ArgumentException ex) { // Merge conflict requires manual resolution. }
  • 26.
  • 27.
    Create a View var view = db.GetView("foo"); Debug.Assert(view != null); var view = db.GetExistingView("foo"); Debug.Assert(view == null);
  • 28.
    Add a MapFunction view.SetMap((doc, emit) => { var foo = (String)doc["foo"]; if (foo.Equals("bar")) { emit ("text", doc["text"]); } }, "1");
  • 29.
    Using a ReduceFunction ReduceDelegate reducer = (keys, values, rereduce) => { var i = 0; var wordCount = 0; foreach(var key in keys) { if (key == "text") { var str = (String)values[i]; wordCount += str.Split(' ').Length; } } return wordCount; }; view.SetMapReduce(mapper, reducer, "1");
  • 30.
    Create a Query var query = view.CreateQuery(); // Options, like... query.Completed += (sender, e) => { Log("Results: {0}", e.Rows); }; query.Descending = true; // Get records... var rows = await query.RunAsync(); rows.Where(row => ...);
  • 31.
    Create a LiveQuery var liveQuery = query.ToLiveQuery(); // Respond to changes in the view. liveQuery.Changed += (sender, e) => { Log("Updates: {0}", e.Rows.Count); };
  • 32.
  • 33.
    Pull Replicator varuri = new Uri(syncGatewayUrl); var pull = db.CreatePullReplication(uri); pull.Continuous = true; pull.Changed += ReplicationChanged; pull.Start();
  • 34.
    Push Replicator varuri = new Uri(syncGatewayUrl); var push = db.CreatePushReplication(uri); push.Continuous = true; push.Changed += ReplicationChanged; push.Start();
  • 35.
  • 36.
    Couchbase Developer Portal developer.couchbase.com/mobile
  • 37.
    Xamarin Component Store components.xamarin.com/view/couchbase-lite-net
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
    Contact Me zack@couchbase.com(email) @zgramana (twitter)