Browse Source

fcl-db: sqldb: fix AV (uninitialized variable) in MySQL tests
rearrange ordering of methods
rename some methods as discussed in DB-Core

git-svn-id: trunk@29196 -

lacak 10 years ago
parent
commit
e3b12486c5

+ 1 - 1
packages/fcl-db/src/base/bufdataset.pas

@@ -512,7 +512,6 @@ type
     procedure RemoveRecordFromIndexes(const ABookmark : TBufBookmark);
     procedure RemoveRecordFromIndexes(const ABookmark : TBufBookmark);
   protected
   protected
     // abstract & virtual methods of TDataset
     // abstract & virtual methods of TDataset
-    procedure ActiveBufferToRecord;
     procedure SetPacketRecords(aValue : integer); virtual;
     procedure SetPacketRecords(aValue : integer); virtual;
     procedure UpdateIndexDefs; override;
     procedure UpdateIndexDefs; override;
     procedure SetRecNo(Value: Longint); override;
     procedure SetRecNo(Value: Longint); override;
@@ -559,6 +558,7 @@ type
     procedure SetReadOnly(AValue: Boolean); virtual;
     procedure SetReadOnly(AValue: Boolean); virtual;
     function IsReadFromPacket : Boolean;
     function IsReadFromPacket : Boolean;
     function getnextpacket : integer;
     function getnextpacket : integer;
+    procedure ActiveBufferToRecord;
     // abstracts, must be overidden by descendents
     // abstracts, must be overidden by descendents
     function Fetch : boolean; virtual;
     function Fetch : boolean; virtual;
     function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual;
     function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual;

+ 9 - 10
packages/fcl-db/src/sqldb/mysql/mysqlconn.inc

@@ -99,12 +99,11 @@ Type
     procedure ExecuteDirectMySQL(const query : string);
     procedure ExecuteDirectMySQL(const query : string);
     function EscapeString(const Str : string) : string;
     function EscapeString(const Str : string) : string;
   protected
   protected
-    function GetLastInsertIDForField(Query : TCustomSQLQuery; AField : TField): Boolean; override;
-    function StrToStatementType(s : string) : TStatementType; override;
     Procedure ConnectToServer; virtual;
     Procedure ConnectToServer; virtual;
     Procedure SelectDatabase; virtual;
     Procedure SelectDatabase; virtual;
     function MySQLDataType(AField: PMYSQL_FIELD; var NewType: TFieldType; var NewSize: Integer): Boolean;
     function MySQLDataType(AField: PMYSQL_FIELD; var NewType: TFieldType; var NewSize: Integer): Boolean;
     function MySQLWriteData(AField: PMYSQL_FIELD; FieldDef: TFieldDef; Source, Dest: PChar; Len: integer; out CreateBlob : boolean): Boolean;
     function MySQLWriteData(AField: PMYSQL_FIELD; FieldDef: TFieldDef; Source, Dest: PChar; Len: integer; out CreateBlob : boolean): Boolean;
+
     // SQLConnection methods
     // SQLConnection methods
     procedure DoInternalConnect; override;
     procedure DoInternalConnect; override;
     procedure DoInternalDisconnect; override;
     procedure DoInternalDisconnect; override;
@@ -117,6 +116,7 @@ Type
     Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override;
     Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override;
     Function AllocateTransactionHandle : TSQLHandle; override;
     Function AllocateTransactionHandle : TSQLHandle; override;
 
 
+    function StrToStatementType(s : string) : TStatementType; override;
     procedure PrepareStatement(cursor: TSQLCursor;ATransaction : TSQLTransaction;buf : string; AParams : TParams); override;
     procedure PrepareStatement(cursor: TSQLCursor;ATransaction : TSQLTransaction;buf : string; AParams : TParams); override;
     procedure UnPrepareStatement(cursor:TSQLCursor); override;
     procedure UnPrepareStatement(cursor:TSQLCursor); override;
     procedure FreeFldBuffers(cursor : TSQLCursor); override;
     procedure FreeFldBuffers(cursor : TSQLCursor); override;
@@ -134,6 +134,7 @@ Type
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
     procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
+    function RefreshLastInsertID(Query : TCustomSQLQuery; Field : TField): Boolean; override;
   Public
   Public
     constructor Create(AOwner : TComponent); override;
     constructor Create(AOwner : TComponent); override;
     procedure GetFieldNames(const TableName : string; List :  TStrings); override;
     procedure GetFieldNames(const TableName : string; List :  TStrings); override;
