db4o Replication System (dRS) provides functionality to periodically synchronize databases that work disconnected from each other, such as remote autonomous servers or handheld devices synchronizing with central servers.
In order to use replication, the following configuration settings have to be called before a database file is created or opened:
1public static void ConfigureReplication() 2
{ 3
Db4oFactory.Configure().GenerateUUIDs(Int32.MaxValue); 4
Db4oFactory.Configure().GenerateVersionNumbers(Int32.MaxValue); 5
}
1Public Shared Sub ConfigureReplication() 2
Db4oFactory.Configure().GenerateUUIDs(Int32.MaxValue) 3
Db4oFactory.Configure().GenerateVersionNumbers(Int32.MaxValue) 4
End Sub
(See the section below on how to enable replication for existing databases)
Both settings can also be configured on a per-class basis:
1public static void ConfigureReplicationPilot() 2
{ 3
Db4oFactory.Configure().ObjectClass(typeof(Pilot)).GenerateUUIDs(true); 4
Db4oFactory.Configure().ObjectClass(typeof(Pilot)).GenerateVersionNumbers(true); 5
}
1Public Shared Sub ConfigureReplicationPilot() 2
Db4oFactory.Configure().ObjectClass(GetType(Pilot)).GenerateUUIDs(True) 3
Db4oFactory.Configure().ObjectClass(GetType(Pilot)).GenerateVersionNumbers(True) 4
End Sub
Suppose we have opened two ObjectContainers from two different databases called "handheld" and "desktop", that we want to replicate. This is how we do it:
01public static void Replicate() 02
{ 03
IObjectContainer desktop = Db4oFactory.OpenFile(DtFileName); 04
IObjectContainer handheld = Db4oFactory.OpenFile(HhFileName); 05
Db4objects.Drs.IReplicationSession replication = Db4objects.Drs.Replication.Begin(handheld, desktop); 06
/* 07
* There is no need to replicate all the objects each time. 08
* ObjectsChangedSinceLastReplication methods gives us 09
* a list of modified objects 10
*/ 11
IObjectSet changed = replication.ProviderA().ObjectsChangedSinceLastReplication(); 12
//Iterate changed objects, replicate them 13
while (changed.HasNext()) 14
{ 15
Pilot p = (Pilot)changed 16
.Next(); 17
if (p.Name.StartsWith("S")) 18
{ 19
replication.Replicate(p); 20
} 21
} 22
replication.Commit(); 23
}
01Public Shared Sub Replicate() 02
Dim desktop As IObjectContainer = Db4oFactory.OpenFile(DtFileName) 03
Dim handheld As IObjectContainer = Db4oFactory.OpenFile(HhFileName) 04
Dim replic As IReplicationSession = Replication.Begin(handheld, desktop) ' 05
' * There is no need to replicate all the objects each time. 06
' * ObjectsChangedSinceLastReplication methods gives us 07
' * a list of modified objects 08
' */ 09
Dim provider As IReplicationProvider = replic.ProviderA() 10
Dim changed As IObjectSet = provider.ObjectsChangedSinceLastReplication() 11
'Iterate changed objects, replicate them 12
While changed.HasNext() 13
Dim p As Pilot = CType(changed.Next, Pilot) 14
If p.Name.StartsWith("S") Then 15
replic.Replicate(p) 16
End If 17
End While 18
replic.Commit() 19
End Sub
That's all there is to it.
We are using a query that will return all objects but we could use any query we like to constrain the objects we want.
Calling whereModified() will add a constraint to the query so that it only returns the objects that have actually been modified since the last replication between both the containers in question.
After replication commit, all modified objects (INCLUDING THE ONES THAT WERE NOT REPLICATED) are considered to be "in sync" and will not show up in future "where modified" queries, unless they are modified again.
Let's take a look at the necessary configuration calls to tell db4o to generate version numbers and UUIDs:<
When the replication process is commited, the lowest database version number among both databases is set to be equal to the highest. After replication commit, therefore, both databases have the same version number and are "in sync".
As we learned in the last sections, Db4o.configure().generateUUIDs() and Db4o.configure().generateVersionNumbers() (or its objectClass counterparts) must be called before storing any objects to a data file because db4o replication needs object versions and UUIDs to work. This implies that objects in existing data files stored without the correct settings can't be replicated.
Fortunately enabling replication for existing data files is a very simple process:
We just need to use the Defragment tool in com.db4o.tools (distributed as a source code for the versions before 6.0) after enabling replication:
1public static void ConfigureForExisting() 2
{ 3
Db4oFactory.Configure().ObjectClass(typeof(Pilot)).EnableReplication(true); 4
Db4objects.Db4o .Defragment.Defragment.Defrag(DtFileName); 5
}
1Public Shared Sub ConfigureForExisting() 2
Db4oFactory.Configure().ObjectClass(GetType(Pilot)).EnableReplication(True) 3
Defragment.Defragment.Defrag(DtFileName) 4
End Sub
After a successful defragmentation our data files are ready for replication.