Siaqodb can be synchronized with a server side NoSQL database like CouchDB or MongoDB via a RESTful service called SiaqodbCloud. SiaqodbCloud is a ASP.NET WebAPI project and it is provided as Open Source on Github, so you can customize it, add support for another database engine and host it in your proffered cloud or your own data center.

Only Buckets from Siaqodb's DocumentStore can be synchronized with server side databases.

SiaqodbCloud service

SiaqodbCloud service is Open Source and it can be downloaded from Github. It is an ASP.NET WebAPI project and after successfully installed and started it can be used as a replication end point for Siaqodb. On the server side, MongoDB and CouchDB are supported as NoSQL databases. So, to synchronize Siaqodb's Buckets, you will need to create for each Siaqodb Bucket, a database in CouchDB or a collection in a MongoDB database. For instance, if you have in Siaqodb a bucket called "invoices" (accessed by: siaqodb.Documents["invoices"]), you will have to create a collection called 'invoices' in a MongoDB database or a database 'invoices' in CouchDB, so all documents from the bucket 'invoices' will be synchronized with MongoDB/CouchDB documents from database/collection 'invoices'.

SiaqodbCloud client

Any Bucket from Siaqodb can be synchronized via SiaqodbCloud only if the bucket is marked as Sync-able. To mark it, you will have to call:

 Sqo.SiaqodbConfigurator.SetSyncableBucket("invoices", true);

To start sync-ing buckets, you will have to reference SiaqodbCloud.dll assembly which can be found inside Siaqodb package. After you add the reference, create a SiaqodbSync instance by providing:

  • URL to SiaqodbCloud WebPI
  • AccessKeyId which will be sent in the header of every HTTP request
  • SecretKey which will be used to build Signature that signs every HTTP request

Example:

using SiaqodbCloud;
.....
SiaqodbSync syncContext = new SiaqodbSync("http://localhost:11735/v0/", 
    "3ba69b5835dgdb308766b4756b00079a", 
    "4362kljh63k4599hhgm");

You can synchronize an Siaqodb local Bucket with an online Bucket by using Push/Upload and Pull/Download operations.

Upload all changes from an offline bucket to a cloud bucket:


IBucket bucket = siaqodb.Documents["invoices"];
syncContext.Push(bucket);//push local changes to server

Download all changes from the cloud bucket:

IBucket bucket = siaqodb.Documents["invoices"];
syncContext.Pull(bucket);//pull server changes to client db

Important note: every Pull() operation will call Push() first, so for a complete Sync is enough to call only Pull()

Filtering

It does not always make sense to download all data from a cloud bucket to the local device. SiaqodbCloud allows you to filter and download only changes of records by a certain criteria, example:

 IBucket bucket = siaqodb.Documents["invoices"];
Filter f = new Filter("year");
f.Value = 2016;
syncContext.Pull(bucket,f); // pull server changes to client but only for filtered records

Conflicts

When an app works regardless connection and many concurrent users may do modification on data, or same user but from different devices, obviously conflicts may appear. SiaqodbSync can handle those conflicts and let developer decides based on the app business criteria, how to merge or what record is the "winner".

Conflicts are detected based on Document.Version property. This property is updated by server only at every UPDATE/DELETE/INSERT operation. The client code should never update this property.

Following types of conflicts may appear:

Delete - Delete: a record is deleted locally by one user, but the same record is deleted online by another user. When the synchronization is made, at push, a conflict appears;

Delete - Update: a record is deleted locally by one user, but the same record is updated online by another user. When the synchronization is made, at push, a conflict appears;

Update - Delete: a record is locally updated by one user, but the same record has been deleted online by another user. When the synchronization is made, at push, a conflict appears;

Update - Update: a record is locally updated by one user, but the same record is updated online by another user. When the synchronization is made, at push, a conflict appears;

By default, online record is the 'winner', so for example on an update-update conflict, after Push() operation occurs, the local Document changes are rejected and the server version is downloaded and stored locally.

However this behavior may be overwritten and developer may merge both conflicted documents or choose as winner based on app business criteria. To overwrite it you have to pass a instance of a class that implements 'IConflictResolver' to the Push/Pull methods. Example:

 private class LocalResolver : IConflictResolver
{
    public Document Resolve(Document local, Document online)
    {
        return local;
    }
}

And now you can pass an instance of this class to Pull/Push methods:

syncContext.Pull(bucket, new LocalResolver());//also calls Push()