Browse Source

* Large patch from Joost Van der Sluis.
* Float fix in interbase
+ Commit and commitretaining for pqconnection
+ Preparestatement and prepareselect joined.
+ Freestatement and FreeSelect joined
+ TSQLQuery.GetSQLStatementType implemented
+ TBufDataset.AllocBuffer now no longer does a realloc
+ Fetch=True means succesfully got data. False means end of data.
+ Default implementation of GetFieldData implemented/

michael 21 years ago
parent
commit
8030ebf357

+ 27 - 57
fcl/db/sqldb/interbase/ibconnection.pp

@@ -58,17 +58,14 @@ type
     Function AllocateTransactionHandle : TSQLHandle; override;
 
     procedure FreeStatement(cursor : TSQLHandle); override;
-    procedure FreeSelect(cursor : TSQLHandle); override;
     procedure PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string); override;
-    procedure PrepareSelect(cursor : TSQLHandle); override;
     procedure FreeFldBuffers(cursor : TSQLHandle); override;
     procedure Execute(cursor: TSQLHandle;atransaction:tSQLtransaction); override;
     procedure AddFieldDefs(cursor: TSQLHandle; FieldDefs : TfieldDefs); override;
     function GetFieldSizes(cursor : TSQLHandle) : integer; override;
     function Fetch(cursor : TSQLHandle) : boolean; override;
     procedure LoadFieldsFromBuffer(cursor : TSQLHandle;buffer: pchar); override;
-    function GetFieldData(cursor : TSQLHandle; Field: TField; Buffer: Pointer;currbuff:pchar): Boolean; override;
-    function GetStatementType(cursor : TSQLHandle) : tStatementType; override;
+    function GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean; override;
     function GetTransactionHandle(trans : TSQLHandle): pointer; override;
     function Commit(trans : TSQLHandle) : boolean; override;
     function RollBack(trans : TSQLHandle) : boolean; override;
@@ -376,11 +373,6 @@ begin
   result := TIBTrans.create;
 end;
 
-procedure TIBConnection.FreeSelect(cursor : TSQLHandle);
-
-begin
-end;
-
 procedure TIBConnection.FreeStatement(cursor : TSQLHandle);
 begin
   with cursor as TIBcursor do
@@ -392,9 +384,10 @@ begin
 end;
 
 procedure TIBConnection.PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string);
-var
-  dh    : pointer;
-  tr : pointer;
+
+var dh    : pointer;
+    tr    : pointer;
+    x     : shortint;
 
 begin
   with cursor as TIBcursor do
@@ -405,30 +398,24 @@ begin
     tr := aTransaction.Handle;
     if isc_dsql_prepare(@Status, @tr, @Statement, 0, @Buf[1], Dialect, nil) <> 0 then
       CheckError('PrepareStatement', Status);
-    end;
-end;
-
-procedure TIBConnection.PrepareSelect(cursor : TSQLHandle);
-var
-  x  : shortint;
-begin
-  with cursor as TIBCursor do
-    begin
-    if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then
-      CheckError('PrepareSelect', Status);
-    if SQLDA^.SQLD > SQLDA^.SQLN then
+    if StatementType = stselect then
       begin
-      AllocSQLDA((cursor as TIBCursor),SQLDA^.SQLD);
       if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then
         CheckError('PrepareSelect', Status);
+      if SQLDA^.SQLD > SQLDA^.SQLN then
+        begin
+        AllocSQLDA((cursor as TIBCursor),SQLDA^.SQLD);
+        if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then
+          CheckError('PrepareSelect', Status);
+        end;
+      {$R-}
+      for x := 0 to SQLDA^.SQLD - 1 do
+        begin
+        SQLDA^.SQLVar[x].SQLData := AllocMem(SQLDA^.SQLVar[x].SQLLen);
+        SQLDA^.SQLVar[x].SQLInd  := @FFieldFlag[x];
+        end;
+      {$R+}
       end;
-    {$R-}
-    for x := 0 to SQLDA^.SQLD - 1 do
-      begin
-      SQLDA^.SQLVar[x].SQLData := AllocMem(SQLDA^.SQLVar[x].SQLLen);
-      SQLDA^.SQLVar[x].SQLInd  := @FFieldFlag[x];
-      end;
-    {$R+}
     end;
 end;
 
