program firebirdsegment;
{ Tests blob writing performance on Firebird/Interbase databases;
try varying the BlobSegmentSize below }
{
CREATE TABLE TESTTABLE
(
  BLOBCOL BLOB SUB_TYPE 1,
  ID INTEGER NOT NULL,
  CONSTRAINT PK_TESTTABLE_0 PRIMARY KEY (ID)
);
}
{$mode objfpc}{$H+}
{$APPTYPE CONSOLE}
uses {$IFDEF UNIX} {$IFDEF UseCThreads}
  cthreads, {$ENDIF} {$ENDIF}
  Classes,
  SysUtils,
  sqldb,
  ibconnection {Firebird access},
  dateutils; 

var
  FConnection: TIBConnection;
  FQuery: TSQLQuery;
  FTransaction: TSQLTransaction;
  RecordCounter: integer;
  TextCounter: integer;
  Recordtext: string='';
  Currenttime: Tdatetime;
  Endtime: Tdatetime;    
begin
  FConnection:=TIBConnection.Create(nil);
  FConnection.CharSet := 'UTF-8';
  FConnection.DatabaseName := 'test.fdb';
  FConnection.HostName := paramstr(1); //first command line argument
  FConnection.UserName := 'SYSDBA';
  FConnection.Password := 'masterkey';   
  FConnection.Dialect := 3;
  //FConnection.BlobSegmentSize:=80;
  FConnection.BlobSegmentSize:=65535;
  FConnection.Connected:=true;
  FTransaction := TSQLTransaction.Create(nil);
  FConnection.Transaction := FTransaction;
  FQuery := TSQLQuery.Create(nil);
  FQuery.Database := FConnection;  
  FQuery.Close;
  FQuery.SQL.Text := 'SELECT ID, BLOBCOL FROM TESTTABLE;';
  
  //10 meg
  for TextCounter := 1 to 10485760 do
  begin
    RecordText := RecordText + '1';
  end;
  
  writeln('BlobSegmentSize = ' + IntToStr(FConnection.BlobSegmentSize));
  CurrentTime:=now(); 
  for RecordCounter := 0 to 500 do
  begin
    if (RecordCounter mod 10)=0 then
    begin
      // Free up space
      writeln('Cleanup at record ' + inttostr(recordcounter));
      FTransaction.Active:=True;
      FConnection.ExecuteDirect('DELETE FROM TESTTABLE');
      FTransaction.Commit;
      FTransaction.Active := True;
    end;
    Ftransaction.Active:=true;
    FQuery.Open;
    FQuery.Insert;
    FQuery.FieldByName('ID').AsInteger:=RecordCounter;
    FQuery.FieldByName('BLOBCOL').Clear;
    FQuery.FieldByName('BLOBCOL').AsString := RecordText;
    FQuery.Post;
    FQuery.ApplyUpdates;
    FTransaction.Commit;
  end;
  EndTime:=now();
  writeln('Time spent: '+ IntToStr(SecondsBetween(CurrentTime, EndTime)) + ' seconds.'); 
  FQuery.Close;
  FTransaction.Active:=false;
  FConnection.Close;
  FQuery.Free;  
  FTransaction.Free;  
  FConnection.Free;
end.