@@ -464,14 +465,6 @@ begin
   SetLength(result,Len);
   SetLength(result,Len);
 end;
 end;
 
 
-function TConnectionName.GetLastInsertIDForField(Query: TCustomSQLQuery;
-  AField: TField): Boolean;
-begin
-  Result:=inherited GetLastInsertIDForField(Query, AField);
-  if Result then
-    AField.AsLargeInt:=GetInsertID;
-end;
-
 procedure TConnectionName.DoInternalConnect;
 procedure TConnectionName.DoInternalConnect;
 var
 var
   FullVersion: string;
   FullVersion: string;
@@ -1127,6 +1120,12 @@ begin
     Result := -1;
     Result := -1;
 end;
 end;
 
 
+function TConnectionName.RefreshLastInsertID(Query: TCustomSQLQuery; Field: TField): Boolean;
+begin
+  Field.AsLargeInt:=GetInsertID;
+  Result := True;
+end;
+
 constructor TConnectionName.Create(AOwner: TComponent);
 constructor TConnectionName.Create(AOwner: TComponent);
 const SingleBackQoutes: TQuoteChars = ('`','`');
 const SingleBackQoutes: TQuoteChars = ('`','`');
 begin
 begin

+ 131 - 128
packages/fcl-db/src/sqldb/sqldb.pp

@@ -172,15 +172,15 @@ type
     // One day, this may be factored out to a TSQLResolver class.
     // One day, this may be factored out to a TSQLResolver class.
     // The following allow construction of update queries. They can be adapted as needed by descendents to fit the DB engine.
     // The following allow construction of update queries. They can be adapted as needed by descendents to fit the DB engine.
     procedure AddFieldToUpdateWherePart(var sql_where: string; UpdateMode : TUpdateMode; F: TField); virtual;
     procedure AddFieldToUpdateWherePart(var sql_where: string; UpdateMode : TUpdateMode; F: TField); virtual;
-    function ConstructRefreshSQL(Query: TCustomSQLQuery; UpdateKind : TUpdateKind): string; virtual;
-    function ConstructDeleteSQL(Query: TCustomSQLQuery): string; virtual;
     function ConstructInsertSQL(Query: TCustomSQLQuery): string; virtual;
     function ConstructInsertSQL(Query: TCustomSQLQuery): string; virtual;
     function ConstructUpdateSQL(Query: TCustomSQLQuery): string; virtual;
     function ConstructUpdateSQL(Query: TCustomSQLQuery): string; virtual;
+    function ConstructDeleteSQL(Query: TCustomSQLQuery): string; virtual;
+    function ConstructRefreshSQL(Query: TCustomSQLQuery; UpdateKind : TUpdateKind): string; virtual;
     function InitialiseUpdateStatement(Query: TCustomSQLQuery; var qry: TCustomSQLStatement): TCustomSQLStatement;
     function InitialiseUpdateStatement(Query: TCustomSQLQuery; var qry: TCustomSQLStatement): TCustomSQLStatement;
     procedure ApplyFieldUpdate(C : TSQLCursor; P: TSQLDBParam; F: TField; UseOldValue: Boolean); virtual;
     procedure ApplyFieldUpdate(C : TSQLCursor; P: TSQLDBParam; F: TField; UseOldValue: Boolean); virtual;
     // This is the call that updates a record, it used to be in TSQLQuery.
     // This is the call that updates a record, it used to be in TSQLQuery.
-    function GetLastInsertIDForField(Query : TCustomSQLQuery; AField : TField): Boolean; virtual;
     procedure ApplyRecUpdate(Query : TCustomSQLQuery; UpdateKind : TUpdateKind); virtual;
     procedure ApplyRecUpdate(Query : TCustomSQLQuery; UpdateKind : TUpdateKind); virtual;
+    function RefreshLastInsertID(Query : TCustomSQLQuery; Field : TField): Boolean; virtual;
     procedure GetDBInfo(const ASchemaType : TSchemaType; const ASchemaObjectName, AReturnField : string; AList: TStrings);
     procedure GetDBInfo(const ASchemaType : TSchemaType; const ASchemaObjectName, AReturnField : string; AList: TStrings);
     procedure SetTransaction(Value : TSQLTransaction); virtual;
     procedure SetTransaction(Value : TSQLTransaction); virtual;
     procedure DoInternalConnect; override;
     procedure DoInternalConnect; override;