@@ -509,7 +496,7 @@ begin
     if (retcode <> 0) and (retcode <> 100) then
       CheckError('Fetch', Status);
     end;
-  Result := (retcode = 100);
+  Result := (retcode <> 100);
 end;
 
 procedure TIBConnection.LoadFieldsFromBuffer(cursor : TSQLHandle;buffer : pchar);
@@ -535,7 +522,7 @@ begin
   {$R+}
 end;
 
-function TIBConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; Buffer: Pointer;currbuff : pchar): Boolean;
+function TIBConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean;
 var
   x : longint;
   b : longint;
@@ -610,36 +597,19 @@ begin
     4 :
       begin
         Move(CurrBuff^, Sin, 4);
-        Ext := Sin;
+        Dbl := Sin;
       end;
     8 :
       begin
         Move(CurrBuff^, Dbl, 8);
-        Ext := Dbl;
       end;
-    10: Move(CurrBuff^, Ext, 10);
-  end;
-  Move(Ext, Buffer^, 10);
-end;
-
-function TIBConnection.GetStatementType(cursor : TSQLhandle) : TStatementType;
-var
-  x : integer;
-  ResBuf : array [0..7] of char;
-begin
-  Result := stNone;
-  with cursor as TIBCursor do
-    begin
-    x := isc_info_sql_stmt_type;
-    if isc_dsql_sql_info(@Status, @Statement, SizeOf(X),
-      @x, SizeOf(ResBuf), @ResBuf) <> 0 then
-      CheckError('GetStatementType', Status);
-    if Ord(ResBuf[0]) = isc_info_sql_stmt_type then
+    10:
       begin
-      x := isc_vax_integer(@ResBuf[1], 2);
-      Result := TStatementType(isc_vax_integer(@ResBuf[3], x));
+        Move(CurrBuff^, Ext, 10);
+        Dbl := Ext;
       end;
-    end;
+  end;
+  Move(Dbl, Buffer^, 8);
 end;
 
 end.

+ 14 - 47
fcl/db/sqldb/mysql/mysql4conn.pas

@@ -26,7 +26,6 @@ Type
   private
     FDialect: integer;
     FHostInfo: String;
-    FHostName: string;
     FServerInfo: String;
     FMySQL : PMySQL;
     function GetClientInfo: string;
@@ -46,17 +45,14 @@ Type
     Function AllocateTransactionHandle : TSQLHandle; override;
 
     procedure FreeStatement(cursor : TSQLHandle); override;
-    procedure FreeSelect(cursor : TSQLHandle); override;
     procedure PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string); override;
-    procedure PrepareSelect(cursor : TSQLHandle); override;
     procedure FreeFldBuffers(cursor : TSQLHandle); override;
     procedure Execute(cursor: TSQLHandle;atransaction:tSQLtransaction); override;
     procedure AddFieldDefs(cursor: TSQLHandle; FieldDefs : TfieldDefs); override;
     function GetFieldSizes(cursor : TSQLHandle) : integer; override;
     function Fetch(cursor : TSQLHandle) : boolean; override;
     procedure LoadFieldsFromBuffer(cursor : TSQLHandle;buffer: pchar); override;
-    function GetFieldData(cursor : TSQLHandle; Field: TField; Buffer: Pointer;currbuff:pchar): Boolean; override;
-    function GetStatementType(cursor : TSQLHandle) : tStatementType; override;
+    function GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean; override;
     function GetTransactionHandle(trans : TSQLHandle): pointer; override;
     function Commit(trans : TSQLHandle) : boolean; override;
     function RollBack(trans : TSQLHandle) : boolean; override;
@@ -71,7 +67,7 @@ Type
   published
     property Dialect  : integer read FDialect write FDialect;
     property DatabaseName;
-    property HostName : string Read FHostName Write FHostName;
+    property HostName;
     property KeepConnection;
     property LoginPrompt;
     property Params;
@@ -182,34 +178,23 @@ Var
 
 begin
   C:=Cursor as TMysqlCursor;
