Create replicas with script fast
Category Tips
If anybody needs to create replicas for several databases with script , he will find out that the only available method (NotesDatabase.CreateReplica) creates a "full" replica including all documents. This can take a lot of time if the database size is large. There is no way in script how to create only a "replication stub" of a database, like you can if you do this manually form the client. However there is a workaround for this (as always:-))) ...
If anybody needs to create replicas for several databases with script , he will find out that the only available method (NotesDatabase.CreateReplica) creates a "full" replica including all documents. This can take a lot of time if the database size is large. There is no way in script how to create only a "replication stub" of a database, like you can if you do this manually form the client. However there is a workaround for this (as always:-))) ...
Actually you have two options how to do this and both use the trick that you can change the replica-ID of a database via script easily.
1) Create a blank database and change the Replica-ID
Simply create a new blank database (notesDatabase.Create) and then change its replica-id to the same value as your original database. Thats all.
However this method has some serious disadvantages:
Even after replication the replica will not be completly identical as you would expect.
There are several database properties that won't replicate and will be different among your replicas.
2) Create a blank database, change the Replica-ID to "00000000-00000000" and set the title
This method achieves much better results and I would recommend it as it will create "perfect" replicas without any differencies, exactly as you would expect.
However this method is undocumented and unsupported by Lotus so you have to use it at your own risk. (but it works fine in R4,R5,R6)
The whole trick is that if you create a blank database, set its replica-id to only zeros and then change the database title to a predefined format (Server+Tab+Filepath) then this database will be initiated by the next replication with this server.
This creatin mechanism is being used by the notes client in the version R5 when you create local databases.
The only disadvantage of the function is that you have to replicate with exactly the defined server. Only this server can initalize the replica. After this has been done you can of course replicate wih any other without problems.
If you only want to test how this works you can also download this database here.
It is completly blank an has a replica id set to "00000000-00000000".
Simply copy it onto you local machine, change the title to whatever database you want (dont forget the proper format) and then trigger a replication with the server.
Example script:
Dim Session As New NotesSession
Dim DB As NotesDatabase
Dim ReplicaDB As New NotesDatabase( "", "" )
Dim ReplicaServer As String
Dim ReplicaFilePath As String
Dim ReplicaTitle As String
Dim Server As NotesName
Set DB = Session.CurrentDatabase ' this is the datbase from which a replica should be created
Set Server = New NotesName(DB.Server)
ReplicaServer = "Server1/ACME" ' the server on which the replica should be created
ReplicaFilePath = "Test\NewReplica.nsf" ' the filepaht where the replica should be created
ReplicaTitle = Server.COMMON + Chr(9) + DB.FilePath ' this is exactly how the title of the replica has to be
Call ReplicaDB.Create( ReplicaServer , ReplicaFilePath , True) ' creates a new blank database
Call SetReplicaID(ReplicaDB, "0000000000000000") ' changes the replica ID to '00000000:00000000'
ReplicaDB.Title = ReplicaTitle ' changes the title of the database
You will need a function that changes the Replica-ID of a database. This has to be done through API.
You can use your own code, find some function in the formums on Notes.Net or use this one.
(This function has not been written by me, but I don't know where I got it from and so I can't give credits:-( . If I find out I will post it.)
Private Type ReplicaInfo
ID(1) As Long
Flags As Integer
CutoffDays As Integer
CutoffDate(1) As Long
End Type
Declare Private Function W32_OSPathNetConstruct Lib "nnotes.dll" Alias "OSPathNetConstruct" ( Byval Z As Long, Byval S As Lmbcs String, Byval F As Lmbcs String, Byval P As Lmbcs String) As Integer
Declare Private Function NSFDbReplicaInfoGet Lib "nnotes.dll" ( Byval H As Long, R As ReplicaInfo) As Integer
Declare Private Function NSFDbReplicaInfoSet Lib "nnotes.dll" ( Byval H As Long, R As ReplicaInfo) As Integer
Declare Private Function NSFDbOpen Lib "nnotes.dll" Alias "NSFDbOpen" ( Byval P As String, H As Long) As Integer
Declare Private Function NSFDbClose Lib "nnotes.dll" Alias "NSFDbClose" ( Byval H As Long) As Integer
Sub SetReplicaID(db As NotesDatabase, replicaid As String)
Dim l1 As Long
Dim l0 As Long
Dim v1 As Variant
Dim v0 As Variant
Dim p As String*1024
Dim hDB As Long
Dim R As ReplicaInfo
p$ = String(1024, " ")
Call W32_OSPathNetConstruct (0, db.Server, db.FilePath, p$)
NSFDbOpen p$, hDB
Call NSFDbReplicaInfoGet( hDB, R)
v1=HexStringToLong(Mid(replicaid,1,8))
v0=HexStringToLong(Mid(replicaid,9,8))
If v1>2147483648 Then
l1=v1-4294967296
Else
l1=v1
End If
If v0>2147483648 Then
l0=v0-4294967296
Else
l0=v0
End If
R.ID(1)=l1
R.ID(0)=l0
Call NSFDbReplicaInfoSet(hDB, R)
Call NSFDbClose(hDB)
End Sub
Function HexStringToLong(hexstring As String) As Variant
Dim dez As Variant
Dim y As Integer
Dim x As Long
For x=Len(hexstring)-1 To 0 Step -1
y=Asc(Mid(hexstring, x+1, 1))
Select Case y
Case 48 To 57 '0..9
dez=dez+(y-48)*16^(Len(hexstring)-1-x)
Case 65 To 70 'A..F
dez=dez+(y-55)*16^(Len(hexstring)-1-x)
Case 97 To 102 'a..f
dez=dez+(y-87)*16^(Len(hexstring)-1-x)
End Select
Next
hexstringtolong=dez
End Function



Comments
Sub doDatabase(database As NotesDatabase, targetservers As Variant, pathname As String)
On Error Goto errhandler
Dim index As Integer
Dim server As String
Forall targetserver In targetservers
index = index + 1
Call runner.updateProgressBar(targetserver & "!!" & pathname, index , Ubound(targetservers) + 1)
server = targetserver
' Check if there already is a database at the destination
Dim dbr As NotesDatabase
Set dbr = New NotesDatabase(targetserver, pathname)
If dbr.IsOpen Then
Call runner.logError("Database " & targetserver & "!!" & pathname & " could not be created. The target filename is used.")
Delete dbr
Else
' now create the replica stub
Call createReplicaStub(database, server, pathname)
End If
nextServer:
End Forall
Goto eos
errhandler:
If Err = 4005 Then
Call runner.logError("Database " & server & "!!" & pathname & " could not be created. The target server does not respond.")
Resume nextServer
Else
Call runner.logError("Err: " & Err & " Error: " & Error & " Erl: " & Erl & " : " & server & "!!" & pathname)
Resume eos
End If
eos:
End Sub
Peter Närlund, 09.09.2007 04:48:29 | - Website - |
Const DBCOPY_REPLICA = &H0001&
Const NOTE_CLASS_NONE = &H0000&
Declare Function W32NSFDbCreateAndCopy Lib "nnotes.dll" Alias "NSFDbCreateAndCopy" _
(Byval srcDb As Lmbcs String,_
Byval dstDb As Lmbcs String,_
Byval NoteClass As Integer,_
Byval limit As Integer,_
Byval flags As Long,_
retHandle As Long) As Integer
Declare Function W32NSFDbClose Lib "nnotes.dll" Alias "NSFDbClose" _
(Byval hDB As Long) As Integer
Function createReplicaStub(sourceDatabase As NotesDatabase, targetServer As String, targetFilePath As String) As Boolean
On Error Goto errHandler
Dim srcDb As String
srcDb = sourceDatabase.Server & "!!" & sourceDatabase.FilePath
Dim dstDb As String
dstDb = targetServer & "!!" & targetFilePath
Dim hDB As Long
Dim CAPIErr As Integer
CAPIErr = W32NSFDbCreateAndCopy (srcDb, dstDb, NOTE_CLASS_NONE, 0, DBCOPY_REPLICA, hDB)
If (CAPIErr = 0) Then
CAPIErr = W32NSFDbClose(hDB)
If (CAPIErr <> 0) Then
Error 1001, "Unable to close database " & dstDb & "; Error: " & Hex$(CAPIErr)
End If
Else
Error 1001, "Unable to create replica at " & dstDb & "; Error: " & Hex$(CAPIErr)
End If
getOut:
Exit Function
errHandler:
On Error Goto 0
Error Err, Error$ & " on line " & Erl & " [in " & Lsi_info(2) & "]"
Resume getOut
End Function
Peter Närlund, 09.09.2007 04:51:58 | - Website - |
Dim dbr As NotesDatabase
Set dbr = New NotesDatabase(targetserver, pathname)
If dbr.IsOpen Then
Call runner.logError("Database " & targetserver & "!!" & pathname & " could not be created. The target filename is used.")
Delete dbr
Else [url={<a href="{ Link } watches</a>}
[url={ <a href="{ Link } rel="nofollow" target="blank">Link</a> }
cristina, 07.30.2010 05:41:27 | - Website - |
homecoming hairstyles 2012 updos, 09.30.2011 21:50:11 | - Website - |
cute short haircuts 2012, 09.30.2011 23:03:46 | - Website - |
evening dresses under 100, 10.01.2011 16:21:36 | - Website - |
bbq ideas for a crowd, 10.07.2011 09:26:16 | - Website - |
f150 towing capacity chart, 10.07.2011 09:49:36 | - Website - |