Browse Source

* StartRender/EndRender support (enable transaction control) for bug ID #0033496

git-svn-id: trunk@38629 -
michael 7 years ago
parent
commit
3adbab7855
2 changed files with 144 additions and 3 deletions
  1. 57 0
      packages/fcl-report/src/fpreportdata.pp
  2. 87 3
      packages/fcl-report/src/fpreportdatasqldb.pp

+ 57 - 0
packages/fcl-report/src/fpreportdata.pp

@@ -27,6 +27,10 @@ Type
     // Check if the configuration is valid. Return a string that describes the error(s)
     // If the return is an empty string, the data designer will not close.
     Class Function CheckConfig(AConfig : TJSONObject) : String; virtual;
+    // Called before and after rendering of a report in the designer.
+    // Can be used to start/stop transactions
+    Class Procedure StartRender(ADataset : TDataset); virtual;
+    Class Procedure EndRender(ADataset : TDataset); virtual;
     // Configuration component. This is normally a visual class.
     Class Function ConfigFrameClass : TComponentClass; virtual;
     Class Function DataType : String; virtual; abstract;
@@ -139,6 +143,9 @@ Type
     procedure RemoveFromReport;
     procedure ApplyToReport(aReport: TFPReport; Errors: TStrings); virtual;
     Procedure ApplyToReport(Errors : TStrings);
+    // call this to start/stop a render, so dataset handlers can do cleanup, refetch data, reset transactions.
+    Procedure StartRender;
+    Procedure EndRender;
     Property Report : TFPReport Read FReport Write SetReport;
     Property DataParent : TComponent Read FDataParent Write SetDataParent;
   end;
@@ -371,6 +378,46 @@ begin
   ApplyToReport(FReport,Errors);
 end;
 
+procedure TFPCustomReportDataManager.StartRender;
+
+Var
+  I : integer;
+  D : TFPReportDataDefinitionItem;
+  H : TFPReportDataHandler;
+
+begin
+  // Create all datasets
+  For I:=0 to DataDefinitions.Count-1 do
+    begin
+    D:=DataDefinitions[i];
+    if Assigned(D.RunReportData) then
+      begin
+      H:=TFPCustomReportDataManager.GetTypeHandler(D.DataType);
+      H.StartRender(D.RunReportData.DataSet);
+      end;
+    end;
+end;
+
+procedure TFPCustomReportDataManager.EndRender;
+
+Var
+  I : integer;
+  D : TFPReportDataDefinitionItem;
+  H : TFPReportDataHandler;
+
+begin
+  // Create all datasets
+  For I:=0 to DataDefinitions.Count-1 do
+    begin
+    D:=DataDefinitions[i];
+    if Assigned(D.RunReportData) then
+      begin
+      H:=TFPCustomReportDataManager.GetTypeHandler(D.DataType);
+      H.EndRender(D.RunReportData.DataSet);
+      end;
+    end;
+end;
+
 procedure TFPCustomReportDataManager.ApplyToReport(aReport : TFPReport; Errors: TStrings);
 
 
@@ -622,6 +669,16 @@ begin
   Result:='';
 end;
 
+class procedure TFPReportDataHandler.StartRender(ADataset: TDataset);
+begin
+  // Do nothing
+end;
+
+class procedure TFPReportDataHandler.EndRender(ADataset: TDataset);
+begin
+  // Do nothing
+end;
+
 class function TFPReportDataHandler.ConfigFrameClass: TComponentClass;
 begin
   Result:=Nil;

+ 87 - 3
packages/fcl-report/src/fpreportdatasqldb.pp

@@ -51,10 +51,12 @@ Type
       FPool : TStringList;
   Public
     Procedure LoadFromConfig(aConfig : TJSONObject);
-    class function CreateConnection(aConfig: TJSONObject): TFPReportConnector;
-    Class Function TestConnection (aConfig : TJSONObject) : string;
+    class function CreateConnection(aConfig: TJSONObject): TFPReportConnector; virtual;
+    Class Function TestConnection (aConfig : TJSONObject) : string; virtual;
     class function CreateDataset(aOwner: TComponent; aConfig: TJSONObject): TSQLQuery;
     class function CreateConfigHash(aConfig: TJSONObject): String;