+  if c.StatementType=stSelect then
+    c.FNeedData:=False;
   If (C.FRes<>Nil) then
     begin
     C.FRes:=Nil;
     end;
 end;
 
-procedure TMySQLConnection.FreeSelect(cursor: TSQLHandle);
-
-Var
-  C : TMySQLCursor;
-
-begin
-  C:=Cursor as TMysqlCursor;
-  C.FNeedData:=False;
-end;
-
 procedure TMySQLConnection.PrepareStatement(cursor: TSQLHandle;
   ATransaction: TSQLTransaction; buf: string);
 begin
   With Cursor as TMysqlCursor do
+    begin
     FStatement:=Buf;
-end;
-
-procedure TMySQLConnection.PrepareSelect(cursor: TSQLHandle);
-begin
-  // Do nothing.
-  with (Cursor as TMySQLCursor) do
-    FNeedData:=True;
+    if StatementType=stSelect then
+      FNeedData:=True;
+    end
 end;
 
 procedure TMySQLConnection.FreeFldBuffers(cursor: TSQLHandle);
@@ -373,7 +358,7 @@ Var
 begin
   C:=Cursor as TMySQLCursor;
   C.Row:=MySQL_Fetch_row(C.FRes);
-  Result:=(C.Row=Nil);
+  Result:=(C.Row<>Nil);
 end;
 
 procedure TMySQLConnection.LoadFieldsFromBuffer(cursor: TSQLHandle;
@@ -495,10 +480,8 @@ var
   VI: Integer;
   VF: Double;
   VD: TDateTime;
-  l : Integer;
   Src : String;
-  P : Pchar;
-  
+
 begin
   Result := 0;
   If (Source<>Nil) Then
@@ -581,8 +564,7 @@ begin
   end;
 end;
 
-function TMySQLConnection.GetFieldData(cursor: TSQLHandle; Field: TField;
-  Buffer: Pointer; currbuff: pchar): Boolean;
+function TMySQLConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean;
   
 var
   I, FC: Integer;
@@ -614,25 +596,10 @@ begin
     end;
 end;
 
-{
-  TStatementType = (stNone, stSelect, stInsert, stUpdate, stDelete,
-    stDDL, stGetSegment, stPutSegment, stExecProcedure,
-    stStartTrans, stCommit, stRollback, stSelectForUpd);
-}
-
-const
- StatementTokens : Array[TStatementType] of string = ('(none)', 'select',
-                  'insert', 'update', 'delete',
-                  'create', 'get', 'put', 'execute',
-                  'start','commit','rollback', '?'
-                 );
-
 Function GetSQLStatementType(SQL : String) : TStatementType;
 
-
-
 Var
-  I,L : Integer;
+  L : Integer;
   cmt : boolean;
   P,PE,PP : PChar;
   S : string;
@@ -678,7 +645,7 @@ begin
       Exit(t);
 end;
 
-function TMySQLConnection.GetStatementType(cursor: TSQLHandle): tStatementType;
+{function TMySQLConnection.GetStatementType(cursor: TSQLHandle): tStatementType;
 
 Var
   C : TMySQLCursor;
@@ -686,7 +653,7 @@ Var
 begin
   C:=Cursor as TMySQLCursor;
   Result:=GetSQLStatementType(C.FStatement);
-end;
+end;}
 
 function TMySQLConnection.GetTransactionHandle(trans: TSQLHandle): pointer;
 begin

+ 78 - 50
fcl/db/sqldb/postgres/pqconnection.pp

@@ -5,7 +5,7 @@ unit pqconnection;
 interface
 
 uses
-  Classes, SysUtils, postgres3, sqldb, db;
+  Classes, SysUtils, sqldb, db,postgres3;
   
 type
   TPQTrans = Class(TSQLHandle)
@@ -36,19 +36,18 @@ type
     Function AllocateTransactionHandle : TSQLHandle; override;
 
     procedure FreeStatement(cursor : TSQLHandle); override;
-    procedure FreeSelect(cursor : TSQLHandle); override;
     procedure PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string); override;
