Browse Source

Merged revisions 9098-9100,9107-9108,9114,9119-9120 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r9098 | joost | 2007-11-03 12:12:01 +0100 (Sat, 03 Nov 2007) | 1 line

* Implemented RowsAffected and modified the test
........
r9099 | joost | 2007-11-03 12:19:34 +0100 (Sat, 03 Nov 2007) | 1 line

* Fixed data/time/datetime fields
........
r9100 | joost | 2007-11-03 13:05:15 +0100 (Sat, 03 Nov 2007) | 2 lines

* Recognize Timestamp records as TDateTime fields
* Fixed TDateTimes which are before the year 1900
........
r9107 | joost | 2007-11-03 17:08:34 +0100 (Sat, 03 Nov 2007) | 2 lines

* Removed unused SetIndexDefs
* IndexDefs should not be passed as var to UpdateIndexDefs
........
r9119 | joost | 2007-11-03 23:20:45 +0100 (Sat, 03 Nov 2007) | 4 lines

* TSQLQuery.StatementType should not be published
* Quote fieldnames in ApplyUpdates for connections which needs this + test (bug 9661)
* Do not try to update the indexdefinitions if the TableName is unknown
* Try to obtain the TableName even if the dataset is readonly
........
r9120 | joost | 2007-11-03 23:30:18 +0100 (Sat, 03 Nov 2007) | 1 line

* Solved bug #9503
........

git-svn-id: branches/fixes_2_2@9754 -

joost 17 years ago
parent
commit
4e3d937b14

+ 1 - 1
packages/fcl-db/src/fields.inc

@@ -380,7 +380,7 @@ end;
 procedure TField.FocusControl;
 procedure TField.FocusControl;
 
 
 begin
 begin
-  FDataSet.DataEvent(deFocusControl,ptrint(Self));
+  FDataSet.DataEvent(deFocusControl,ptrint(@Self));
 end;
 end;
 
 
 procedure TField.FreeBuffers;
 procedure TField.FreeBuffers;

+ 3 - 3
packages/fcl-db/src/sqldb/interbase/ibconnection.pp

@@ -91,7 +91,7 @@ type
     function StartdbTransaction(trans : TSQLHandle; AParams : string) : boolean; override;
     function StartdbTransaction(trans : TSQLHandle; AParams : string) : boolean; override;
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
-    procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
+    procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
@@ -162,7 +162,7 @@ constructor TIBConnection.Create(AOwner : TComponent);
 
 
 begin
 begin
   inherited;
   inherited;
-  FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat];
+  FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat] + [sqQuoteFieldnames];
   FBLobSegmentSize := 80;
   FBLobSegmentSize := 80;
   FDialect := -1;
   FDialect := -1;
   FDBDialect := -1;
   FDBDialect := -1;
@@ -995,7 +995,7 @@ begin
 end;
 end;
 
 
 
 
-procedure TIBConnection.UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string);
+procedure TIBConnection.UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string);
 
 
 var qry : TSQLQuery;
 var qry : TSQLQuery;
 
 

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

@@ -116,7 +116,7 @@ Type
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
-    procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
+    procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
   Public
   Public
     constructor Create(AOwner : TComponent); override;
     constructor Create(AOwner : TComponent); override;
@@ -825,7 +825,7 @@ begin
   Result := True;
   Result := True;
 end;
 end;
 
 
-procedure TConnectionName.UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string);
+procedure TConnectionName.UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string);
 
 
 var qry : TSQLQuery;
 var qry : TSQLQuery;
 
 
@@ -838,7 +838,7 @@ begin
   qry.database := Self;
   qry.database := Self;
   with qry do
   with qry do
     begin
     begin
-    ReadOnly := True;
+    ParseSQL := False;
     sql.clear;
     sql.clear;
     sql.add('show index from ' +  TableName);
     sql.add('show index from ' +  TableName);
     open;
     open;

+ 2 - 2
packages/fcl-db/src/sqldb/odbc/odbcconn.pas

@@ -102,7 +102,7 @@ type
 {$ENDIF}
 {$ENDIF}
     procedure FreeFldBuffers(cursor:TSQLCursor); override;
     procedure FreeFldBuffers(cursor:TSQLCursor); override;
     // - UpdateIndexDefs
     // - UpdateIndexDefs
