How does it work?

Your application will use a modified version of the SQLite library containing the LiteSync code to access your database.

The modifications on the SQLite library are internal and the interface is the same.

The LiteSync libraries will communicate to each other, exchanging transaction data.






Replication

The first time the app is open it will connect to the other node(s) and download a fresh copy of the database.

In a centralized topology the primary node will send the database copy to the secondary nodes.

Once it is downloaded the node starts the synchronization.



Synchronization

Once the nodes have the same base db they exchange transactions that were executed when they were off-line.

After this they enter in on-line mode and once a new transaction is executed in a node it is transferred to be executed in the connected nodes.

If the node is off-line then the transaction is stored in a local log to be exchanged later.



DO I NEED TO CHANGE MY APP CODE?

There are a few steps but basically we must change the URI string in the database opening from this:

"file:app.db"

to something like this:

"file:app.db?node=secondary&connect=tcp://server.ip:1234"

The good news is that LiteSync uses the native SQLite3 interface. It means that we don't need to use another API.



Connection

Each node has 2 options:

bind to an address
connect to the peer address

So you can choose which side will connect to the other. This is useful when one side is behind a router or firewall.



Supported Topologies


Centralized, Star Topology


In this topology we have a node in which all the other nodes will be connected to, so it must be on-line for the synchronization to take place.

Here are some example configurations:


The primary node can bind to an address and the secondary nodes connect to it.

Primary node:

"file:/home/user/app.db?node=primary&bind=tcp://0.0.0.0:1234"

Secondary Node: (in another device)

"file:/home/user/app.db?node=secondary&connect=tcp://server:1234"


The primary node can also connect to secondary nodes.

Primary node:

"file:/home/user/app.db?node=primary&connect=tcp://address1:port1,tcp://address2:port2"

Secondary Nodes: (each on a separate device)

"file:/home/user/app.db?node=secondary&bind=tcp://0.0.0.0:1234"


We can even use a mix of these 2 options.

Primary node:

"file:/home/user/app.db?node=primary&bind=tcp://0.0.0.0:1234&connect=tcp://address1:port1"

Secondary Node 1:

"file:/home/user/app.db?node=secondary&connect=tcp://server:1234"

Secondary Node 2:

"file:/home/user/app.db?node=secondary&bind=tcp://0.0.0.0:1234"



Peer-to-Peer Topology


The fully-connected peer-to-peer network is made between primary nodes.

We need to inform the total number of nodes on the network manually on each node (for now)

The direction of connections must also be informed (which nodes will connect to which)

Here is an example of a network with 3 nodes:

Node 1:

"file:db1.db?node=primary&total_primary_nodes=3&bind=tcp://0.0.0.0:1201"

Node 2:

"file:db2.db?node=primary&total_primary_nodes=3&bind=tcp://0.0.0.0:1202& connect=tcp://127.0.0.1:1201"

Node 3:

"file:db3.db?node=primary&total_primary_nodes=3&bind=tcp://0.0.0.0:1203& connect=tcp://127.0.0.1:1201,tcp://127.0.0.1:1202"



Mixed Topology


In this topology we have more than one primary nodes connected as peers and many secondary nodes connected to them.

The configuration for the primary nodes is the same as above, in the peer-to-peer topology.

Each secondary node will be connected to a single primary node at a given time. We can inform the address of many primary nodes so they choose one randomly. If the connection to a primary node drops, it will connect to another one.

Here is an example URI for a secondary node:

"file:db4.db?node=secondary&connect=tcp://127.0.0.1:1201,tcp://127.0.0.1:1202,tcp://127.0.0.1:1203"



Synchronization Status

We can check the synchronization status using this command:

PRAGMA sync_status

It returns a JSON string.



Synchronization Notification

Your application can be notified when the local database is updated due to synchronization with remote nodes. The notification is done via a user-defined function.

Select a language -->

Important: On some languages the notification function is called by the worker thread. The application should NOT use the db connection inside the notification function and it must return as fast as possible! The application can transfer the notification to the main thread before returning.



Checking if the db is ready

If the app is being open for the first time on a device it can download a new copy of the database from another node. Until it is done we cannot access the db.

We can retrieve the sync status and check the db_is_ready variable.

Check the basic app examples bellow.



How to use it in my app?

There are 3 steps:

1  Replace the SQLite library with the one containing LiteSync

2  Change the URI connection string

3  Check for the db ready status

When compiling C and C++ apps you must link your application to the LiteSync library.

For other languages you must have the proper wrapper installed.



Primary node example

The primary node can be a normal application, exactly the same app as the secondary nodes but using a different URI.

Or we can use an app dedicated to be the primary node.

A basic standalone application used solely for the purpose of keeping a centralized db node would look like this:

Select a language -->



Basic app example

A basic app that writes to the local database would look like this:

Select a language -->



SECURITY

LiteSync uses the "shared secret" method to control which nodes can be part of the network, via encryption with a secret key

It is possible (and recommended) to enable encryption on the database and on the communication between the nodes

Check the instructions about Encryption



CURRENT LIMITATIONS

1  Non-deterministic functions (which return different values each time they are called) are blocked, like random() and date('now'). Use explicit values generated on your app

2  AUTOINCREMENT keyword is not supported - but you don't need it! (check video for details)

3  Only a single application can access the database at the same time. Each instance must use its own database, and then they will be replicated and synchronized using LiteSync