-    procedure PrepareSelect(cursor : TSQLHandle); override;
     procedure FreeFldBuffers(cursor : TSQLHandle); override;
     procedure Execute(cursor: TSQLHandle;atransaction:tSQLtransaction); override;
     procedure AddFieldDefs(cursor: TSQLHandle; FieldDefs : TfieldDefs); override;
     function GetFieldSizes(cursor : TSQLHandle) : integer; override;
     function Fetch(cursor : TSQLHandle) : boolean; override;
     procedure LoadFieldsFromBuffer(cursor : TSQLHandle;buffer: pchar); override;
-    function GetFieldData(cursor : TSQLHandle; Field: TField; Buffer: Pointer;currbuff:pchar): Boolean; override;
-    function GetStatementType(cursor : TSQLHandle) : tStatementType; override;
+    function GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean; override;
     function GetTransactionHandle(trans : TSQLHandle): pointer; override;
     function RollBack(trans : TSQLHandle) : boolean; override;
+    function Commit(trans : TSQLHandle) : boolean; override;
+    procedure CommitRetaining(trans : TSQLHandle); override;
     function StartTransaction(trans : TSQLHandle) : boolean; override;
     procedure RollBackRetaining(trans : TSQLHandle); override;
   published
@@ -63,6 +62,7 @@ implementation
 
 ResourceString
   SErrRollbackFailed = 'Rollback transaction failed';
+  SErrCommitFailed = 'Commit transaction failed';
   SErrConnectionFailed = 'Connection to database failed';
   SErrTransactionFailed = 'Start of transacion failed';
   SErrClearSelection = 'Clear of selection failed';
@@ -80,21 +80,6 @@ const Oid_Text    = 25;
       Oid_bpchar  = 1042;
       Oid_varchar = 1043;
 
-type
-  TTm = packed record
-    tm_sec : longint;
-    tm_min : longint;
-    tm_hour : longint;
-    tm_mday : longint;
-    tm_mon : longint;
-    tm_year : longint;
-    tm_wday : longint;
-    tm_yday : longint;
-    tm_isdst : longint;
-    __tm_gmtoff : longint;
-    __tm_zone : Pchar;
-  end;
-
 function TPQConnection.GetTransactionHandle(trans : TSQLHandle): pointer;
 begin
   Result := (trans as TPQtrans).TransactionHandle;
@@ -124,6 +109,31 @@ begin
     end;
 end;
 
+function TPQConnection.Commit(trans : TSQLHandle) : boolean;
+var
+  res : PPGresult;
+  tr  : TPQTrans;
+begin
+  result := false;
+
+  tr := trans as TPQTrans;
+
+  res := PQexec(tr.TransactionHandle, 'COMMIT');
+  if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
+    begin
+    PQclear(res);
+    result := false;
+    DatabaseError(SErrCommitFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
+    end
+  else
+    begin
+    PQclear(res);
+    PQFinish(tr.TransactionHandle);
+    result := true;
+    end;
+end;
+
+
 function TPQConnection.StartTransaction(trans : TSQLHandle) : boolean;
 var
   res : PPGresult;
@@ -190,6 +200,36 @@ begin
     end;
 end;
 
+procedure TPQConnection.CommitRetaining(trans : TSQLHandle);
+var
+  res : PPGresult;
+  tr  : TPQTrans;
+  msg : string;
+begin
+  tr := trans as TPQTrans;
+  res := PQexec(tr.TransactionHandle, 'COMMIT');
+  if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
+    begin
+    PQclear(res);
+    DatabaseError(SErrCommitFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.transactionhandle) + ')',self);
+    end
+  else
+    begin
+    PQclear(res);
+    res := PQexec(tr.TransactionHandle, 'BEGIN');
+    if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
+      begin
+      PQclear(res);
+      msg := PQerrorMessage(tr.transactionhandle);
+      PQFinish(tr.TransactionHandle);
+      DatabaseError(sErrTransactionFailed + ' (PostgreSQL: ' + msg + ')',self);
+      end
+    else
+      PQclear(res);
+    end;
+end;
+
+
 procedure TPQConnection.DoInternalConnect;
 
 var msg : string;
@@ -248,31 +288,12 @@ end;
 
 procedure TPQConnection.PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string);
 