@@ -384,10 +384,10 @@ type
     FUpdateable          : boolean;
     FUpdateable          : boolean;
     FTableName           : string;
     FTableName           : string;
     FStatement           : TCustomSQLStatement;
     FStatement           : TCustomSQLStatement;
-    FRefreshSQL,
-    FUpdateSQL,
     FInsertSQL,
     FInsertSQL,
-    FDeleteSQL           : TStringList;
+    FUpdateSQL,
+    FDeleteSQL,
+    FRefreshSQL          : TStringList;
     FIsEOF               : boolean;
     FIsEOF               : boolean;
     FLoadingFieldDefs    : boolean;
     FLoadingFieldDefs    : boolean;
     FUpdateMode          : TUpdateMode;
     FUpdateMode          : TUpdateMode;
@@ -403,30 +403,30 @@ type
     FSchemaObjectName    : string;
     FSchemaObjectName    : string;
     FSchemaPattern       : string;
     FSchemaPattern       : string;
 
 
+    FInsertQry,
     FUpdateQry,
     FUpdateQry,
-    FDeleteQry,
-    FInsertQry           : TCustomSQLStatement;
+    FDeleteQry           : TCustomSQLStatement;
     procedure FreeFldBuffers;
     procedure FreeFldBuffers;
     function GetParamCheck: Boolean;
     function GetParamCheck: Boolean;
     function GetParams: TParams;
     function GetParams: TParams;
     function GetParseSQL: Boolean;
     function GetParseSQL: Boolean;
     function GetServerIndexDefs: TServerIndexDefs;
     function GetServerIndexDefs: TServerIndexDefs;
-    function GetSQL: TStringlist;
+    function GetSQL: TStringList;
     function GetSQLConnection: TSQLConnection;
     function GetSQLConnection: TSQLConnection;
     function GetSQLTransaction: TSQLTransaction;
     function GetSQLTransaction: TSQLTransaction;
     function GetStatementType : TStatementType;
     function GetStatementType : TStatementType;
-    Function NeedLastinsertID: TField;
+    Function NeedLastInsertID: TField;
     procedure SetOptions(AValue: TSQLQueryOptions);
     procedure SetOptions(AValue: TSQLQueryOptions);
     procedure SetParamCheck(AValue: Boolean);
     procedure SetParamCheck(AValue: Boolean);
-    procedure SetRefreshSQL(AValue: TStringlist);
     procedure SetSQLConnection(AValue: TSQLConnection);
     procedure SetSQLConnection(AValue: TSQLConnection);
     procedure SetSQLTransaction(AValue: TSQLTransaction);
     procedure SetSQLTransaction(AValue: TSQLTransaction);
-    procedure SetUpdateSQL(const AValue: TStringlist);
-    procedure SetDeleteSQL(const AValue: TStringlist);
-    procedure SetInsertSQL(const AValue: TStringlist);
+    procedure SetInsertSQL(const AValue: TStringList);
+    procedure SetUpdateSQL(const AValue: TStringList);
+    procedure SetDeleteSQL(const AValue: TStringList);
+    procedure SetRefreshSQL(const AValue: TStringList);
     procedure SetParams(AValue: TParams);
     procedure SetParams(AValue: TParams);
     procedure SetParseSQL(AValue : Boolean);
     procedure SetParseSQL(AValue : Boolean);
-    procedure SetSQL(const AValue: TStringlist);
+    procedure SetSQL(const AValue: TStringList);
     procedure SetUsePrimaryKeyAsKey(AValue : Boolean);
     procedure SetUsePrimaryKeyAsKey(AValue : Boolean);
     procedure SetUpdateMode(AValue : TUpdateMode);
     procedure SetUpdateMode(AValue : TUpdateMode);
     procedure OnChangeModifySQL(Sender : TObject);
     procedure OnChangeModifySQL(Sender : TObject);
@@ -434,10 +434,9 @@ type
     procedure ApplyFilter;
     procedure ApplyFilter;
     Function AddFilter(SQLstr : string) : string;
     Function AddFilter(SQLstr : string) : string;
   protected
   protected
-    Function UpdateLastInsertIDField(F: TField): Boolean; virtual;
+    Function RefreshLastInsertID(Field: TField): Boolean; virtual;
     Function NeedRefreshRecord (UpdateKind: TUpdateKind): Boolean; virtual;
     Function NeedRefreshRecord (UpdateKind: TUpdateKind): Boolean; virtual;
     Function RefreshRecord (UpdateKind: TUpdateKind) : Boolean; virtual;
     Function RefreshRecord (UpdateKind: TUpdateKind) : Boolean; virtual;
