浏览代码

* AutoCommit option

git-svn-id: trunk@29121 -
michael 10 年之前
父节点
当前提交
411e798495
共有 2 个文件被更改,包括 73 次插入35 次删除
  1. 27 5
      packages/fcl-db/src/sqldb/sqldb.pp
  2. 46 30
      packages/fcl-db/tests/testsqldb.pas

+ 27 - 5
packages/fcl-db/src/sqldb/sqldb.pp

@@ -60,7 +60,7 @@ type
   TDBEventTypes = set of TDBEventType;
   TDBEventTypes = set of TDBEventType;
   TDBLogNotifyEvent = Procedure (Sender : TSQLConnection; EventType : TDBEventType; Const Msg : String) of object;
   TDBLogNotifyEvent = Procedure (Sender : TSQLConnection; EventType : TDBEventType; Const Msg : String) of object;
 
 
-  TSQLQueryOption = (sqoDisconnected, sqoAutoApplyUpdates);
+  TSQLQueryOption = (sqoDisconnected, sqoAutoApplyUpdates, sqoAutoCommit);
   TSQLQueryOptions = Set of TSQLQueryOption;
   TSQLQueryOptions = Set of TSQLQueryOption;
 
 
   TSQLHandle = Class(TObject)
   TSQLHandle = Class(TObject)
@@ -317,6 +317,7 @@ type
     FTransaction: TSQLTransaction;
     FTransaction: TSQLTransaction;
     FParseSQL: Boolean;
     FParseSQL: Boolean;
     FDataLink : TDataLink;
     FDataLink : TDataLink;
+    FRowsAffected : TRowsCount;
     procedure SetDatabase(AValue: TSQLConnection);
     procedure SetDatabase(AValue: TSQLConnection);
     procedure SetParams(AValue: TParams);
     procedure SetParams(AValue: TParams);
     procedure SetSQL(AValue: TStrings);
     procedure SetSQL(AValue: TStrings);
@@ -463,6 +464,7 @@ type
   public
   public
     constructor Create(AOwner : TComponent); override;
     constructor Create(AOwner : TComponent); override;
     destructor Destroy; override;
     destructor Destroy; override;
+    Procedure ApplyUpdates(MaxErrors: Integer); override; overload;
     procedure Prepare; virtual;
     procedure Prepare; virtual;
     procedure UnPrepare; virtual;
     procedure UnPrepare; virtual;
     procedure ExecSQL; virtual;
     procedure ExecSQL; virtual;
@@ -869,6 +871,7 @@ end;
 
 
 Procedure TCustomSQLStatement.DoExecute;
 Procedure TCustomSQLStatement.DoExecute;
 begin
 begin
+  FRowsAffected:=-1;
   If (FParams.Count>0) and Assigned(DataSource) then
   If (FParams.Count>0) and Assigned(DataSource) then
     CopyParamsFromMaster(False);
     CopyParamsFromMaster(False);
   If LogEvent(detExecute) then
   If LogEvent(detExecute) then
@@ -1074,10 +1077,12 @@ end;
 
 
 function TCustomSQLStatement.RowsAffected: TRowsCount;
 function TCustomSQLStatement.RowsAffected: TRowsCount;
 begin
 begin
-  Result := -1;
-  if not Assigned(Database) then
-    Exit;
-  Result:=Database.RowsAffected(FCursor);
+  if FRowsAffected=-1 then
+    begin
+    if Assigned(Database) then
+      FRowsAffected:=Database.RowsAffected(FCursor);
+    end;
+  Result:=FRowsAffected;
 end;
 end;
 
 
 { TSQLConnection }
 { TSQLConnection }
@@ -2067,6 +2072,17 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+Procedure TCustomSQLQuery.ApplyUpdates(MaxErrors: Integer);
+begin
+  inherited ApplyUpdates(MaxErrors);
+  If sqoAutoCommit in QueryOptions then
+    begin
+    // Retrieve rows affected for last update.
+    FStatement.RowsAffected;
+    SQLTransaction.Commit;
+    end;
+end;
+
 function TCustomSQLQuery.ParamByName(Const AParamName: String): TParam;
 function TCustomSQLQuery.ParamByName(Const AParamName: String): TParam;
 
 
 begin
 begin
@@ -2401,6 +2417,12 @@ begin
   try
   try
     Prepare;
     Prepare;
     Execute;
     Execute;
+    If sqoAutoCommit in QueryOptions then
+      begin
+      // Retrieve rows affected
+      FStatement.RowsAffected;
+      SQLTransaction.Commit;
+      end;
   finally
   finally
     // Cursor has to be assigned, or else the prepare went wrong before PrepareStatment was
     // Cursor has to be assigned, or else the prepare went wrong before PrepareStatment was
     //   called, so UnPrepareStatement shoudn't be called either
     //   called, so UnPrepareStatement shoudn't be called either

+ 46 - 30
packages/fcl-db/tests/testsqldb.pas

