Einzelnen Beitrag anzeigen

Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.095 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

DataSnap DataSet übertragen mit Blobfelder macht Probleme

  Alt 10. Sep 2015, 16:58
Datenbank: Firebird • Version: 2.5 • Zugriff über: DataSnap
Hallo Zusammen,

das Problem vorab: Wenn ein Dataset vom DataSnapServer zum einem DataSnapClient transportiert wird welches mehrere
Records beinhaltet die auch ein binary Blob beinhalten, können die Blobinhalte verloren gehen!
Der Blob Inhalt wird massiv vergrössert.

Um das zu demonstrieren habe ich auch eine Testanwendung erzeugt mit einem DataSnapServer und ein DataSnapClient.
Die Datenbank ist eine Firebird DB mit einer Tabelle. Die Tabelle beinhaltet 15 Records.
Die ersten fünf Bilder sind gleich mit einer Größe von 2kb(2338). Die nächsten fünf Bilder ebenfalls gleich mit 22kb(21959)
und die nächsten fünf Bilder ebenfalls gleich mit einer Größe von 263kb(263368)

(Screen shot "AllImages")
Rufe ich das komplette DataSet mit alle 15 Bilder ab und speichere sie auf der Platte, ist zu sehen:
-die ersten fünf 2kb Bilder sind gleich.
-die nächsten fünf Bilder mit je 22kb wird jedes zweite und den Faktor 100 vergrößert
-die letzten fünf Bilder mit je 263kb sind wieder gleich.

(Screen shot "ImagesOneIaATime")

Rufe ich die Bilder so ab dass das DataSet immer nur ein Record liefert, werden alle 15 Bilder mit der richtigen Größe
abgerufen.

Hat jemand eine Idee warum das so ist?
Dürfen in DataSets die mehr wie ein Record haben keine Blob Felder enthalten, ist da was bekannt?
Kann das auch bei String Blobs passieren?


//Server Methoden um das DataSet zu liefern
Delphi-Quellcode:
function TdmDAL.GetIMAGES: TDataSet;
var
  oQuery: TFDQuery;
begin
  result := nil;
  oQuery := nil;

  oQuery := TFDQuery.Create(nil);
  try
    TThread.Synchronize(nil, procedure
    begin
      oQuery.Connection := FDConnection1;
      oQuery.FetchOptions.AutoFetchAll := afAll;
      oQuery.FetchOptions.RecordCountMode := cmTotal;

      oQuery.SQL.add('/*Get all images*/');
      oQuery.SQL.add('SELECT *');
      oQuery.SQL.add('FROM IMAGES');
      oQuery.Open;
    end);

    result := oQuery;
  finally
// oQuery.Free;
  end;

end;

function TdmDAL.GetIMAGE(ImageID:integer): TDataSet;
var
  oQuery: TFDQuery;
begin
  result := nil;
  oQuery := nil;

  oQuery := TFDQuery.Create(nil);
  try
    TThread.Synchronize(nil, procedure
    begin
      oQuery.Connection := FDConnection1;
      oQuery.FetchOptions.AutoFetchAll := afAll;
      oQuery.FetchOptions.RecordCountMode := cmTotal;

      oQuery.SQL.add('/*Get all images*/');
      oQuery.SQL.add('SELECT *');
      oQuery.SQL.add('FROM IMAGES');
      oQuery.SQL.add('WHERE IMAGEID = :IMAGEID');

      oQuery.Params[0].Value := ImageID;

      oQuery.Open;
    end);

    result := oQuery;
  finally
// oQuery.Free;
  end;

end;

//Client Methoden um die Images vom Server abzurufen.
Delphi-Quellcode:

Function SaveBlobIntoFile(aField: TField; aFile: String): Boolean;
Var
   S : TStream;
   FileS : TFileStream;

begin
   Result := False;
   If Not aField.IsBlob Then Exit;
// If aField.IsNull Then EXIT;

   S := aField.DataSet.CreateBlobStream(aField, bmRead);
   FileS := TFileStream.Create(aFile, fmCreate);
   Try
     Try
       FileS.CopyFrom(S, S.Size);
       Result := FileExists(aFile);
     Except
       on e:exception Do
       Begin
         Result := False;
       End;
     End;
   Finally
     S.Free;
     FileS.Free;
   End;
end;


procedure TfrClientMain.Button1Click(Sender: TObject);
var LDataSet: TDataSet;
  ImagaPath:String;
begin

  if not dmComm.InitConnection then exit;
  try

    LDataSet := dmComm.ClientContainer.FProxyInst.GetIMAGES;

    LDataSet.Open;
    LDataSet.first;

    ImagaPath := ExtractFilePath(Application.ExeName) + 'Images\';
    ForceDirectories(ImagaPath);
    while not LDataSet.Eof do
    begin
      SaveBlobIntoFile(LDataSet.FieldByName('IMAGE'), ImagaPath + LDataSet.FieldByName('IMAGEID').AsString+'.png');
      LDataSet.Next;
    end;

    ShellExecute(Handle, nil, PChar(ImagaPath), nil, nil, SW_SHOW);

  finally
    dmComm.CloseConnection;
  end;

end;

procedure TfrClientMain.Button2Click(Sender: TObject);
begin
  if not dmComm.InitConnection then exit;
  try

    Edit1.text := dmComm.ClientContainer.FProxyInst.ReverseString(Edit1.text);
  finally
    dmComm.CloseConnection;
  end;

end;

procedure TfrClientMain.Button3Click(Sender: TObject);
var LDataSet: TDataSet;
  ImagaPath:String;
  i:integer;

begin

  if not dmComm.InitConnection then exit;
  try
    ImagaPath := ExtractFilePath(Application.ExeName) + 'Images\';
    ForceDirectories(ImagaPath);

    for i := 1 to 15 do
    begin

      if Assigned(LDataSet) and LDataSet.Active then LDataSet.close;

      LDataSet := dmComm.ClientContainer.FProxyInst.GetIMAGE(i);
      LDataSet.Open;
      LDataSet.first;
      SaveBlobIntoFile(LDataSet.FieldByName('IMAGE'), ImagaPath + LDataSet.FieldByName('IMAGEID').AsString+'.png');
    end;

    ShellExecute(Handle, nil, PChar(ImagaPath), nil, nil, SW_SHOW);

  finally
    dmComm.CloseConnection;
  end;

end;
Gruß Kostas
Miniaturansicht angehängter Grafiken
allimages.png   imagesoneiaatime.png  
Angehängte Dateien
Dateityp: zip BlobTransfer.zip (4,34 MB, 5x aufgerufen)
  Mit Zitat antworten Zitat