-    procedure SetPacketRecords(aValue : integer); override;
     Function Cursor : TSQLCursor;
     Function Cursor : TSQLCursor;
     Function LogEvent(EventType : TDBEventType) : Boolean;
     Function LogEvent(EventType : TDBEventType) : Boolean;
     Procedure Log(EventType : TDBEventType; Const Msg : String); virtual;
     Procedure Log(EventType : TDBEventType; Const Msg : String); virtual;
@@ -446,6 +445,7 @@ type
     function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
     function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); override;
     procedure ApplyRecUpdate(UpdateKind : TUpdateKind); override;
     procedure ApplyRecUpdate(UpdateKind : TUpdateKind); override;
+    procedure SetPacketRecords(aValue : integer); override;
     // abstract & virtual methods of TDataset
     // abstract & virtual methods of TDataset
     procedure UpdateServerIndexDefs; virtual;
     procedure UpdateServerIndexDefs; virtual;
     procedure SetDatabase(Value : TDatabase); override;
     procedure SetDatabase(Value : TDatabase); override;
@@ -476,14 +476,15 @@ type
     procedure Prepare; virtual;
     procedure Prepare; virtual;
     procedure UnPrepare; virtual;
     procedure UnPrepare; virtual;
     procedure ExecSQL; virtual;
     procedure ExecSQL; virtual;
-    Procedure Post; override;
-    Procedure Delete; override;
     procedure SetSchemaInfo( ASchemaType : TSchemaType; ASchemaObjectName, ASchemaPattern : string); virtual;
     procedure SetSchemaInfo( ASchemaType : TSchemaType; ASchemaObjectName, ASchemaPattern : string); virtual;
     function RowsAffected: TRowsCount; virtual;
     function RowsAffected: TRowsCount; virtual;
     function ParamByName(Const AParamName : String) : TParam;
     function ParamByName(Const AParamName : String) : TParam;
     Property Prepared : boolean read IsPrepared;
     Property Prepared : boolean read IsPrepared;
     Property SQLConnection : TSQLConnection Read GetSQLConnection Write SetSQLConnection;
     Property SQLConnection : TSQLConnection Read GetSQLConnection Write SetSQLConnection;
     Property SQLTransaction: TSQLTransaction Read GetSQLTransaction Write SetSQLTransaction;
     Property SQLTransaction: TSQLTransaction Read GetSQLTransaction Write SetSQLTransaction;
+    // overriden TDataSet methods
+    Procedure Post; override;
+    Procedure Delete; override;
   protected
   protected
     // redeclared TDataSet properties
     // redeclared TDataSet properties
     property Active;
     property Active;
@@ -517,10 +518,10 @@ type
     property Transaction;
     property Transaction;
     property SchemaType : TSchemaType read FSchemaType default stNoSchema;
     property SchemaType : TSchemaType read FSchemaType default stNoSchema;
     property SQL : TStringlist read GetSQL write SetSQL;
     property SQL : TStringlist read GetSQL write SetSQL;
-    property UpdateSQL : TStringlist read FUpdateSQL write SetUpdateSQL;
-    property InsertSQL : TStringlist read FInsertSQL write SetInsertSQL;
-    property DeleteSQL : TStringlist read FDeleteSQL write SetDeleteSQL;
-    property RefreshSQL : TStringlist read FRefreshSQL write SetRefreshSQL;
+    property InsertSQL : TStringList read FInsertSQL write SetInsertSQL;
+    property UpdateSQL : TStringList read FUpdateSQL write SetUpdateSQL;
+    property DeleteSQL : TStringList read FDeleteSQL write SetDeleteSQL;
+    property RefreshSQL : TStringList read FRefreshSQL write SetRefreshSQL;
     Property Options : TSQLQueryOptions Read FOptions Write SetOptions;
     Property Options : TSQLQueryOptions Read FOptions Write SetOptions;
     property Params : TParams read GetParams Write SetParams;
     property Params : TParams read GetParams Write SetParams;
     Property ParamCheck : Boolean Read GetParamCheck Write SetParamCheck default true;
     Property ParamCheck : Boolean Read GetParamCheck Write SetParamCheck default true;
@@ -575,10 +576,10 @@ type
     property Transaction;
     property Transaction;
     property ReadOnly;
     property ReadOnly;
     property SQL;
     property SQL;
