Preample:
We use a Firemonkey application then interact with a DataSnap REST Server. This server use a SQLite database. On the client side, we use FireDac Memtable to manage data. Usually for updating data, we edit the FDMemTable, then we use a function called ApplyUpdate which (in few words) create a TFDJSONDeltas, then pass it to server for applying updates. This work well for all "standard" data type.
Now we have to store a blob in the database which is the logo of the enterprise.
Some investigations:
We've found some exemple that use PARAMS and EXECUTE function of FDQuery but we do not have a FDQuery on the client side. Many of the example are for FDQuery, we do not see a sample for FDMemTable. FDMemtable do not have ExecSQL function.
We also see many algo with TBlobStream, (but unless we miss the right unit declaration), this object seem not be implemented on the Firemonkey side.
Question:
There is a way to perform this task using the FDMemTable or is it better to first upload the image to server and then let the server perform the task to add the image to blob field ?
I can send blob fields to DataSnap REST Server with something like this:
client side:
var
mes: TMemoryStream;
FDMemUp: TFDMemTable;
LDeltaList: TFDJSONDeltas;
begin
mes:= TMemoryStream.Create;
FDMemUp:= TFDMemTable.Create(nil);
FDMemUp.CachedUpdates:= true;
FDMemUp.FieldDefs.Add('IMAGE',ftBlob);
FDMemUp.FieldDefs.Add('ID',ftInteger);
FDMemUp.CreateDataSet;
//append one record with blob field filled from stream
FDMemUp.Append;
(FDMemUp.FieldByName('ID') as TIntegerField).AsInteger:= 106;
(FDMemUp.FieldByName('IMAGE') as TBlobField).LoadFromStream(mes);
FDMemUp.Post;
//send dataset to server
try
try
LDeltaList:= TFDJSONDeltas.Create;
TFDJSONDeltasWriter.ListAdd(LDeltaList, 'INFOLOGO', FDMemUp);
Result:= DM.ServerCoreClient.SendData(LDeltaList);
except
Result:= nil;
end;
finally
FreeAndNil(FDMemUp);
FreeAndNil(mes);
end;
Then process data at server side:
function TDMCore.SendData(const ADeltaList: TFDJSONDeltas): boolean;
var
LApply: IFDJSONDeltasApplyUpdates;
mes: TMemoryStream;
begin
LApply:= TFDJSONDeltasApplyUpdates.Create(ADeltaList);
if (LApply.Values[0].RecordCount > 0) then
begin
mes:= TMemoryStream.Create;
LApply.Values[0].First;
while not LApply.Values[0].Eof do
begin
mes.Clear;
//read stream data from blob field
(LApply.Values[0].Fields[1] as TBlobField).SaveToStream(mes);
mes.Position:= 0;
//Use stream to insert in a database or create a image or whatever the stream represent
LApply.Values[0].Next;
end;
result:= true;
end else result:= false;
end;