Interfaces used for replication of tables from a server or table provider to a client. On the client side the table will be written into a local database. On the server side the table could be anything. The replication relies on a underlying websocket connection which provides JsonApi for message exchange.
The libraries for the replicator (client) and publisher (server), cover the following features:
File | common/interface/replication.h |
Classes |
IReplicator UReplicator IPublisher UPublisher |
class IReplicator : public UJsonApiContext {
public:
virtual ~IReplicator() {};
virtual void Update(const char * domain, const char * instance) = 0;
virtual void AddColumn(const char * remote, const char * local, enum ReplicationType type, bool update) = 0;
virtual class IReplicatorArray * AddArray(const char * remote, const char * local, bool update, const char * reference) = 0;
virtual void Initialize(const char * row) = 0;
virtual void Added(ulong64 id) = 0;
virtual void Deleted(ulong64 id) = 0;
virtual void DeletedConfirm(ulong64 id) = 0;
virtual void Updated(ulong64 id, ulong64 mask=0xffffffffffffffffLL) = 0;
virtual void Start() = 0;
virtual void Stop() = 0;
static class IReplicator * createReplicator(class UReplicator * user, const char * remote, const char * domain, const char * instance, const char * domainProperty, const char * instanceProperty, class IDatabase * database, const char * local, bool add, bool del);
};
The IReplicator function is the virtual interface class returned when creating the replicator. The public interface functions of this class are called to perform any operations.
This functions is called to create the replicator as part of the initialization.
class UReplicator * user | Use the UReplicator class as base class of one of your classes. The virtual functions of this class are called so signal events from the replicator the the user of the replicator. |
const char * remote | The remote table name, used to publish the table. This name is used inside the replication protocol as "api" property. |
const char * domain, instance | If the App Service can receive AppWebsocket connections from multiple domains and instances, these parameters can be used to only use matching connections for the replication. |
const char * domainProperty, instanceProperty |
The name of the properties used to send domain and instance in the message
which is used to decide, that this AppWebsocket connection can be used for
replication. Note: the default value for domainProperty is "domain" and for instanceProperty "pbx" if you replicate from an innovaphone PBX! |
class IDatabase * database | The database pointer |
const char * local | The name of the local database table, into which the remote table is replicated |
bool add | If true, the replicator announces that it may add to the replicated table. If this is not possible on the publisher of the table, the replication won't start. |
bool del | If true, the replicator announces that it may delete from the replicated table. If this is not possible on the publisher of the table, the replication won't start. |
For this to work, the AppInstance class needs to use JsonApiContext as base class.
class <Your App Name>> : public AppInstance, ... , public JsonApiContext
After createReplicator is called the interface has to be registered in the JsonApiContext
replicator = IReplicator::createReplicator(this, ...);
RegisterJsonApi(replicator);
When an AppWebsocket connection is established, which may be used for the replication, this AppWebsocket connection needs to be added to the JsonApiContext:
class <Your App Session>> : ..., public AppWebsocket, ... {
// when receiving a message indicating this session is used for replication
class JsonApi * jsonApi = <App Instance class>->CreateJsonApi(<Table Name>, this, msg, base);
if (jsonApi) jsonApi->JsonApiStart();
Function may be called to update domain and instance (see creatReplicator). The replication is restarted when this function is called
const char * domain, instance |
If the App Service can receive AppWebsocket connections from multiple
domains and instances, these parameters can be used to only use matching
connections for the replication. If you replicate from an innovaphone PBX, you typically use the App instance domain name for domain and a configurable value for instance, which must match the "PBX Name" of the PBX which is used for replication. The configuration of the PBX name can be e.g. done inside a PBX Manager Plugin for your App. |
After the replicator is created, the columns which should be replicated must be configured. This is done by calling AddColumn for each column.
const char * remote | The column name under which it is published |
const char * local | The local database column name |
enum ReplicationType type |
|
bool update | The replicator user may update this column |
An column in the table can consist of an array of objects. This array is added with the AddArray function the same way as simple elements are added with AddColumn. The array of objects is represented as table with columns, with each elemnt of the object as column.
const char * remote | The column name under which it is published |
const char * local | The local database column name |
bool update | The replicator user may update this column |
const char * reference | The name of the column in the database table used for the join to a column of "id" in the array table. |
Called to initialize the local database table. Must be called, after the replicator is created and all columns are added. The UReplicator::Initialited function is called when the initialization is complete.
const char * row |
The Initialize creates a database table "replicator_full", which is used to
store the replicated rows after the initial full replication, so that the
rows not present on the publisher anymore can be deleted. This table has a
column "id" as unique id and uses the column "row" to link to the replicated
table. The argument row is the SQL defintion used for the column.
Example: "BIGINT REFERENCES users(id) ON DELETE CASCADE NOT NULL" |
Called when a row was added to the local table, so that the replicator can replicate the change to the publisher
ulong64 id | The id of the row added |
Called when a row is to be deleted locally, so that the replicator can replicate the deletetion to the publisher. The actual database delete should be done after the DeletedConfirm callback
ulong64 id | The id of the row to be deleted |
Call to acknowlegde an incoming Deleted call. Only after the DeletedConfirm call the row is deleted from the table.
ulong64 id | The id of the row to be deleted |
Called when a row was updated in the local table, so that the replicator can replicate the change to the publisher
ulong64 id | The id of the row updated |
Call to start the replicator after it was stopped. After initialization the replicator is started automatically, so there is no need to call Start.
Call to stop the replicator
class UReplicator {
public:
virtual void ReplicatorInitialized() = 0;
virtual void ReplicatorAdded(ulong64 id) = 0;
virtual void ReplicatorDeleted(ulong64 id) = 0;
virtual void ReplicatorDeletedConfirm(ulong64 id) = 0;
virtual void ReplicatorDeletedConfirmComplete(ulong64 id) = 0;
virtual void ReplicatorUpdated(ulong64 id, ulong64 mask) = 0;
virtual void ReplicatorSessionInitialized() {}
virtual void ReplicatorStopped() = 0;
virtual void ReplicatorUpdate(class json_io & msg, word base, bool initial) {};
virtual void ReplicatorStart(class json_io & msg, word base, char * & tmp) {};
};
Called when replicator initialization is complete
Called when a row was added by the replicator
ulong64 id | The id of the row added |
Called when a row was deleted on the publisher. Locally the row is deleted only after DeletedConfirm is called
ulong64 id | The id of the row deleted |
Called when a row can be deleted locally after a Deleted was called
ulong64 id | The id of the row deleted |
Called when a row was deleted locally after a DeletedConfirm call
ulong64 id | The id of the row deleted |
Called when a row was updated by the replicator
ulong64 id | The id of the row deleted |
ulong64 mask | A 1 is set in this value for each updated column, with the bit position beeing the position of the column in the AddColumn calls. |
?
?
?
Callback to add custom arguments to the ReplicateStart message. The JSON properties, which may be added here depend on the publisher of the table.
class IPublisher : public UJsonApiContext {
public:
virtual ~IPublisher() {};
virtual void AddColumn(const char * remote, const char * local, enum ReplicationType type, bool update) = 0;
virtual void Initialize(const char * row) = 0;
virtual void Added(ulong64 id) = 0;
virtual void Deleted(ulong64 id) = 0;
virtual void DeletedConfirm(ulong64 id) = 0;
virtual void Updated(ulong64 id, ulong64 mask) = 0;
virtual void Stop() = 0;
static class IPublisher * createPublisher(class UPublisher * user, const char * remote, class IDatabase * database, const char * local, const char * sequence, bool add, bool del);
};
This functions is called to create a publisher as part of the initialization.
class UPublisher * user | Use the UPublisher class as base class of one of your classes. The virtual functions of this class are called so signal events from the publisher to the user of the publisher. |
const char * remote | The remote table name, used to publish the table. This name is used inside the replication protocol as "api" property. |
class IDatabase * database | The database pointer |
const char * local | The name of the local database table, from which the remote table is replicated |
bool add | If true, the publisher allows to add to the local table. |
bool del | If true, the publisher allows to delete from the local table. |
After the publisher is created, this function is called to add columns to the replicator. The column in a local database is specified together with the name under which the column is published.
const char * remote | The name under which the column is published |
const char * local | The name of the local database column |
enum ReplicationType type | The type of the column |
bool update | Indicates if the column my be updated from remote |
To be called after all columns have been added to initialize local datastructures and database tables
const char * row | SQL type to for a database column used to join to a row of the published table |