-    property UpdateSQL;
     property InsertSQL;
     property InsertSQL;
-    property RefreshSQL;
+    property UpdateSQL;
     property DeleteSQL;
     property DeleteSQL;
+    property RefreshSQL;
     property IndexDefs;
     property IndexDefs;
     Property Options;
     Property Options;
     property Params;
     property Params;
@@ -727,8 +728,8 @@ implementation
 uses dbconst, strutils;
 uses dbconst, strutils;
 
 
 Const
 Const
-  // Flags to check which fields must be refreshed. Index is false for update, true for insert
-  RefreshFlags : Array [Boolean] of TProviderFlag = (pfRefreshOnUpdate,pfRefreshOnUpdate);
+  // Flags to check which fields must be refreshed.
+  RefreshFlags : Array [ukModify..ukInsert] of TProviderFlag = (pfRefreshOnUpdate,pfRefreshOnInsert);
 
 
 
 
 function TimeIntervalToString(Time: TDateTime): string;
 function TimeIntervalToString(Time: TDateTime): string;
@@ -1559,6 +1560,7 @@ begin
   Result:=qry;
   Result:=qry;
 end;
 end;
 
 
+
 procedure TSQLConnection.AddFieldToUpdateWherePart(var sql_where : string;UpdateMode : TUpdateMode; F : TField);
 procedure TSQLConnection.AddFieldToUpdateWherePart(var sql_where : string;UpdateMode : TUpdateMode; F : TField);
 
 
 begin
 begin
@@ -1577,45 +1579,35 @@ begin
      end;
      end;
 end;
 end;
 
 
-function TSQLConnection.ConstructRefreshSQL(Query: TCustomSQLQuery;
-  UpdateKind: TUpdateKind): string;
 
 
-Var
-  F : TField;
-  PF : TProviderFlag;
-  Where : String;
+function TSQLConnection.ConstructInsertSQL(Query : TCustomSQLQuery) : string;
+
+var x          : integer;
+    sql_fields : string;
+    sql_values : string;
+    F : TField;
 
 
 begin
 begin
-  Where:='';
-  Result:=Query.RefreshSQL.Text;
-  if (Result='') then
+  sql_fields := '';
+  sql_values := '';
+  for x := 0 to Query.Fields.Count -1 do
     begin
     begin
-    PF:=RefreshFlags[UpdateKind=ukInsert];
-    For F in Query.Fields do
+    F:=Query.Fields[x];
+    if (not F.IsNull) and (pfInUpdate in F.ProviderFlags) and (not F.ReadOnly) then
       begin
       begin
-      if PF in F.ProviderFlags then
-        begin
-        if (Result<>'') then
-          Result:=Result+', ';
-        if (F.Origin<>'') and (F.Origin<>F.FieldName) then
-          Result:=Result+F.Origin+' as '+F.FieldName
-        else
-          Result:=Result+FieldNameQuoteChars[0]+F.FieldName+FieldNameQuoteChars[1]
-        end;
-      if pfInkey in F.ProviderFlags then
-        begin
-        if (Where<>'') then
-          Where:=Where+' AND ';
-        Where:=Where+'('+FieldNameQuoteChars[0]+F.FieldName+FieldNameQuoteChars[0]+' = :'+F.FieldName+')';
-        end;
+      sql_fields := sql_fields + FieldNameQuoteChars[0] + F.FieldName + FieldNameQuoteChars[1] + ',';
+      sql_values := sql_values + ':"' + F.FieldName + '",';
       end;
       end;
-    if (Where='') then
-      DatabaseError(SErrNoKeyFieldForRefreshClause,Query);
-    Result:='SELECT '+Result+' FROM '+Query.FTableName+' WHERE '+Where;
     end;
     end;
+  if length(sql_fields) = 0 then
+    DatabaseErrorFmt(sNoUpdateFields,['insert'],self);
+  setlength(sql_fields,length(sql_fields)-1);
+  setlength(sql_values,length(sql_values)-1);
 
 
+  result := 'insert into ' + Query.FTableName + ' (' + sql_fields + ') values (' + sql_values + ')';
 end;
 end;
 
 
+
 function TSQLConnection.ConstructUpdateSQL(Query: TCustomSQLQuery): string;
 function TSQLConnection.ConstructUpdateSQL(Query: TCustomSQLQuery): string;
 
 
 var x : integer;
 var x : integer;