@@ -46,6 +46,7 @@ type
     Procedure TestAutoApplyUpdatesPost;
     Procedure TestAutoApplyUpdatesPost;
     Procedure TestAutoApplyUpdatesDelete;
     Procedure TestAutoApplyUpdatesDelete;
     Procedure TestCheckRowsAffected;
     Procedure TestCheckRowsAffected;
+    Procedure TestAutoCOmmit;
   end;
   end;
 
 
   { TTestTSQLConnection }
   { TTestTSQLConnection }
@@ -183,11 +184,7 @@ begin
   // Test also that an edit still works.
   // Test also that an edit still works.
   with SQLDBConnector do
   with SQLDBConnector do
     begin
     begin
-    try
-      ExecuteDirect('DROP table testdiscon');
-    except
-      // Ignore
-    end;
+    TryDropIfExist('testdiscon');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     Transaction.COmmit;
     Transaction.COmmit;
     for I:=1 to 20 do
     for I:=1 to 20 do
@@ -250,11 +247,7 @@ begin
   // Check that we can only set QueryOptions when the query is inactive.
   // Check that we can only set QueryOptions when the query is inactive.
   with SQLDBConnector do
   with SQLDBConnector do
     begin
     begin
-    try
-      ExecuteDirect('DROP table testdiscon');
-    except
-      // Ignore
-    end;
+    TryDropIfExist('testdiscon');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     Transaction.COmmit;
     Transaction.COmmit;
      ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[1,1]));
      ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[1,1]));
@@ -275,11 +268,7 @@ begin
   // Test also that POST afterpost event is backwards compatible.
   // Test also that POST afterpost event is backwards compatible.
   with SQLDBConnector do
   with SQLDBConnector do
     begin
     begin
-    try
-      ExecuteDirect('DROP table testdiscon');
-    except
-      // Ignore
-    end;
+    TryDropIfExist('testdiscon');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     Transaction.COmmit;
     Transaction.COmmit;
     for I:=1 to 2 do
     for I:=1 to 2 do
@@ -315,11 +304,7 @@ begin
   // Test that if sqoAutoApplyUpdates is in QueryOptions, then Delete automatically does an ApplyUpdates
   // Test that if sqoAutoApplyUpdates is in QueryOptions, then Delete automatically does an ApplyUpdates
   with SQLDBConnector do
   with SQLDBConnector do
     begin
     begin
-    try
-      ExecuteDirect('DROP table testdiscon');
-    except
-      // Ignore
-    end;
+    TryDropIfExist('testdiscon');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     Transaction.COmmit;
     Transaction.COmmit;
     for I:=1 to 2 do
     for I:=1 to 2 do
@@ -357,11 +342,7 @@ begin
   // Test that if sqoAutoApplyUpdates is in QueryOptions, then Delete automatically does an ApplyUpdates
   // Test that if sqoAutoApplyUpdates is in QueryOptions, then Delete automatically does an ApplyUpdates
   with SQLDBConnector do
   with SQLDBConnector do
     begin
     begin
-    try
-      ExecuteDirect('DROP table testdiscon');
-    except
-      // Ignore
-    end;
+    TryDropIfExist('testdiscon');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     Transaction.COmmit;
     Transaction.COmmit;
     for I:=1 to 2 do
     for I:=1 to 2 do
@@ -380,6 +361,45 @@ begin
     end;
     end;
 end;
 end;
 
 
+Procedure TTestTSQLQuery.TestAutoCOmmit;
+var
+  Q: TSQLQuery;
+  T : TSQLTransaction;
+  I, J : Integer;
+begin
+  with SQLDBConnector do
+    begin
+    TryDropIfExist('testdiscon');
+    ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
+    if Transaction.Active then
+      Transaction.Commit;
+    end;
+  Q:=SQLDBConnector.Query;
+  Q.QueryOptions:=[sqoAutoCommit];
+  for I:=1 to 2 do
+    begin
+    Q.SQL.Text:=Format('INSERT INTO testdiscon values (%d,''%.6d'');',[i,i]);
+    Q.Prepare;
+    Q.ExecSQL;
+    // We do not commit anything explicitly.
+    end;
+  Q:=Nil;
+  T:=Nil;
+  try
+    T:=TSQLTransaction.Create(Nil);
+    Q:=TSQLQuery.Create(Nil);
+    Q.Transaction:=T;
+    Q.Database:=SQLDBConnector.Connection;
+    T.Database:=SQLDBConnector.Connection;
+    Q.SQL.text:='SELECT COUNT(*) from testdiscon';
+    Q.Open;
+    AssertEquals('Records have been committed to database',2,Q.Fields[0].AsInteger);
+  finally
+    Q.Free;
+    T.Free;
+  end;
+end;
+
 
 
 { TTestTSQLConnection }
 { TTestTSQLConnection }
 
 
@@ -437,11 +457,7 @@ var
 begin
 begin
   with SQLDBConnector do
   with SQLDBConnector do
     begin
     begin
-    try
-      TryDropIfExist('testdiscon');
-    except
-      // Ignore
-    end;
+    TryDropIfExist('testdiscon');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))');
     if Transaction.Active then
     if Transaction.Active then
       Transaction.Commit;
       Transaction.Commit;