0

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 ?

Alain V
  • 311
  • 3
  • 17

1 Answers1

3

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;
A. Fornés
  • 183
  • 1
  • 8
  • Thanks Mr. Fornés, the line code we was searching is : {(FDMemUp.FieldByName('IMAGE') as TBlobField).LoadFromStream(mes);}­ – Alain V Jan 16 '17 at 23:39