-begin
-  (cursor as TPQCursor).statement := buf;
-end;
-
-procedure TPQConnection.PrepareSelect(cursor : TSQLHandle);
-
 begin
   with (cursor as TPQCursor) do
-   statement := 'DECLARE selectst' + name + '  BINARY CURSOR FOR ' + statement;
-end;
-
-procedure TPQConnection.FreeSelect(cursor : TSQLHandle);
-
-var st : string;
-
-begin
-  with cursor as TPQCursor do
     begin
-    st := 'CLOSE selectst' + name;
-    Res := pqexec(tr,pchar(st));
-    if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
-      begin
-      pqclear(res);
-      DatabaseError(SErrClearSelection + ' (PostgreSQL: ' + PQerrorMessage(tr) + ')',self);
-      end
+    (cursor as TPQCursor).statement := buf;
+    if StatementType = stselect then
+      statement := 'DECLARE selectst' + name + '  BINARY CURSOR FOR ' + statement;
     end;
 end;
 
@@ -281,6 +302,15 @@ procedure TPQConnection.FreeStatement(cursor : TSQLHandle);
 begin
   with cursor as TPQCursor do
     begin
+    if StatementType = stselect then
+      begin
+      Res := pqexec(tr,pchar('CLOSE selectst' + name));
+      if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
+        begin
+        pqclear(res);
+        DatabaseError(SErrClearSelection + ' (PostgreSQL: ' + PQerrorMessage(tr) + ')',self);
+        end
+      end;
     pqclear(baseres);
     pqclear(res);
     end;
@@ -292,15 +322,17 @@ begin
 // Do nothing
 end;
 
-
 procedure TPQConnection.Execute(cursor: TSQLHandle;atransaction:tSQLtransaction);
 
+var st : string;
+
 begin
   with cursor as TPQCursor do
     begin
     tr := aTransaction.Handle;
 //    res := pqexecParams(tr,pchar(statement),0,nil,nil,nil,nil,1);
-    res := pqexec(tr,pchar(statement));
+    st := statement;
+    res := pqexec(tr,pchar(st));
     if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
       begin
       pqclear(res);
@@ -381,7 +413,7 @@ begin
       pqclear(Res);
       DatabaseError(SErrfetchFailed + ' (PostgreSQL: ' + PQerrorMessage(tr) + ')',self)
       end;
-    Result := (PQntuples(res)=0);
+    Result := (PQntuples(res)<>0);
     end;
 end;
 
@@ -417,7 +449,7 @@ begin
   {$R+}
 end;
 
-function TPQConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; Buffer: Pointer;currbuff : pchar): Boolean;
+function TPQConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean;
 var
   x    : longint;
   size : integer;
@@ -461,10 +493,6 @@ begin
     end;
 end;
 
-function TPQConnection.GetStatementType(cursor : TSQLhandle) : TStatementType;
-begin
-  result := stselect;
-end;
 
 end.
 

+ 107 - 72
fcl/db/sqldb/sqldb.pp

@@ -29,23 +29,32 @@ type
   TSQLTransaction = class;
   TSQLQuery = class;
 
-  ESQLdbError = class(Exception);
-
   TStatementType = (stNone, stSelect, stInsert, stUpdate, stDelete,
     stDDL, stGetSegment, stPutSegment, stExecProcedure,
     stStartTrans, stCommit, stRollback, stSelectForUpd);
 
   TSQLHandle = Class(TObject)
-//    Procedure FreeHandle ; Virtual; Abstract;
+    protected
+    StatementType       : TStatementType;
   end;
 
-{ TSQLConnection }
 
+const
+ StatementTokens : Array[TStatementType] of string = ('(none)', 'select',
+                  'insert', 'update', 'delete',
+                  'create', 'get', 'put', 'execute',
+                  'start','commit','rollback', '?'
+                 );
+
+
+{ TSQLConnection }
+type
   TSQLConnection = class (TDatabase)
   private
     FPassword            : string;
     FTransaction         : TSQLTransaction;
     FUserName            : string;
+    FHostName            : string;
     FCharSet             : string;
     FRole                : String;
     