-    procedure UpdateIndexDefs(var IndexDefs:TIndexDefs; TableName:string); override;
+    procedure UpdateIndexDefs(IndexDefs:TIndexDefs; TableName:string); override;
     // - Schema info
     // - Schema info
     function GetSchemaInfoSQL(SchemaType:TSchemaType; SchemaObjectName, SchemaObjectPattern:string):string; override;
     function GetSchemaInfoSQL(SchemaType:TSchemaType; SchemaObjectName, SchemaObjectPattern:string):string; override;
 
 
@@ -990,7 +990,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TODBCConnection.UpdateIndexDefs(var IndexDefs: TIndexDefs; TableName: string);
+procedure TODBCConnection.UpdateIndexDefs(IndexDefs: TIndexDefs; TableName: string);
 var
 var
   StmtHandle:SQLHSTMT;
   StmtHandle:SQLHSTMT;
   Res:SQLRETURN;
   Res:SQLRETURN;

+ 2 - 2
packages/fcl-db/src/sqldb/postgres/pqconnection.pp

@@ -62,7 +62,7 @@ type
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure CommitRetaining(trans : TSQLHandle); override;
     function StartdbTransaction(trans : TSQLHandle; AParams : string) : boolean; override;
     function StartdbTransaction(trans : TSQLHandle; AParams : string) : boolean; override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
-    procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
+    procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor;ATransaction : TSQLTransaction); override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor;ATransaction : TSQLTransaction); override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
@@ -764,7 +764,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TPQConnection.UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string);
+procedure TPQConnection.UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string);
 
 
 var qry : TSQLQuery;
 var qry : TSQLQuery;
 
 

+ 31 - 39
packages/fcl-db/src/sqldb/sqldb.pp

@@ -23,7 +23,7 @@ interface
 uses SysUtils, Classes, DB, bufdataset;
 uses SysUtils, Classes, DB, bufdataset;
 
 
 type TSchemaType = (stNoSchema, stTables, stSysTables, stProcedures, stColumns, stProcedureParams, stIndexes, stPackages);
 type TSchemaType = (stNoSchema, stTables, stSysTables, stProcedures, stColumns, stProcedureParams, stIndexes, stPackages);
-     TConnOption = (sqSupportParams,sqEscapeSlash,sqEscapeRepeat);
+     TConnOption = (sqSupportParams,sqEscapeSlash,sqEscapeRepeat,sqQuoteFieldnames);
      TConnOptions= set of TConnOption;
      TConnOptions= set of TConnOption;
 
 
      TRowsCount = LargeInt;
      TRowsCount = LargeInt;
@@ -104,7 +104,7 @@ type
     function StartdbTransaction(trans : TSQLHandle; aParams : string) : boolean; virtual; abstract;
     function StartdbTransaction(trans : TSQLHandle; aParams : string) : boolean; virtual; abstract;
     procedure CommitRetaining(trans : TSQLHandle); virtual; abstract;
     procedure CommitRetaining(trans : TSQLHandle); virtual; abstract;
     procedure RollBackRetaining(trans : TSQLHandle); virtual; abstract;
     procedure RollBackRetaining(trans : TSQLHandle); virtual; abstract;
-    procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); virtual;
+    procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); virtual;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; virtual;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; virtual;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); virtual; abstract;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); virtual; abstract;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; virtual;
     function RowsAffected(cursor: TSQLCursor): TRowsCount; virtual;
@@ -185,7 +185,6 @@ type
     FParams              : TParams;
     FParams              : TParams;
     FusePrimaryKeyAsKey  : Boolean;
     FusePrimaryKeyAsKey  : Boolean;
     FSQLBuf              : String;
     FSQLBuf              : String;
-    FFromPart            : String;
     FWhereStartPos       : integer;
     FWhereStartPos       : integer;
     FWhereStopPos        : integer;
     FWhereStopPos        : integer;
     FParseSQL            : boolean;
     FParseSQL            : boolean;
@@ -200,10 +199,8 @@ type
     FInsertQry           : TCustomSQLQuery;
     FInsertQry           : TCustomSQLQuery;
 
 
     procedure FreeFldBuffers;
     procedure FreeFldBuffers;
-    procedure InitUpdates(ASQL : string);
     function GetIndexDefs : TIndexDefs;
     function GetIndexDefs : TIndexDefs;
     function GetStatementType : TStatementType;
     function GetStatementType : TStatementType;