@@ -1639,33 +1631,6 @@ begin
   result := 'update ' + Query.FTableName + ' set ' + sql_set + ' where ' + sql_where;
   result := 'update ' + Query.FTableName + ' set ' + sql_set + ' where ' + sql_where;
 end;
 end;
 
 
-function TSQLConnection.ConstructInsertSQL(Query : TCustomSQLQuery) : string;
-
-var x          : integer;
-    sql_fields : string;
-    sql_values : string;
-    F : TField;
-
-begin
-  sql_fields := '';
-  sql_values := '';
-  for x := 0 to Query.Fields.Count -1 do
-    begin
-    F:=Query.Fields[x];
-    if (not F.IsNull) and (pfInUpdate in F.ProviderFlags) and (not F.ReadOnly) then
-      begin
-      sql_fields := sql_fields + FieldNameQuoteChars[0] + F.FieldName + FieldNameQuoteChars[1] + ',';
-      sql_values := sql_values + ':"' + F.FieldName + '",';
-      end;
-    end;
-  if length(sql_fields) = 0 then
-    DatabaseErrorFmt(sNoUpdateFields,['insert'],self);
-  setlength(sql_fields,length(sql_fields)-1);
-  setlength(sql_values,length(sql_values)-1);
-
-  result := 'insert into ' + Query.FTableName + ' (' + sql_fields + ') values (' + sql_values + ')';
-end;
-
 
 
 function TSQLConnection.ConstructDeleteSQL(Query : TCustomSQLQuery) :  string;
 function TSQLConnection.ConstructDeleteSQL(Query : TCustomSQLQuery) :  string;
 
 
@@ -1682,6 +1647,43 @@ begin
   result := 'delete from ' + Query.FTableName + ' where ' + sql_where;
   result := 'delete from ' + Query.FTableName + ' where ' + sql_where;
 end;
 end;
 
 
+function TSQLConnection.ConstructRefreshSQL(Query: TCustomSQLQuery; UpdateKind: TUpdateKind): string;
+
+Var
+  F : TField;
+  PF : TProviderFlag;
+  Where : String;
+
+begin
+  Where:='';
+  Result:=Query.RefreshSQL.Text;
+  if (Result='') then
+    begin
+    PF:=RefreshFlags[UpdateKind];
+    For F in Query.Fields do
+      begin
+      if PF in F.ProviderFlags then
+        begin
+        if (Result<>'') then
+          Result:=Result+', ';
+        if (F.Origin<>'') and (F.Origin<>F.FieldName) then
+          Result:=Result+F.Origin+' AS '+F.FieldName
+        else
+          Result:=Result+FieldNameQuoteChars[0]+F.FieldName+FieldNameQuoteChars[1]
+        end;
+      if pfInkey in F.ProviderFlags then
+        begin
+        if (Where<>'') then
+          Where:=Where+' AND ';
+        Where:=Where+'('+FieldNameQuoteChars[0]+F.FieldName+FieldNameQuoteChars[0]+' = :'+F.FieldName+')';
+        end;
+      end;
+    if (Where='') then
+      DatabaseError(SErrNoKeyFieldForRefreshClause,Query);
+    Result:='SELECT '+Result+' FROM '+Query.FTableName+' WHERE '+Where;
+    end;
+end;
+
 procedure TSQLConnection.ApplyFieldUpdate(C : TSQLCursor; P : TSQLDBParam;F : TField; UseOldValue : Boolean);
 procedure TSQLConnection.ApplyFieldUpdate(C : TSQLCursor; P : TSQLDBParam;F : TField; UseOldValue : Boolean);
 
 
 begin
 begin
@@ -1692,11 +1694,6 @@ begin
   P.FFieldDef:=F.FieldDef;
   P.FFieldDef:=F.FieldDef;
 end;
 end;
 
 
-function TSQLConnection.GetLastInsertIDForField(Query: TCustomSQLQuery; AField: TField): Boolean;
-begin
-  Result:=sqLastInsertID in ConnOptions;
-end;
-
 procedure TSQLConnection.ApplyRecUpdate(Query: TCustomSQLQuery; UpdateKind: TUpdateKind);
 procedure TSQLConnection.ApplyRecUpdate(Query: TCustomSQLQuery; UpdateKind: TUpdateKind);
 
 
 var
 var
@@ -1745,6 +1742,11 @@ begin
     DatabaseErrorFmt(SErrFailedToUpdateRecord, [Qry.RowsAffected], Query);
     DatabaseErrorFmt(SErrFailedToUpdateRecord, [Qry.RowsAffected], Query);
 end;
 end;
 
 