+    Class Procedure StartRender(ADataset : TDataset); virtual;
+    Class Procedure EndRender(ADataset : TDataset); virtual;
     Class procedure CheckDBRelease;
     Property RefCount : Integer Read FRefCount;
   end;
@@ -67,11 +69,22 @@ Type
     Destructor Destroy; override;
   end;
 
+  { TReportSQLtransaction }
 
+  TFPReportSQLtransaction = Class(TSQLTransaction)
+  private
+    FStartRefCount: Integer;
+  Public
+    Procedure StartRender;
+    Procedure EndRender;
+    Property StartRefCount : Integer Read FStartRefCount;
+  end;
   { TSQLDBReportDataHandler }
 
   TSQLDBReportDataHandler = Class(TFPReportDataHandler)
     Function CreateDataset(AOwner : TComponent; AConfig : TJSONObject) : TDataset; override;
+    Class Procedure StartRender(ADataset : TDataset); override;
+    Class Procedure EndRender(ADataset : TDataset); override;
     Class Function CheckConfig(AConfig: TJSONObject): String; override;
     Class Function DataType : String; override;
     Class Function DataTypeDescription : String; override;
@@ -82,6 +95,30 @@ Type
 
 implementation
 
+{ TFPReportSQLtransaction }
+
+procedure TFPReportSQLtransaction.StartRender;
+
+Var
+  Start : Boolean;
+
+begin
+  Start:=(FStartRefCount=0);
+  Inc(FStartRefCount);
+  if Start and not Active then
+    StartTransaction;
+end;
+
+procedure TFPReportSQLtransaction.EndRender;
+begin
+  if FStartRefCount>0 then
+    begin
+    Dec(FStartRefCount);
+    If FStartRefCount=0 then
+      RollBack;
+    end;
+end;
+
 { TFPReportQuery }
 
 constructor TFPReportQuery.Create(AOwner: TComponent);
@@ -147,6 +184,43 @@ begin
       AH(IntToStr(I),A.Strings[i]);
 end;
 
+
+class procedure TFPReportConnector.StartRender(ADataset: TDataset);
+
+var
+  Q : TFPReportQuery;
+  T : TFPReportSQLTransaction;
+
+begin
+  if (aDataset is TFPReportQuery) then
+    begin
+    Q:=aDataset as TFPReportQuery;
+    if Q.Transaction is TFPReportSQLTransaction then
+      begin
+      T:=Q.Transaction as TFPReportSQLTransaction;
+      T.StartRender;
+      end;
+    end;
+end;
+
+class procedure TFPReportConnector.EndRender(ADataset: TDataset);
+
+var
+  Q : TFPReportQuery;
+  T : TFPReportSQLTransaction;
+
+begin
+  if (aDataset is TFPReportQuery) then
+    begin
+    Q:=aDataset as TFPReportQuery;
+    if Q.Transaction is TFPReportSQLTransaction then
+      begin
+      T:=Q.Transaction as TFPReportSQLTransaction;
+      T.EndRender;
+      end;
+    end;
+end;
+
 class procedure TFPReportConnector.CheckDBRelease;
 
 Var
@@ -189,7 +263,7 @@ class function TFPReportConnector.CreateConnection(aConfig: TJSONObject): TFPRep
 begin
   Result:=Self.Create(Nil);
   Result.LoadFromConfig(aConfig);
-  Result.Transaction:=TSQLtransaction.Create(Result);
+  Result.Transaction:=TFPReportSQLtransaction.Create(Result);
 end;
 
 class function TFPReportConnector.TestConnection(aConfig: TJSONObject): string;
@@ -243,6 +317,16 @@ begin
   Result:=TFPReportConnector.CreateDataset(aOwner,aConfig);
 end;
 
+class procedure TSQLDBReportDataHandler.StartRender(ADataset: TDataset);
+begin
+  TFPReportConnector.StartRender(aDataset);
+end;
+
+class procedure TSQLDBReportDataHandler.EndRender(ADataset: TDataset);
+begin
+  TFPReportConnector.EndRender(aDataset);
+end;
+
 class function TSQLDBReportDataHandler.CheckConfig(AConfig: TJSONObject): String;
 
 Var