-    procedure SetIndexDefs(AValue : TIndexDefs);
     procedure SetReadOnly(AValue : Boolean);
     procedure SetReadOnly(AValue : Boolean);
     procedure SetParseSQL(AValue : Boolean);
     procedure SetParseSQL(AValue : Boolean);
     procedure SetUsePrimaryKeyAsKey(AValue : Boolean);
     procedure SetUsePrimaryKeyAsKey(AValue : Boolean);
@@ -338,7 +335,6 @@ type
     property Params;
     property Params;
     property UpdateMode;
     property UpdateMode;
     property UsePrimaryKeyAsKey;
     property UsePrimaryKeyAsKey;
-    property StatementType;
     property ParseSQL;
     property ParseSQL;
     Property DataSource;
     Property DataSource;
     property ServerFilter;
     property ServerFilter;
@@ -405,7 +401,7 @@ type
     function StartdbTransaction(trans : TSQLHandle; aParams : string) : boolean; override;
     function StartdbTransaction(trans : TSQLHandle; aParams : string) : boolean; override;
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure CommitRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
-    procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
+    procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); override;
     Property Proxy : TSQLConnection Read FProxy;
     Property Proxy : TSQLConnection Read FProxy;
@@ -461,7 +457,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TSQLConnection.UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string);
+procedure TSQLConnection.UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string);
 
 
 begin
 begin
 // Empty abstract
 // Empty abstract
@@ -888,10 +884,7 @@ begin
       Db.PrepareStatement(Fcursor,sqltr,FSQLBuf,FParams);
       Db.PrepareStatement(Fcursor,sqltr,FSQLBuf,FParams);
 
 
     if (FCursor.FStatementType = stSelect) then
     if (FCursor.FStatementType = stSelect) then
-      begin
       FCursor.FInitFieldDef := True;
       FCursor.FInitFieldDef := True;
-      if not ReadOnly then InitUpdates(FSQLBuf);
-      end;
     end;
     end;
 end;
 end;
 
 
@@ -988,6 +981,7 @@ Var
   EndOfComment            : Boolean;
   EndOfComment            : Boolean;
   BracketCount            : Integer;
   BracketCount            : Integer;
   ConnOptions             : TConnOptions;
   ConnOptions             : TConnOptions;
+  FFromPart               : String;
 
 
 begin
 begin
   PSQL:=Pchar(ASQL);
   PSQL:=Pchar(ASQL);
@@ -1072,9 +1066,21 @@ begin
                          ParsePart := ppBogus;
                          ParsePart := ppBogus;
                          StrLength := CurrentP-PStatementPart;
                          StrLength := CurrentP-PStatementPart;
                          end;
                          end;
-                       Setlength(FFromPart,StrLength);
-                       Move(PStatementPart^,FFromPart[1],(StrLength));
-                       FFrompart := trim(FFrompart);
+                       if FCursor.FStatementType = stSelect then
+                         begin
+                         Setlength(FFromPart,StrLength);
+                         Move(PStatementPart^,FFromPart[1],(StrLength));
+                         FFrompart := trim(FFrompart);
+                       
+                         if pos(',',FFromPart) > 0 then
+                           FUpdateable := False // select-statements from more then one table are not updateable
+                         else
+                           begin
+                           FUpdateable := True;
+                           FTableName := FFromPart;
+                           end;
+                         end;
+
                        FWhereStartPos := PStatementPart-PSQL+StrLength+1;
                        FWhereStartPos := PStatementPart-PSQL+StrLength+1;
                        PStatementPart := CurrentP;
                        PStatementPart := CurrentP;
                        end;
                        end;
@@ -1104,20 +1110,6 @@ begin
     end
     end
 end;
 end;
 
 
-procedure TCustomSQLQuery.InitUpdates(ASQL : string);
-
-
-begin
-  if pos(',',FFromPart) > 0 then
-    FUpdateable := False // select-statements from more then one table are not updateable
-  else
-    begin
-    FUpdateable := True;
-    FTableName := FFromPart;
-    end;
-
-end;
-
 procedure TCustomSQLQuery.InternalOpen;
 procedure TCustomSQLQuery.InternalOpen;
 
 
   procedure InitialiseModifyQuery(var qry : TCustomSQLQuery; aSQL: TSTringList);
   procedure InitialiseModifyQuery(var qry : TCustomSQLQuery; aSQL: TSTringList);