+function TSQLConnection.RefreshLastInsertID(Query: TCustomSQLQuery; Field: TField): Boolean;
+begin
+  Result:=False;
+end;
+
 procedure TSQLConnection.FreeFldBuffers(cursor: TSQLCursor);
 procedure TSQLConnection.FreeFldBuffers(cursor: TSQLCursor);
 begin
 begin
   // empty
   // empty
@@ -2205,17 +2207,17 @@ Function TCustomSQLQuery.NeedRefreshRecord(UpdateKind: TUpdateKind): Boolean;
 
 
 
 
 Var
 Var
-  F : TProviderFlag;
+  PF : TProviderFlag;
   I : Integer;
   I : Integer;
 begin
 begin
   Result:=(FRefreshSQL.Count<>0);
   Result:=(FRefreshSQL.Count<>0);
   if Not Result then
   if Not Result then
     begin
     begin
-    F:=RefreshFlags[UpdateKind=ukInsert];
+    PF:=RefreshFlags[UpdateKind];
     I:=0;
     I:=0;
     While (Not Result) and (I<Fields.Count) do
     While (Not Result) and (I<Fields.Count) do
       begin
       begin
-      Result:=F in Fields[i].ProviderFlags;
+      Result:=PF in Fields[i].ProviderFlags;
       Inc(I);
       Inc(I);
       end;
       end;
     end;
     end;
@@ -2228,7 +2230,6 @@ Var
   P : TParam;
   P : TParam;
   F,FD : TField;
   F,FD : TField;
   N : String;
   N : String;
-  S : TDatasetState;
 
 
 begin
 begin
   Result:=False;
   Result:=False;
@@ -2375,14 +2376,6 @@ begin
   Result:=Transaction as TSQLTransaction;
   Result:=Transaction as TSQLTransaction;
 end;
 end;
 
 
-procedure TCustomSQLQuery.SetPacketRecords(aValue: integer);
-begin
-  if (AValue=PacketRecords) then exit;
-  if (AValue<>-1) and (sqoKeepOpenOnCommit in Options) then
-    DatabaseError(SErrDisconnectedPacketRecords);
-  Inherited SetPacketRecords(aValue);
-end;
-
 Function TCustomSQLQuery.Cursor: TSQLCursor;
 Function TCustomSQLQuery.Cursor: TSQLCursor;
 begin
 begin
   Result:=FStatement.Cursor;
   Result:=FStatement.Cursor;
@@ -2586,11 +2579,6 @@ begin
   FStatement.SQL.Assign(AValue);
   FStatement.SQL.Assign(AValue);
 end;
 end;
 
 
-procedure TCustomSQLQuery.SetUpdateSQL(const AValue: TStringlist);
-begin
-  FUpdateSQL.Assign(AValue);
-end;
-
 procedure TCustomSQLQuery.SetUsePrimaryKeyAsKey(AValue : Boolean);
 procedure TCustomSQLQuery.SetUsePrimaryKeyAsKey(AValue : Boolean);
 
 
 begin
 begin
@@ -2610,7 +2598,7 @@ begin
     SQLConnection.UpdateIndexDefs(ServerIndexDefs,FTableName);
     SQLConnection.UpdateIndexDefs(ServerIndexDefs,FTableName);
 end;
 end;
 
 
-Function TCustomSQLQuery.NeedLastinsertID : TField;
+Function TCustomSQLQuery.NeedLastInsertID : TField;
 
 
 Var
 Var
   I : Integer;
   I : Integer;
@@ -2630,38 +2618,40 @@ begin
     end
     end
 end;
 end;
 
 
-Function TCustomSQLQuery.UpdateLastInsertIDField(F : TField) : Boolean;
+Function TCustomSQLQuery.RefreshLastInsertID(Field : TField) : Boolean;
 
 
 begin
 begin
-  Result:=SQLConnection.GetLastInsertIDForField(Self,F);
+  Result:=SQLConnection.RefreshLastInsertID(Self, Field);
 end;
 end;
 
 
 procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind: TUpdateKind);
 procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind: TUpdateKind);
 
 
 Var
 Var
-  DoRefresh,RecordRefreshed : Boolean;
+  DoRefresh, RecordRefreshed : Boolean;
   LastIDField : TField;
   LastIDField : TField;