@@ -58,22 +67,15 @@ type
     Function AllocateCursorHandle : TSQLHandle; virtual; abstract;
     Function AllocateTransactionHandle : TSQLHandle; virtual; abstract;
 
-{    function GetCursor : pointer; virtual; abstract;
-    procedure FreeCursor(cursor : pointer); virtual; abstract;
-    function GetTrans : pointer; virtual; abstract;
-    procedure FreeTrans(trans : pointer); virtual; abstract;}
     procedure FreeStatement(cursor : TSQLHandle); virtual; abstract;
-    procedure FreeSelect(cursor : TSQLHandle); virtual; abstract;
     procedure PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string); virtual; abstract;
-    procedure PrepareSelect(cursor : TSQLHandle); virtual; abstract;
     procedure FreeFldBuffers(cursor : TSQLHandle); virtual; abstract;
     procedure Execute(cursor: TSQLHandle;atransaction:tSQLtransaction); virtual; abstract;
     procedure AddFieldDefs(cursor: TSQLHandle; FieldDefs : TfieldDefs); virtual; abstract;
     function GetFieldSizes(cursor : TSQLHandle) : integer; virtual; abstract;
     function Fetch(cursor : TSQLHandle) : boolean; virtual; abstract;
     procedure LoadFieldsFromBuffer(cursor : TSQLHandle;buffer : pchar); virtual; abstract;
-    function GetFieldData(cursor : TSQLHandle; Field: TField; Buffer: Pointer;currbuff : pchar): Boolean; virtual; abstract;
-    function GetStatementType(cursor : TSQLHandle) : tStatementType; virtual; abstract;
+    function GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean; virtual;
     function GetTransactionHandle(trans : TSQLHandle): pointer; virtual; abstract;
     function Commit(trans : TSQLHandle) : boolean; virtual; abstract;
     function RollBack(trans : TSQLHandle) : boolean; virtual; abstract;
@@ -88,6 +90,7 @@ type
     property Transaction : TSQLTransaction read FTransaction write SetTransaction;
     property UserName : string read FUserName write FUserName;
     property CharSet : string read FCharSet write FCharSet;
+    property HostName : string Read FHostName Write FHostName;
 
     property Connected;
     Property Role :  String read FRole write FRole;
@@ -109,7 +112,6 @@ type
     FTrans               : TSQLHandle;
     FAction              : TCommitRollbackAction;
     FActive              : boolean;
-//    FDatabase            : TSQLConnection;
 
     procedure SetActive(Value : boolean);
   protected
@@ -127,7 +129,6 @@ type
   published
     property Action : TCommitRollbackAction read FAction write FAction;
     property Active : boolean read FActive write SetActive;
-//    property Database : TSQLConnection read FDatabase write FDatabase;
     property Database;
   end;
 
@@ -138,32 +139,25 @@ type
     FCursor              : TSQLHandle;
     FOpen                : Boolean;
     FTransaction         : TSQLTransaction;
-//    FDatabase            : TSQLConnection;
     FSQL                 : TStrings;
     FIsEOF               : boolean;
-    FStatementType       : TStatementType;
     FLoadingFieldDefs    : boolean;
     FRecordSize          : Integer;
 
     procedure SetTransaction(Value : TSQLTransaction);
     procedure FreeStatement;
-    procedure FreeSelect;
     procedure PrepareStatement;
-    procedure PrepareSelect;
     procedure FreeFldBuffers;
     procedure Fetch;
     function LoadBuffer(Buffer : PChar): TGetResult;
-    procedure GetStatementType;
     procedure SetFieldSizes;
 
-    procedure ExecuteImmediate;
-    procedure ExecuteParams;
     procedure Execute;
 
   protected
     // abstract & virual methods of TDataset
     procedure SetDatabase(Value : TDatabase); override;
-    function AllocRecord: PChar; override;
+    function AllocRecord(ExtraSize : integer): PChar; override;
     procedure FreeRecord(var Buffer: PChar); override;
     function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
     function GetNextRecord(Buffer : pchar) : TGetResult; override;
@@ -178,12 +172,11 @@ type
     procedure InternalPost; override;
     function IsCursorOpen: Boolean; override;
     procedure SetFieldData(Field: TField; Buffer: Pointer); override;