@@ -1289,19 +1281,21 @@ end;
 Procedure TCustomSQLQuery.UpdateIndexDefs;
 Procedure TCustomSQLQuery.UpdateIndexDefs;
 
 
 begin
 begin
-  if assigned(DataBase) then
+  if assigned(DataBase) and (FTableName<>'') then
     TSQLConnection(DataBase).UpdateIndexDefs(FIndexDefs,FTableName);
     TSQLConnection(DataBase).UpdateIndexDefs(FIndexDefs,FTableName);
 end;
 end;
 
 
 Procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind);
 Procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind);
 
 
+var FieldNamesQuoteChar : char;
+
   procedure UpdateWherePart(var sql_where : string;x : integer);
   procedure UpdateWherePart(var sql_where : string;x : integer);
 
 
   begin
   begin
     if (pfInKey in Fields[x].ProviderFlags) or
     if (pfInKey in Fields[x].ProviderFlags) or
        ((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or
        ((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or
        ((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then
        ((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then
-      sql_where := sql_where + '(' + fields[x].FieldName + '= :OLD_' + fields[x].FieldName + ') and ';
+      sql_where := sql_where + '(' + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + '= :OLD_' + fields[x].FieldName + ') and ';
   end;
   end;
 
 
   function ModifyRecQuery : string;
   function ModifyRecQuery : string;
@@ -1318,7 +1312,7 @@ Procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind);
       UpdateWherePart(sql_where,x);
       UpdateWherePart(sql_where,x);
 
 
       if (pfInUpdate in Fields[x].ProviderFlags) then
       if (pfInUpdate in Fields[x].ProviderFlags) then
-        sql_set := sql_set + fields[x].FieldName + '=:' + fields[x].FieldName + ',';
+        sql_set := sql_set +FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar +'=:' + fields[x].FieldName + ',';
       end;
       end;
 
 
     if length(sql_set) = 0 then DatabaseError(sNoUpdateFields,self);
     if length(sql_set) = 0 then DatabaseError(sNoUpdateFields,self);
@@ -1342,7 +1336,7 @@ Procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind);
       begin
       begin
       if (not fields[x].IsNull) and (pfInUpdate in Fields[x].ProviderFlags) then
       if (not fields[x].IsNull) and (pfInUpdate in Fields[x].ProviderFlags) then
         begin
         begin
-        sql_fields := sql_fields + fields[x].FieldName + ',';
+        sql_fields := sql_fields + FieldNamesQuoteChar + fields[x].FieldName + FieldNamesQuoteChar + ',';
         sql_values := sql_values + ':' + fields[x].FieldName + ',';
         sql_values := sql_values + ':' + fields[x].FieldName + ',';
         end;
         end;
       end;
       end;
@@ -1374,6 +1368,10 @@ var qry : TCustomSQLQuery;
     Fld : TField;
     Fld : TField;
     
     
 begin
 begin
+  if sqQuoteFieldnames in TSQLConnection(DataBase).ConnOptions then
+    FieldNamesQuoteChar := '"'
+  else
+    FieldNamesQuoteChar := ' ';
     case UpdateKind of
     case UpdateKind of
       ukModify : begin
       ukModify : begin
                  qry := FUpdateQry;
                  qry := FUpdateQry;
@@ -1421,12 +1419,6 @@ begin
   Result := FIndexDefs;
   Result := FIndexDefs;
 end;
 end;
 
 
-procedure TCustomSQLQuery.SetIndexDefs(AValue : TIndexDefs);
-
-begin
-  FIndexDefs := AValue;
-end;
-
 procedure TCustomSQLQuery.SetUpdateMode(AValue : TUpdateMode);
 procedure TCustomSQLQuery.SetUpdateMode(AValue : TUpdateMode);
 
 
 begin
 begin
@@ -1919,7 +1911,7 @@ begin
   FProxy.RollBackRetaining(trans);
   FProxy.RollBackRetaining(trans);
 end;
 end;
 
 
-procedure TSQLConnector.UpdateIndexDefs(var IndexDefs: TIndexDefs;
+procedure TSQLConnector.UpdateIndexDefs(IndexDefs: TIndexDefs;
   TableName: string);
   TableName: string);
 begin
 begin
   CheckProxy;
   CheckProxy;

+ 17 - 3
packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp

@@ -42,6 +42,8 @@ type
   TArrayStringArray = Array of TStringArray;
   TArrayStringArray = Array of TStringArray;
   PArrayStringArray = ^TArrayStringArray;
   PArrayStringArray = ^TArrayStringArray;
  
  
+  { TSQLite3Connection }
+
   TSQLite3Connection = class(TSQLConnection)
   TSQLite3Connection = class(TSQLConnection)
   private
   private
     fhandle: psqlite3;
     fhandle: psqlite3;
@@ -83,6 +85,7 @@ type
     procedure execsql(const asql: string);
     procedure execsql(const asql: string);
     procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; const TableName : string); // Differs from SQLDB.
     procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; const TableName : string); // Differs from SQLDB.
     function  getprimarykeyfield(const atablename: string; const acursor: tsqlcursor): string; 
     function  getprimarykeyfield(const atablename: string; const acursor: tsqlcursor): string; 
+    function RowsAffected(cursor: TSQLCursor): TRowsCount; override;
   public
   public
     function GetInsertID: int64; 
     function GetInsertID: int64; 
   published
   published
@@ -111,6 +114,8 @@ type
    Procedure UnPrepare;
    Procedure UnPrepare;
    Procedure Execute;
    Procedure Execute;
    Function Fetch : Boolean;
    Function Fetch : Boolean;
+ public
+   RowsAffected : Largeint;
  end;
  end;
 
 
 procedure freebindstring(astring: pointer); cdecl;
 procedure freebindstring(astring: pointer); cdecl;
@@ -222,6 +227,7 @@ begin
 {$endif}  
 {$endif}  
   if (fstate<=sqliteerrormax) then 
   if (fstate<=sqliteerrormax) then 
     checkerror(sqlite3_reset(fstatement));
     checkerror(sqlite3_reset(fstatement));
+  RowsAffected:=sqlite3_changes(fhandle);
   if (fstate=sqlite_row) then 
   if (fstate=sqlite_row) then 
     fstate:= sqliteerrormax; //first row
     fstate:= sqliteerrormax; //first row
 end;  
 end;  
@@ -307,7 +313,7 @@ Type
   end;
   end;
   
   
 Const
 Const
-  FieldMapCount = 18;
+  FieldMapCount = 19;
   FieldMap : Array [1..FieldMapCount] of TFieldMap = (
   FieldMap : Array [1..FieldMapCount] of TFieldMap = (
    (n:'INT'; t: ftInteger),
    (n:'INT'; t: ftInteger),
    (n:'LARGEINT'; t:ftlargeInt),
    (n:'LARGEINT'; t:ftlargeInt),
@@ -317,6 +323,7 @@ Const
    (n:'REAL'; t: ftFloat),
    (n:'REAL'; t: ftFloat),
    (n:'FLOAT'; t: ftFloat),
    (n:'FLOAT'; t: ftFloat),
    (n:'DOUBLE'; t: ftFloat),
    (n:'DOUBLE'; t: ftFloat),
+   (n:'TIMESTAMP'; t: ftDateTime),
    (n:'DATETIME'; t: ftDateTime), // MUST be before date
    (n:'DATETIME'; t: ftDateTime), // MUST be before date
    (n:'DATE'; t: ftDate),
    (n:'DATE'; t: ftDate),
    (n:'TIME'; t: ftTime),
    (n:'TIME'; t: ftTime),
@@ -459,7 +466,7 @@ begin
     else if (Pos(':',S)<>0) then
     else if (Pos(':',S)<>0) then
       TS:=S;
       TS:=S;
     end;
     end;
-  Result:=ParseSQLiteDate(DS)+ParseSQLiteTime(TS);    
+  Result:=ComposeDateTime(ParseSQLiteDate(DS),ParseSQLiteTime(TS));
 end;
 end;
 function TSQLite3Connection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 function TSQLite3Connection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 
 
@@ -494,7 +501,6 @@ begin
     ftDate,
     ftDate,
     ftTime:  if st1 = sttext then 
     ftTime:  if st1 = sttext then 
                begin
                begin
-               result:= false;
                setlength(str1,sqlite3_column_bytes(st,fnum));
                setlength(str1,sqlite3_column_bytes(st,fnum));
                move(sqlite3_column_text(st,fnum)^,str1[1],length(str1));
                move(sqlite3_column_text(st,fnum)^,str1[1],length(str1));
                PDateTime(Buffer)^:=ParseSqliteDateTime(str1)
                PDateTime(Buffer)^:=ParseSqliteDateTime(str1)
@@ -697,6 +703,14 @@ begin
     end;
     end;
 end;
 end;
 
 
+function TSQLite3Connection.RowsAffected(cursor: TSQLCursor): TRowsCount;
+begin
+  if assigned(cursor) then
+    Result := (cursor as TSQLite3Cursor).RowsAffected
+  else
+    Result := -1;
+end;
+
 procedure TSQLite3Connection.UpdateIndexDefs(var IndexDefs: TIndexDefs;
 procedure TSQLite3Connection.UpdateIndexDefs(var IndexDefs: TIndexDefs;
                               const TableName: string);
                               const TableName: string);
 var
 var

+ 47 - 2
packages/fcl-db/tests/testsqlfieldtypes.pas

@@ -27,6 +27,7 @@ type
     procedure RunTest; override;
     procedure RunTest; override;
   published
   published
     procedure TestInsertLargeStrFields; // bug 9600
     procedure TestInsertLargeStrFields; // bug 9600
+    procedure TestNumericNames; // Bug9661
     procedure Test11Params;
     procedure Test11Params;
     procedure TestRowsAffected; // bug 9758
     procedure TestRowsAffected; // bug 9758
     procedure TestStringsReplace;
     procedure TestStringsReplace;
@@ -896,6 +897,47 @@ begin
     end;
     end;
 end;
 end;
 
 
+procedure TTestFieldTypes.TestNumericNames;
+begin
+  with TSQLDBConnector(DBConnector) do
+    begin
+    if sqQuoteFieldnames in Connection.ConnOptions then
+      Connection.ExecuteDirect('create table FPDEV2 (         ' +
+                                '  "2ID" INT NOT NULL            , ' +
+                                '  "3TEST" VARCHAR(10),     ' +
+                                '  PRIMARY KEY ("2ID")           ' +
+                                ')                            ')
+    else
+      Connection.ExecuteDirect('create table FPDEV2 (         ' +
+                                '  2ID INT NOT NULL            , ' +
+                                '  3TEST VARCHAR(10),     ' +
+                                '  PRIMARY KEY (2ID)           ' +
+                                ')                            ');
+// Firebird/Interbase need a commit after a DDL statement. Not necessary for the other connections
+    TSQLDBConnector(DBConnector).Transaction.CommitRetaining;
+    with query do
+      begin
+      SQL.Text:='select * from FPDEV2';
+      Open;
+      Edit;
+      fieldbyname('2ID').AsInteger:=1;
+      fieldbyname('3TEST').AsString:='3test';
+      Post;
+      ApplyUpdates(0);
+      close;
+      open;
+      AssertEquals('3test',FieldByName('3TEST').AsString);
+      Edit;
+      fieldbyname('3TEST').AsString:='test3';
+      Post;
+      ApplyUpdates(0);
+      open;
+      AssertEquals('test3',FieldByName('3TEST').AsString);
+      close;
+      end;
+    end;
+end;
+
 procedure TTestFieldTypes.TestRowsAffected;
 procedure TTestFieldTypes.TestRowsAffected;
 begin
 begin
   with TSQLDBConnector(DBConnector) do
   with TSQLDBConnector(DBConnector) do
@@ -921,8 +963,11 @@ begin
     Query.Open;
     Query.Open;
     AssertTrue(query.RowsAffected<>0); // It should return -1 or the number of selected rows.
     AssertTrue(query.RowsAffected<>0); // It should return -1 or the number of selected rows.
     query.Close;
     query.Close;
-    AssertEquals(-1,query.RowsAffected);
-    Query.SQL.Text := 'delete from FPDEV2';
+    AssertTrue(query.RowsAffected<>0); // It should return -1 or the same as the last time it was called.
+    if (SQLDbType = sqlite3) then  // sqlite doesn't count the rowsaffected if there is no where-clause
+      Query.SQL.Text := 'delete from FPDEV2 where 1'
+    else
+      Query.SQL.Text := 'delete from FPDEV2';
     Query.ExecSQL;
     Query.ExecSQL;
     AssertEquals(2,query.RowsAffected);
     AssertEquals(2,query.RowsAffected);
     Query.SQL.Text := 'delete from FPDEV2';
     Query.SQL.Text := 'delete from FPDEV2';