-  S : TDatasetState;
+  S : TDataSetState;
 
 
 begin
 begin
   // Moved to connection: the SQLConnection always has more information about types etc.
   // Moved to connection: the SQLConnection always has more information about types etc.
   // than SQLQuery itself.
   // than SQLQuery itself.
-  SQLConnection.ApplyRecupdate(Self,UpdateKind);
-  if (UpdateKind=ukInsert) then
-    LastIDField:=NeedLastInsertID;
+  SQLConnection.ApplyRecUpdate(Self,UpdateKind);
+
+  if UpdateKind=ukInsert then
+    LastIDField:=NeedLastInsertID
+  else
+    LastIDField:=nil;
   DoRefresh:=(UpdateKind in [ukModify,ukInsert]) and NeedRefreshRecord(UpdateKind);
   DoRefresh:=(UpdateKind in [ukModify,ukInsert]) and NeedRefreshRecord(UpdateKind);
-  if ((LastIDField<>Nil) or DoRefresh) then
+  if assigned(LastIDField) or DoRefresh then
     begin
     begin
-    S:=State;
+    S:=SetTempState(dsNewValue);
     try
     try
       RecordRefreshed:=False;
       RecordRefreshed:=False;
-      SetState(dsNewValue);
-      if LastIDField<>Nil then
-        RecordRefreshed:=UpdateLastInsertIDField(LastIDField);
+      if assigned(LastIDField) then
+        RecordRefreshed:=RefreshLastInsertID(LastIDField);
       if DoRefresh then
       if DoRefresh then
         RecordRefreshed:=RefreshRecord(UpdateKind) or RecordRefreshed;
         RecordRefreshed:=RefreshRecord(UpdateKind) or RecordRefreshed;
     finally
     finally
-      SetState(S);
+      RestoreState(S);
     end;
     end;
     if RecordRefreshed then
     if RecordRefreshed then
       // Active buffer is updated, move to record.
       // Active buffer is updated, move to record.
@@ -2669,6 +2659,14 @@ begin
     end;
     end;
 end;
 end;
 
 
+procedure TCustomSQLQuery.SetPacketRecords(aValue: integer);
+begin
+  if (AValue=PacketRecords) then exit;
+  if (AValue<>-1) and (sqoKeepOpenOnCommit in Options) then
+    DatabaseError(SErrDisconnectedPacketRecords);
+  Inherited SetPacketRecords(aValue);
+end;
+
 
 
 function TCustomSQLQuery.GetCanModify: Boolean;
 function TCustomSQLQuery.GetCanModify: Boolean;
 
 
@@ -2752,12 +2750,6 @@ begin
     PacketRecords:=-1;
     PacketRecords:=-1;
 end;
 end;
 
 
-procedure TCustomSQLQuery.SetRefreshSQL(AValue: TStringlist);
-begin
-  if FRefreshSQL=AValue then Exit;
-  FRefreshSQL.Assign(AValue);
-end;
-
 procedure TCustomSQLQuery.SetSQLConnection(AValue: TSQLConnection);
 procedure TCustomSQLQuery.SetSQLConnection(AValue: TSQLConnection);
 begin
 begin
   Database:=AValue;
   Database:=AValue;
@@ -2768,16 +2760,27 @@ begin
   Transaction:=AValue;
   Transaction:=AValue;
 end;
 end;
 
 
-procedure TCustomSQLQuery.SetDeleteSQL(const AValue: TStringlist);
+procedure TCustomSQLQuery.SetInsertSQL(const AValue: TStringList);
+begin
+  FInsertSQL.Assign(AValue);
+end;
+
+procedure TCustomSQLQuery.SetUpdateSQL(const AValue: TStringList);
+begin
+  FUpdateSQL.Assign(AValue);
+end;
+
+procedure TCustomSQLQuery.SetDeleteSQL(const AValue: TStringList);
 begin
 begin
   FDeleteSQL.Assign(AValue);
   FDeleteSQL.Assign(AValue);
 end;
 end;
 
 
-procedure TCustomSQLQuery.SetInsertSQL(const AValue: TStringlist);
+procedure TCustomSQLQuery.SetRefreshSQL(const AValue: TStringList);
 begin
 begin
-  FInsertSQL.Assign(AValue);
+  FRefreshSQL.Assign(AValue);
 end;
 end;
 
 
+
 procedure TCustomSQLQuery.SetParams(AValue: TParams);
 procedure TCustomSQLQuery.SetParams(AValue: TParams);
 begin
 begin
   FStatement.Params.Assign(AValue);
   FStatement.Params.Assign(AValue);