I’m working with briefcase files to store on the client side, tables that do not change often. I keep track of the last update date of these tables on the server, and on startup, I compare those dates to the local dates and decide which tables to reload from the server.
However, I’m now interested in the following use case from this article:
Request only the changed records for some huge table from the server side and then merge the delta with the client table loaded from the local briefcase.
Do you have any suggestions or samples on how to accomplish this? What I can think of is storing each delta in a table on the server, using the OnBeforeProcessChange event of the table’s business processor. Then, on the client, when I get the table the first time from the server, I’d load the table along with the date of the last known delta. Then, when I refresh the table on the client, I’d compare the dates of the last delta in the client and the server, and if they are different, get the missing deltas and apply them on the client.
Is this the best approach, or is there any other way to achieve this? Also, how do I store a delta in the database, and then apply it to the local data table once I retrieve the delta from the server?
On the server the table has a trigger-based field that stores for each row the datetime of its last update.
When the time to update the local cache comes the client app requests only the lines with last update dates past the max update data in the local table ant then merges the received data rows (if any) into the local data table
Thanks, Antonk, this is definitely a much simpler approach.
Do you have any suggestions on how to do the merge of the new records? I know there is a RefreshFromServer method that will add new records and update modified records, which is basically what I need to do in this case. Is there a way to use a different data call for RefreshFromServer? I’m thinking I could use that to run a query that returns only those records that changed, and then let RefreshFromServer do the rest.
with table.DynamicWhere do begin
loldExpression := Expression; // store current expression
Expression := NewBinaryExpression(table.LogicalName, 'Updated', dboGreater, myLastUpdate, datDateTime); // apply new expression
try
table.RefreshFromServer;
finally
Expression.Free;
Expression := loldExpression; // restore default table expression
end;
end;
deleted field will indicate that records were deleted so you need to hide it with filters.
Also you can introduce a new event that will be fired by server if any changes are made.
when clients receive it, they should also call RefreshFromServer as above.
You don’t need to use different data call because you can just use DynamicWhere expression.
Hi
I’m trying to run refresh on briefcase which is working just fine in Delphi project with something like this:
procedure TClientDataModule.RefreshBriefcase;
var
lbriefcaseName: string;
lbriefcase: TDAFolderBriefcase;
begin
lbriefcaseName := GetBriefcaseFileName;
lbriefcase:= TDAFolderBriefcase.Create(lbriefcaseName,True,True);
if ValidateBriefcase(lbriefcase) then begin
GetTablesFromBriefcase(lbriefcase);
end;
end;
same idea in .NET throwing an error :
A DataTable named ‘Products’ already belongs to this DataSet
public void RefreshBriefcase()
{
String briefcaseName = this.BriefcaseFileName;
this.AddToLog(String.Format("Briefcase: {0}", briefcaseName));
Briefcase briefcase = new FolderBriefcase(briefcaseName);
briefcase.ReadBriefcase();
Boolean valid = this.ValidateBriefcase(briefcase);
if (valid)
{
this.GetTablesFromBriefcase(briefcase);
}
}