+    Function GetSQLStatementType(SQL : String) : TStatementType; virtual;
   public
     procedure ExecSQL; virtual;
     constructor Create(AOwner : TComponent); override;
     destructor Destroy; override;
-
-
   published
     // redeclared data set properties
     property Active;
@@ -216,9 +209,7 @@ type
     property AutoCalcFields;
     property Database;
 
-
     property Transaction : TSQLTransaction read FTransaction write SetTransaction;
-//    property Database    : TSQLConnection read FDatabase write SetDatabase;
     property SQL         : TStrings read FSQL write FSQL;
   end;
 
@@ -259,11 +250,6 @@ begin
     Close;
 end;
 
-procedure TSQLQuery.GetStatementType;
-begin
-  FStatementType := (Database as tsqlconnection).GetStatementType(Fcursor);
-end;
-
 procedure TSQLConnection.DoInternalDisconnect;
 begin
 end;
@@ -278,6 +264,25 @@ begin
   inherited Destroy;
 end;
 
+function TSQLConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean;
+
+var
+  x : longint;
+
+begin
+  Result := False;
+  for x := 0 to FieldDefs.count-1 do
+    begin
+    if (Field.FieldName = FieldDefs[x].Name) then
+      begin
+      Move(CurrBuff^, Buffer^, Field.Size);
+      Result := True;
+      Break;
+      end
+    else Inc(CurrBuff, FieldDefs[x].Size);
+    end;
+end;
+
 { TSQLTransaction }
 
 procedure TSQLTransaction.SetActive(Value : boolean);
@@ -318,7 +323,6 @@ begin
   Rollback;
 end;
 
-
 procedure TSQLTransaction.RollbackRetaining;
 begin
   if not FActive then Exit;
@@ -379,8 +383,6 @@ begin
     inherited setdatabase(value);
     if (FTransaction = nil) and (Assigned(Db.Transaction)) then
       SetTransaction(Db.Transaction);
-{    if assigned(fcursor) then freemem(FCursor);
-    FCursor := Db.AllocateCursorHandle;}
     end;
 end;
 
@@ -389,11 +391,6 @@ begin
   (Database as tsqlconnection).FreeStatement(FCursor);
 end;
 
-procedure TSQLQuery.FreeSelect;
-begin
-  (Database as tsqlconnection).FreeSelect(FCursor);
-end;
-
 procedure TSQLQuery.PrepareStatement;
 var
   Buf : string;
@@ -422,12 +419,10 @@ begin
     DatabaseError(SErrNoStatement);
     exit;
     end;
-  Db.PrepareStatement(Fcursor,FTransaction,buf);
-end;
 
-procedure TSQLQuery.PrepareSelect;
-begin
-  (Database as tsqlconnection).PrepareSelect(FCursor);
+  FCursor.StatementType := GetSQLStatementType(buf);
+
+  Db.PrepareStatement(Fcursor,FTransaction,buf);
 end;
 
 procedure TSQLQuery.FreeFldBuffers;
@@ -437,10 +432,10 @@ end;
 
 procedure TSQLQuery.Fetch;
 begin
-  if not (FStatementType in [stSelect]) then
+  if not (Fcursor.StatementType in [stSelect]) then
     Exit;
 
-  FIsEof := (Database as tsqlconnection).Fetch(Fcursor);
+  FIsEof := not (Database as tsqlconnection).Fetch(Fcursor);
 end;
 
 function TSQLQuery.LoadBuffer(Buffer : PChar): TGetResult;
@@ -460,27 +455,14 @@ begin
   FRecordSize := (Database as tsqlconnection).GetfieldSizes(Fcursor);
 end;
 
-procedure TSQLQuery.ExecuteImmediate;
-begin
-end;
-
-procedure TSQLQuery.ExecuteParams;
-begin
-  //!! to be implemented
-end;
-
 procedure TSQLQuery.Execute;
 begin
-  if FTransaction = nil then
-    DatabaseError(SErrTransactionnSet);
-  if not FTransaction.Active then
-    FTransaction.StartTransaction;
   (Database as tsqlconnection).execute(Fcursor,FTransaction);
 end;
 
-function TSQLQuery.AllocRecord: PChar;
+function TSQLQuery.AllocRecord(ExtraSize : integer): PChar;
 begin
-  Result := AllocMem(FRecordSize);
+  Result := AllocMem(FRecordSize+ExtraSize);
 end;
 
 procedure TSQLQuery.FreeRecord(var Buffer: PChar);
@@ -491,7 +473,7 @@ end;
 
 function TSQLQuery.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
 begin
-  result := (Database as tsqlconnection).GetFieldData(Fcursor,Field,buffer,activebuffer);
+  result := (Database as tsqlconnection).GetFieldData(Fcursor,Field,FieldDefs,buffer,activebuffer);
 end;
 
 function TSQLQuery.GetNextRecord(Buffer: PChar): TGetResult;
@@ -509,11 +491,7 @@ end;
 
 procedure TSQLQuery.InternalClose;
 begin
-  if FStatementType in [stSelect] then
-    begin
-    FreeFldBuffers;
-    FreeSelect;
-    end;
+  FreeFldBuffers;
   FreeStatement;
   if DefaultFields then
     DestroyFields;
@@ -558,10 +536,8 @@ procedure TSQLQuery.InternalOpen;
 begin
   try
     PrepareStatement;
-    GetStatementType;
-    if FStatementType in [stSelect] then
+    if Fcursor.StatementType in [stSelect] then
       begin
-      PrepareSelect;
       Execute;
       FOpen:=True;
       InternalInitFieldDefs;
@@ -599,7 +575,6 @@ procedure TSQLQuery.ExecSQL;
 begin
   try
     PrepareStatement;
-    GetStatementType;
     Execute;
   finally
     FreeStatement;
@@ -620,6 +595,55 @@ begin
   inherited Destroy;
 end;
 
+Function TSQLQuery.GetSQLStatementType(SQL : String) : TStatementType;
+
+Var
+  L       : Integer;
+  cmt     : boolean;
+  P,PE,PP : PChar;
+  S       : string;
+  T       : TStatementType;
+
+begin
+  Result:=stNone;
+  L:=Length(SQL);
+  If (L=0) then
+    Exit;
+  P:=Pchar(SQL);
+  PP:=P;
+  Cmt:=False;
+  While ((P-PP)<L) do
+    begin
+    if not (P^ in [' ',#13,#10,#9]) then
+      begin
+      if not Cmt then
+        begin
+        // Check for comment.
+        Cmt:=(P^='/') and (((P-PP)<=L) and (P[1]='*'));
+        if not (cmt) then
+          Break;
+        end
+      else
+        begin
+        // Check for end of comment.
+         Cmt:=Not( (P^='*') and (((P-PP)<=L) and (P[1]='/')) );
+        If not cmt then
+          Inc(p);
+        end;
+      end;
+    inc(P);
+    end;
+  PE:=P+1;
+  While ((PE-PP)<L) and (PE^ in ['0'..'9','a'..'z','A'..'Z','_']) do
+   Inc(PE);
+  Setlength(S,PE-P);
+  Move(P^,S[1],(PE-P));
+  S:=Lowercase(s);
+  For t:=stselect to strollback do
+    if (S=StatementTokens[t]) then
+      Exit(t);
+end;
+
 function TSQLQuery.getrecordsize : Word;
 
 begin
@@ -630,7 +654,18 @@ end.
 
 {
   $Log$
-  Revision 1.3  2004-10-02 14:52:25  michael
+  Revision 1.4  2004-10-10 14:24:22  michael
+  * Large patch from Joost Van der Sluis.
+  * Float fix in interbase
+  + Commit and commitretaining for pqconnection
+  + Preparestatement and prepareselect joined.
+  + Freestatement and FreeSelect joined
+  + TSQLQuery.GetSQLStatementType implemented
+  + TBufDataset.AllocBuffer now no longer does a realloc
+  + Fetch=True means succesfully got data. False means end of data.
+  + Default implementation of GetFieldData implemented/
+
+  Revision 1.3  2004/10/02 14:52:25  michael
   + Added mysql connection
 
   Revision 1.2  2004/09/26 16:56:32  michael