Răsfoiți Sursa

+ Further fixes from Joost van der sluis for Postgresql

michael 21 ani în urmă
părinte
comite
f348e8bef4
4 a modificat fișierele cu 425 adăugiri și 513 ștergeri
  1. 81 196
      fcl/db/sqldb/Makefile
  2. 7 6
      fcl/db/sqldb/Makefile.fpc
  3. 190 186
      fcl/db/sqldb/interbase/ibconnection.pp
  4. 147 125
      fcl/db/sqldb/sqldb.pp

+ 81 - 196
fcl/db/sqldb/Makefile

@@ -1,8 +1,8 @@
 #
-# Don't edit, this file is generated by FPCMake Version 1.1 [2004/09/04]
+# Don't edit, this file is generated by FPCMake Version 1.1 [2004/09/19]
 #
 default: all
-MAKEFILETARGETS=linux go32v2 win32 os2 freebsd beos netbsd amiga atari sunos qnx netware openbsd wdosx palmos macos darwin emx watcom morphos netwlibc
+MAKEFILETARGETS=linux
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) sunos qnx
 FORCE:
@@ -215,24 +215,10 @@ endif
 PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
 override PACKAGE_NAME=fcl
 ifeq ($(OS_TARGET),linux)
-override TARGET_DIRS+=interbase
-endif
-ifeq ($(OS_TARGET),win32)
-override TARGET_DIRS+=interbase
-endif
-ifeq ($(OS_TARGET),freebsd)
-override TARGET_DIRS+=interbase
-endif
-ifeq ($(OS_TARGET),netbsd)
-override TARGET_DIRS+=interbase
-endif
-ifeq ($(OS_TARGET),openbsd)
-override TARGET_DIRS+=interbase
-endif
-ifeq ($(OS_TARGET),darwin)
-override TARGET_DIRS+=interbase
+override TARGET_DIRS+=interbase postgres
 endif
 override TARGET_UNITS+=sqldb
+override TARGET_RSTS+=sqldb
 override CLEAN_UNITS+=ibas40 ibase60
 override INSTALL_FPCPACKAGE=y
 override COMPILER_OPTIONS+=-S2
@@ -833,7 +819,7 @@ ifndef COPY
 COPY:=$(CPPROG) -fp
 endif
 ifndef COPYTREE
-COPYTREE:=$(CPPROG) -rfp
+COPYTREE:=$(CPPROG) -Rfp
 endif
 ifndef MOVE
 MOVE:=$(MVPROG) -f
@@ -987,198 +973,42 @@ ifeq ($(OS_TARGET),linux)
 ifeq ($(CPU_TARGET),i386)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(CPU_TARGET),m68k)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(CPU_TARGET),powerpc)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(CPU_TARGET),sparc)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(CPU_TARGET),x86_64)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(CPU_TARGET),arm)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),go32v2)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),win32)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),os2)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),freebsd)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),freebsd)
-ifeq ($(CPU_TARGET),m68k)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),freebsd)
-ifeq ($(CPU_TARGET),x86_64)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),beos)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),netbsd)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),netbsd)
-ifeq ($(CPU_TARGET),m68k)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),netbsd)
-ifeq ($(CPU_TARGET),powerpc)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),netbsd)
-ifeq ($(CPU_TARGET),sparc)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),amiga)
-ifeq ($(CPU_TARGET),m68k)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),atari)
-ifeq ($(CPU_TARGET),m68k)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),sunos)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),sunos)
-ifeq ($(CPU_TARGET),sparc)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),qnx)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),netware)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),openbsd)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),openbsd)
-ifeq ($(CPU_TARGET),m68k)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),wdosx)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),palmos)
-ifeq ($(CPU_TARGET),m68k)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),macos)
-ifeq ($(CPU_TARGET),powerpc)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),darwin)
-ifeq ($(CPU_TARGET),powerpc)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),emx)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),watcom)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),morphos)
-ifeq ($(CPU_TARGET),powerpc)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
-endif
-endif
-ifeq ($(OS_TARGET),netwlibc)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
 endif
 endif
 ifdef REQUIRE_PACKAGES_RTL
@@ -1233,6 +1063,32 @@ ifdef UNITDIR_IBASE
 override COMPILER_UNITDIR+=$(UNITDIR_IBASE)
 endif
 endif
+ifdef REQUIRE_PACKAGES_POSTGRES
+PACKAGEDIR_POSTGRES:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /postgres/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_POSTGRES),)
+ifneq ($(wildcard $(PACKAGEDIR_POSTGRES)/$(OS_TARGET)),)
+UNITDIR_POSTGRES=$(PACKAGEDIR_POSTGRES)/$(OS_TARGET)
+else
+UNITDIR_POSTGRES=$(PACKAGEDIR_POSTGRES)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_POSTGRES)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_POSTGRES) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_POSTGRES)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_POSTGRES=
+UNITDIR_POSTGRES:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /postgres/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_POSTGRES),)
+UNITDIR_POSTGRES:=$(firstword $(UNITDIR_POSTGRES))
+else
+UNITDIR_POSTGRES=
+endif
+endif
+ifdef UNITDIR_POSTGRES
+override COMPILER_UNITDIR+=$(UNITDIR_POSTGRES)
+endif
+endif
 ifndef NOCPUDEF
 override FPCOPTDEF=$(CPU_TARGET)
 endif
@@ -1641,21 +1497,7 @@ fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
 fpc_makefiles: fpc_makefile fpc_makefile_dirs
 ifeq ($(OS_TARGET),linux)
 TARGET_DIRS_INTERBASE=1
-endif
-ifeq ($(OS_TARGET),win32)
-TARGET_DIRS_INTERBASE=1
-endif
-ifeq ($(OS_TARGET),freebsd)
-TARGET_DIRS_INTERBASE=1
-endif
-ifeq ($(OS_TARGET),netbsd)
-TARGET_DIRS_INTERBASE=1
-endif
-ifeq ($(OS_TARGET),openbsd)
-TARGET_DIRS_INTERBASE=1
-endif
-ifeq ($(OS_TARGET),darwin)
-TARGET_DIRS_INTERBASE=1
+TARGET_DIRS_POSTGRES=1
 endif
 ifdef TARGET_DIRS_INTERBASE
 interbase_all:
@@ -1700,6 +1542,49 @@ interbase:
 	$(MAKE) -C interbase all
 .PHONY: interbase_all interbase_debug interbase_smart interbase_release interbase_examples interbase_shared interbase_install interbase_sourceinstall interbase_exampleinstall interbase_distinstall interbase_zipinstall interbase_zipsourceinstall interbase_zipexampleinstall interbase_zipdistinstall interbase_clean interbase_distclean interbase_cleanall interbase_info interbase_makefiles interbase
 endif
+ifdef TARGET_DIRS_POSTGRES
+postgres_all:
+	$(MAKE) -C postgres all
+postgres_debug:
+	$(MAKE) -C postgres debug
+postgres_smart:
+	$(MAKE) -C postgres smart
+postgres_release:
+	$(MAKE) -C postgres release
+postgres_examples:
+	$(MAKE) -C postgres examples
+postgres_shared:
+	$(MAKE) -C postgres shared
+postgres_install:
+	$(MAKE) -C postgres install
+postgres_sourceinstall:
+	$(MAKE) -C postgres sourceinstall
+postgres_exampleinstall:
+	$(MAKE) -C postgres exampleinstall
+postgres_distinstall:
+	$(MAKE) -C postgres distinstall
+postgres_zipinstall:
+	$(MAKE) -C postgres zipinstall
+postgres_zipsourceinstall:
+	$(MAKE) -C postgres zipsourceinstall
+postgres_zipexampleinstall:
+	$(MAKE) -C postgres zipexampleinstall
+postgres_zipdistinstall:
+	$(MAKE) -C postgres zipdistinstall
+postgres_clean:
+	$(MAKE) -C postgres clean
+postgres_distclean:
+	$(MAKE) -C postgres distclean
+postgres_cleanall:
+	$(MAKE) -C postgres cleanall
+postgres_info:
+	$(MAKE) -C postgres info
+postgres_makefiles:
+	$(MAKE) -C postgres makefiles
+postgres:
+	$(MAKE) -C postgres all
+.PHONY: postgres_all postgres_debug postgres_smart postgres_release postgres_examples postgres_shared postgres_install postgres_sourceinstall postgres_exampleinstall postgres_distinstall postgres_zipinstall postgres_zipsourceinstall postgres_zipexampleinstall postgres_zipdistinstall postgres_clean postgres_distclean postgres_cleanall postgres_info postgres_makefiles postgres
+endif
 all: fpc_all $(addsuffix _all,$(TARGET_DIRS))
 debug: fpc_debug
 smart: fpc_smart

+ 7 - 6
fcl/db/sqldb/Makefile.fpc

@@ -6,13 +6,14 @@
 main=fcl
 
 [target]
-dirs_linux=interbase
-dirs_freebsd=interbase
-dirs_darwin=interbase
-dirs_netbsd=interbase
-dirs_openbsd=interbase
-dirs_win32=interbase
+dirs_linux=interbase postgres
+dirs_freebsd=interbase postgres
+dirs_darwin=interbase postgres
+dirs_netbsd=interbase postgres
+dirs_openbsd=interbase postgres
+dirs_win32=interbase postgres
 units=sqldb
+rsts=sqldb
 
 [clean]
 units=ibas40 ibase60

+ 190 - 186
fcl/db/sqldb/interbase/ibconnection.pp

@@ -8,13 +8,6 @@ uses
   Classes, SysUtils, IBase60, sqldb, db;
   
 type
-  TIBCursor = record
-                Status    : array [0..19] of ISC_STATUS;
-                Statement : pointer;
-                SQLDA     : PXSQLDA;
-              end;
-  PIBCursor = ^TIBCursor;
-
   TAccessMode = (amReadWrite, amReadOnly);
   TIsolationLevel = (ilConcurrent, ilConsistent, ilReadCommittedRecV,
     ilReadCommitted);
@@ -22,16 +15,23 @@ type
   TTableReservation = (trNone, trSharedLockRead, trSharedLockWrite,
     trProtectedLockRead, trProtectedLockWrite);
 
-  TIBTrans  = record
-                TransactionHandle   : pointer;
-                TPB                 : string;                // Transaction parameter buffer
-                Status              : array [0..19] of ISC_STATUS;
-                AccessMode          : TAccessMode;
-                IsolationLevel      : TIsolationLevel;
-                LockResolution      : TLockResolution;
-                TableReservation    : TTableReservation;
-              end;
-  PIBTrans = ^TIBTrans;
+  TIBCursor = Class(TSQLHandle)
+    protected
+    Status    : array [0..19] of ISC_STATUS;
+    Statement : pointer;
+    SQLDA     : PXSQLDA;
+  end;
+
+  TIBTrans = Class(TSQLHandle)
+    protected
+    TransactionHandle   : pointer;
+    TPB                 : string;                // Transaction parameter buffer
+    Status              : array [0..19] of ISC_STATUS;
+    AccessMode          : TAccessMode;
+    IsolationLevel      : TIsolationLevel;
+    LockResolution      : TLockResolution;
+    TableReservation    : TTableReservation;
+  end;
 
   TIBConnection = class (TSQLConnection)
   private
@@ -41,42 +41,40 @@ type
     FFieldFlag           : array [0..1023] of shortint;
     FDialect             : integer;
     procedure SetDBDialect;
-    procedure AllocSQLDA(Cursor : pointer;Count : integer);
+    procedure AllocSQLDA(Cursor : TIBCursor;Count : integer);
     procedure TranslateFldType(SQLType, SQLLen : integer; var LensSet : boolean;
       var TrType : TFieldType; var TrLen : word);
-    procedure SetTPB(trans : pointer);
+    procedure SetTPB(trans : TIBtrans);
     // conversion methods
     procedure GetDateTime(CurrBuff, Buffer : pointer; AType : integer);
     procedure GetFloat(CurrBuff, Buffer : pointer; Field : TField);
+    procedure CheckError(ProcName : string; Status : array of ISC_STATUS);
   protected
     procedure DoInternalConnect; override;
     procedure DoInternalDisconnect; override;
     function GetHandle : pointer; override;
 
-  public
-    function GetCursor : pointer; override;
-    procedure FreeCursor(cursor : pointer); override;
-    function GetTrans : pointer; override;
-    procedure FreeTrans(trans : pointer); override;
-    procedure AllocStatement(cursor : Pointer); override;
-    procedure FreeStatement(cursor : pointer); override;
-    procedure PrepareStatement(cursor: pointer;ATransaction : TSQLTransaction;buf : string); override;
-    procedure DescribeStatement(cursor : pointer); override;
-    procedure AllocFldBuffers(cursor : pointer); override;
-    procedure FreeFldBuffers(cursor : pointer); override;
-    procedure Execute(cursor: pointer;atransaction:tSQLtransaction); override;
-    procedure AddFieldDefs(cursor: pointer; FieldDefs : TfieldDefs); override;
-    function GetFieldSizes(cursor : pointer) : integer; override;
-    function Fetch(cursor : pointer) : boolean; override;
-    procedure LoadFieldsFromBuffer(cursor : pointer;buffer: pchar); override;
-    function GetFieldData(cursor : pointer; Field: TField; Buffer: Pointer;currbuff:pchar): Boolean; override;
-    function GetStatementType(cursor : pointer) : tStatementType; override;
-    function GetTransactionHandle(trans : pointer): pointer; override;
-    function Commit(trans : pointer) : boolean; override;
-    function RollBack(trans : pointer) : boolean; override;
-    function StartTransaction(trans : pointer) : boolean; override;
-    procedure CommitRetaining(trans : pointer); override;
-    procedure RollBackRetaining(trans : pointer); override;
+    Function AllocateCursorHandle : TSQLHandle; override;
+    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 GetTransactionHandle(trans : TSQLHandle): pointer; override;
+    function Commit(trans : TSQLHandle) : boolean; override;
+    function RollBack(trans : TSQLHandle) : boolean; override;
+    function StartTransaction(trans : TSQLHandle) : boolean; override;
+    procedure CommitRetaining(trans : TSQLHandle); override;
+    procedure RollBackRetaining(trans : TSQLHandle); override;
 
   published
     property Dialect  : integer read FDialect write FDialect;
@@ -89,6 +87,9 @@ type
 
 implementation
 
+resourcestring
+  SErrNoDatabaseName = 'Database connect string (DatabaseName) not filled in!';
+
 type
   TTm = packed record
     tm_sec : longint;
@@ -104,7 +105,7 @@ type
     __tm_zone : Pchar;
   end;
 
-procedure CheckError(ProcName : string; Status : array of ISC_STATUS);
+procedure TIBConnection.CheckError(ProcName : string; Status : array of ISC_STATUS);
 var
   buf : array [0..1024] of char;
   p   : pointer;
@@ -115,22 +116,22 @@ begin
     p := @Status;
     while isc_interprete(Buf, @p) > 0 do
       Msg := Msg + #10' -' + StrPas(Buf);
-    raise ESQLdbError.Create(ProcName + ': ' + Msg);
+    DatabaseError(ProcName + ': ' + Msg,self);
   end;
 end;
 
-procedure TIBConnection.SetTPB(trans : pointer);
+procedure TIBConnection.SetTPB(trans : TIBtrans);
 begin
-  with PIBTrans(trans)^ do
+  with trans do
     begin
     TPB := chr(isc_tpb_version3);
 
-    case PIBTrans(trans)^.AccessMode of
+    case AccessMode of
       amReadWrite : TPB := TPB + chr(isc_tpb_write);
       amReadOnly  : TPB := TPB + chr(isc_tpb_read);
     end;
 
-    case PIBTrans(trans)^.IsolationLevel of
+    case IsolationLevel of
       ilConsistent        : TPB := TPB + chr(isc_tpb_consistency);
       ilConcurrent        : TPB := TPB + chr(isc_tpb_concurrency);
       ilReadCommittedRecV : TPB := TPB + chr(isc_tpb_read_committed) +
@@ -139,12 +140,12 @@ begin
         chr(isc_tpb_no_rec_version);
     end;
 
-    case PIBTrans(trans)^.LockResolution of
+    case LockResolution of
       lrWait   : TPB := TPB + chr(isc_tpb_wait);
       lrNoWait : TPB := TPB + chr(isc_tpb_nowait);
     end;
 
-    case PIBTrans(trans)^.TableReservation of
+    case TableReservation of
       trSharedLockRead     : TPB := TPB + chr(isc_tpb_shared) +
         chr(isc_tpb_lock_read);
       trSharedLockWrite    : TPB := TPB + chr(isc_tpb_shared) +
@@ -157,68 +158,62 @@ begin
     end;
 end;
 
-function TIBConnection.GetTransactionHandle(trans : pointer): pointer;
+function TIBConnection.GetTransactionHandle(trans : TSQLHandle): pointer;
 begin
-  Result := PIBTrans(trans)^.TransactionHandle;
+  Result := (trans as TIBtrans).TransactionHandle;
 end;
 
-function TIBConnection.Commit(trans : pointer) : boolean;
+function TIBConnection.Commit(trans : TSQLHandle) : boolean;
 begin
   result := false;
-  if isc_commit_transaction(@PIBTrans(trans)^.Status, @PIBTrans(trans)^.TransactionHandle) <> 0 then
-    CheckError('TSQLTransaction.Commit', PIBTrans(trans)^.Status)
-  else result := true;
+  with (trans as TIBTrans) do
+    if isc_commit_transaction(@Status, @TransactionHandle) <> 0 then
+      CheckError('Commit', Status)
+    else result := true;
 end;
 
-function TIBConnection.RollBack(trans : pointer) : boolean;
+function TIBConnection.RollBack(trans : TSQLHandle) : boolean;
 begin
   result := false;
-  if isc_rollback_transaction(@PIBTrans(trans)^.Status, @PIBTrans(trans)^.TransactionHandle) <> 0 then
-    CheckError('TIBConnection.Rollback', PIBTrans(trans)^.Status)
+  if isc_rollback_transaction(@TIBTrans(trans).Status, @TIBTrans(trans).TransactionHandle) <> 0 then
+    CheckError('Rollback', TIBTrans(trans).Status)
   else result := true;
 end;
 
-function TIBConnection.StartTransaction(trans : pointer) : boolean;
+function TIBConnection.StartTransaction(trans : TSQLHandle) : boolean;
 var
   DBHandle : pointer;
+  tr       : TIBTrans;
 begin
   result := false;
 
   DBHandle := GetHandle;
-  SetTPB(trans);
-  pibtrans(trans)^.TransactionHandle := nil;
-
-  if isc_start_transaction(@pibtrans(trans)^.Status, @pibtrans(trans)^.TransactionHandle, 1,
-     [@DBHandle, Length(pibtrans(trans)^.TPB), @pibtrans(trans)^.TPB[1]]) <> 0 then
-    CheckError('TIBConnection.StartTransaction',pibtrans(trans)^.Status)
-  else Result := True;
-end;
-
-
-procedure TIBConnection.CommitRetaining(trans : pointer);
-begin
-  if isc_commit_retaining(@PIBTrans(trans)^.Status, @PIBTrans(trans)^.TransactionHandle) <> 0 then
-    CheckError('TIBConnection.CommitRetaining', PIBTrans(trans)^.Status);
-end;
+  tr := trans as TIBtrans;
+  SetTPB(tr);
+  with tr do
+    begin
+    TransactionHandle := nil;
 
-procedure TIBConnection.RollBackRetaining(trans : pointer);
-begin
-  if isc_rollback_retaining(@PIBTrans(trans)^.Status, @PIBTrans(trans)^.TransactionHandle) <> 0 then
-    CheckError('TIBConnection.RollBackRetaining', PIBTrans(trans)^.Status);
+    if isc_start_transaction(@Status, @TransactionHandle, 1,
+       [@DBHandle, Length(TPB), @TPB[1]]) <> 0 then
+      CheckError('StartTransaction',Status)
+    else Result := True;
+    end;
 end;
 
-function TIBConnection.GetTrans : pointer;
 
+procedure TIBConnection.CommitRetaining(trans : TSQLHandle);
 begin
-  Result := AllocMem(sizeof(TIBTrans));
-  PIBTrans(result)^.IsolationLevel := ilReadCommitted;
+  with trans as TIBtrans do
+    if isc_commit_retaining(@Status, @TransactionHandle) <> 0 then
+      CheckError('CommitRetaining', Status);
 end;
 
-procedure TIBConnection.FreeTrans(trans : pointer);
-
+procedure TIBConnection.RollBackRetaining(trans : TSQLHandle);
 begin
-  if assigned(PIBTrans(trans)) then
-    freemem(PIBTrans(trans));
+  with trans as TIBtrans do
+    if isc_rollback_retaining(@Status, @TransactionHandle) <> 0 then
+      CheckError('RollBackRetaining', Status);
 end;
 
 
@@ -241,11 +236,11 @@ begin
     DPB := DPB + Chr(isc_dpb_lc_ctype) + Chr(Length(CharSet)) + CharSet;
 
   if (DatabaseName = '') then
-    raise ESQLdbError.Create('TIBConnection.DoInternalConnect: Database connect string (DatabaseName) not filled in!');
+    DatabaseError(SErrNoDatabaseName,self);
   FSQLDatabaseHandle := nil;
   if isc_attach_database(@FStatus, Length(DatabaseName), @DatabaseName[1], @FSQLDatabaseHandle,
          Length(DPB), @DPB[1]) <> 0 then
-    CheckError('TIBConnection.DoInternalConnect', FStatus);
+    CheckError('DoInternalConnect', FStatus);
   SetDBDialect;
 end;
 
@@ -258,7 +253,7 @@ begin
   end;
 
   isc_detach_database(@FStatus[0], @FSQLDatabaseHandle);
-  CheckError('TIBConnection.Close', FStatus);
+  CheckError('Close', FStatus);
 end;
 
 
@@ -272,7 +267,7 @@ begin
   Buffer := Chr(isc_info_db_sql_dialect) + Chr(isc_info_end);
   if isc_database_info(@FStatus, @FSQLDatabaseHandle, Length(Buffer),
     @Buffer[1], SizeOf(ResBuf), @ResBuf) <> 0 then
-      CheckError('TIBDatabse.SetDBDialect', FStatus);
+      CheckError('SetDBDialect', FStatus);
   x := 0;
   while x < 40 do
     case ResBuf[x] of
@@ -289,17 +284,21 @@ begin
 end;
 
 
-procedure TIBConnection.AllocSQLDA(Cursor : pointer;Count : integer);
+procedure TIBConnection.AllocSQLDA(Cursor : TIBcursor;Count : integer);
+
 begin
-  if FSQLDAAllocated > 0 then
-    FreeMem(PIBCursor(cursor)^.SQLDA);
-  GetMem(PIBCursor(cursor)^.SQLDA, XSQLDA_Length(Count));
-  { Zero out the memory block to avoid problems with exceptions within the
-    constructor of this class. }
-  FillChar(PIBCursor(cursor)^.SQLDA^, XSQLDA_Length(Count), 0);
-  FSQLDAAllocated := Count;
-  PIBCursor(cursor)^.SQLDA^.Version := sqlda_version1;
-  PIBCursor(cursor)^.SQLDA^.SQLN := Count;
+  with cursor as TIBCursor do
+    begin
+    if FSQLDAAllocated > 0 then
+      FreeMem(SQLDA);
+    GetMem(SQLDA, XSQLDA_Length(Count));
+    { Zero out the memory block to avoid problems with exceptions within the
+      constructor of this class. }
+    FillChar(SQLDA^, XSQLDA_Length(Count), 0);
+    FSQLDAAllocated := Count;
+    SQLDA^.Version := sqlda_version1;
+    SQLDA^.SQLN := Count;
+    end;
 end;
 
 procedure TIBConnection.TranslateFldType(SQLType, SQLLen : integer; var LensSet : boolean;
@@ -361,105 +360,106 @@ begin
   end;
 end;
 
-function TIBConnection.GetCursor : pointer;
+Function TIBConnection.AllocateCursorHandle : TSQLHandle;
+
+var curs : TIBCursor;
 
 begin
-  Result := AllocMem(sizeof(TIBCursor));
-  AllocSQLDA(result,10);
+  curs := TIBCursor.create;
+  AllocSQLDA(curs,10);
+  result := curs;
 end;
 
-procedure TIBConnection.FreeCursor(cursor : pointer);
+Function TIBConnection.AllocateTransactionHandle : TSQLHandle;
 
 begin
-  if assigned(PIBCursor(cursor)) then
-    freemem(PIBCursor(cursor));
+  result := TIBTrans.create;
 end;
 
-procedure TIBConnection.FreeStatement(cursor : pointer);
-begin
-  if isc_dsql_free_statement(@PIBCursor(cursor)^.Status, @PIBCursor(cursor)^.Statement, DSQL_Drop) <> 0 then
-    CheckError('TIBConnection.FreeStatement', PIBCursor(cursor)^.Status);
-  PIBCursor(cursor)^.Statement := nil;
-end;
+procedure TIBConnection.FreeSelect(cursor : TSQLHandle);
 
-procedure TIBConnection.AllocStatement(cursor : pointer);
-var
-  dh    : pointer;
 begin
-  dh := GetHandle;
-
-  if isc_dsql_allocate_statement(@PIBCursor(cursor)^.Status, @dh, @PIBCursor(cursor)^.Statement) <> 0 then
-    CheckError('TIBConnection.AllocStatement', PIBCursor(cursor)^.Status);
 end;
 
-
-procedure TIBConnection.PrepareStatement(cursor: pointer;ATransaction : TSQLTransaction;buf : string);
-
-var tr : pointer;
-
+procedure TIBConnection.FreeStatement(cursor : TSQLHandle);
 begin
-  tr := aTransaction.Handle;
-
-  if isc_dsql_prepare(@PIBCursor(cursor)^.Status, @tr, @PIBCursor(cursor)^.Statement, 0, @Buf[1], Dialect, nil) <> 0 then
-    CheckError('TIBConnection.PrepareStatement', PIBCursor(cursor)^.Status);
+  with cursor as TIBcursor do
+    begin
+    if isc_dsql_free_statement(@Status, @Statement, DSQL_Drop) <> 0 then
+      CheckError('FreeStatement', Status);
+    Statement := nil;
+    end;
 end;
 
-procedure TIBConnection.DescribeStatement(cursor : pointer);
+procedure TIBConnection.PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string);
+var
+  dh    : pointer;
+  tr : pointer;
 
 begin
-  with PIBCursor(cursor)^ do
+  with cursor as TIBcursor do
     begin
-    if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then
-      CheckError('TSQLQuery.DescribeStatement', Status);
-    if SQLDA^.SQLD > SQLDA^.SQLN then
-      begin
-      AllocSQLDA(PIBCursor(cursor),SQLDA^.SQLD);
-      if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then
-        CheckError('TSQLQuery.DescribeStatement', Status);
-      end;
+    dh := GetHandle;
+    if isc_dsql_allocate_statement(@Status, @dh, @Statement) <> 0 then
+      CheckError('PrepareStatement', Status);
+    tr := aTransaction.Handle;
+    if isc_dsql_prepare(@Status, @tr, @Statement, 0, @Buf[1], Dialect, nil) <> 0 then
+      CheckError('PrepareStatement', Status);
     end;
 end;
 
-procedure TIBConnection.FreeFldBuffers(cursor : pointer);
+procedure TIBConnection.PrepareSelect(cursor : TSQLHandle);
 var
   x  : shortint;
 begin
-  {$R-}
-  for x := 0 to PIBCursor(cursor)^.SQLDA^.SQLD - 1 do
-  begin
-    if PIBCursor(cursor)^.SQLDA^.SQLVar[x].SQLData <> nil then
+  with cursor as TIBCursor do
     begin
-      FreeMem(PIBCursor(cursor)^.SQLDA^.SQLVar[x].SQLData);
-      PIBCursor(cursor)^.SQLDA^.SQLVar[x].SQLData := nil;
+    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;
-  end;
-  {$R+}
 end;
 
-
-procedure TIBConnection.AllocFldBuffers(cursor : pointer);
+procedure TIBConnection.FreeFldBuffers(cursor : TSQLHandle);
 var
   x  : shortint;
 begin
   {$R-}
-  for x := 0 to PIBCursor(cursor)^.SQLDA^.SQLD - 1 do
-  begin
-    PIBCursor(cursor)^.SQLDA^.SQLVar[x].SQLData := AllocMem(PIBCursor(cursor)^.SQLDA^.SQLVar[x].SQLLen);
-    PIBCursor(cursor)^.SQLDA^.SQLVar[x].SQLInd  := @FFieldFlag[x];
-  end;
+  with cursor as TIBCursor do
+    for x := 0 to SQLDA^.SQLD - 1 do
+      begin
+      if SQLDA^.SQLVar[x].SQLData <> nil then
+        begin
+        FreeMem(SQLDA^.SQLVar[x].SQLData);
+        SQLDA^.SQLVar[x].SQLData := nil;
+        end;
+      end;
   {$R+}
 end;
 
-procedure TIBConnection.Execute(cursor: pointer;atransaction:tSQLtransaction);
+procedure TIBConnection.Execute(cursor: TSQLHandle;atransaction:tSQLtransaction);
 var tr : pointer;
 begin
   tr := aTransaction.Handle;
 
-  if isc_dsql_execute(@PIBCursor(cursor)^.Status, @tr, @PIBCursor(cursor)^.Statement, 1, nil) <> 0 then
-    CheckError('TSQLQuery.Execute', PIBCursor(cursor)^.Status);
+  with cursor as TIBCursor do
+    if isc_dsql_execute(@Status, @tr, @Statement, 1, nil) <> 0 then
+      CheckError('Execute', Status);
 end;
 
-procedure TIBConnection.AddFieldDefs(cursor: pointer; FieldDefs : TfieldDefs);
+procedure TIBConnection.AddFieldDefs(cursor: TSQLHandle; FieldDefs : TfieldDefs);
 var
   x         : integer;
   lenset    : boolean;
@@ -468,7 +468,7 @@ var
 
 begin
   {$R-}
-  with PIBCursor(cursor)^ do
+  with cursor as TIBCursor do
     begin
     for x := 0 to SQLDA^.SQLD - 1 do
       begin
@@ -481,13 +481,13 @@ begin
   {$R+}
 end;
 
-function TIBConnection.GetFieldSizes(cursor : pointer) : integer;
+function TIBConnection.GetFieldSizes(cursor : TSQLHandle) : integer;
 var
   x,recsize : integer;
 begin
   recsize := 0;
   {$R-}
-  with PIBCursor(cursor)^ do
+  with cursor as TIBCursor do
     for x := 0 to SQLDA^.SQLD - 1 do
       Inc(recsize, SQLDA^.SQLVar[x].SQLLen);
   {$R+}
@@ -499,24 +499,26 @@ begin
   Result := FSQLDatabaseHandle;
 end;
 
-function TIBConnection.Fetch(cursor : pointer) : boolean;
+function TIBConnection.Fetch(cursor : TSQLHandle) : boolean;
 var
   retcode : integer;
 begin
-  retcode := isc_dsql_fetch(@PIBCursor(cursor)^.Status, @PIBCursor(cursor)^.Statement, 1, PIBCursor(cursor)^.SQLDA);
-  if (retcode <> 0) and (retcode <> 100) then
-    CheckError('TSQLQuery.Fetch', PIBCursor(cursor)^.Status);
-
+  with cursor as TIBCursor do
+    begin
+    retcode := isc_dsql_fetch(@Status, @Statement, 1, SQLDA);
+    if (retcode <> 0) and (retcode <> 100) then
+      CheckError('Fetch', Status);
+    end;
   Result := (retcode = 100);
 end;
 
-procedure TIBConnection.LoadFieldsFromBuffer(cursor : pointer;buffer : pchar);
+procedure TIBConnection.LoadFieldsFromBuffer(cursor : TSQLHandle;buffer : pchar);
 var
   x          : integer;
   VarcharLen : word;
 begin
   {$R-}
-  with PIBCursor(cursor)^ do for x := 0 to SQLDA^.SQLD - 1 do
+  with cursor as TIBCursor do for x := 0 to SQLDA^.SQLD - 1 do
     begin
     with SQLDA^.SQLVar[x] do
       begin
@@ -533,19 +535,18 @@ begin
   {$R+}
 end;
 
-function TIBConnection.GetFieldData(Cursor : pointer;Field: TField; Buffer: Pointer;currbuff : pchar): Boolean;
+function TIBConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; Buffer: Pointer;currbuff : pchar): Boolean;
 var
   x : longint;
   b : longint;
 begin
   Result := False;
 
-  with PIBCursor(cursor)^ do
-    for x := 0 to SQLDA^.SQLD - 1 do
-  begin
+  with cursor as TIBCursor do for x := 0 to SQLDA^.SQLD - 1 do
+    begin
     {$R-}
     if (Field.FieldName = SQLDA^.SQLVar[x].SQLName) then
-    begin
+      begin
       case Field.DataType of
         ftInteger :
           begin
@@ -567,10 +568,10 @@ begin
       Result := True;
 
       Break;
-    end
+      end
     else Inc(CurrBuff, SQLDA^.SQLVar[x].SQLLen);
     {$R+}
-  end;
+    end;
 end;
 
 procedure TIBConnection.GetDateTime(CurrBuff, Buffer : pointer; AType : integer);
@@ -621,21 +622,24 @@ begin
   Move(Ext, Buffer^, 10);
 end;
 
-function TIBConnection.GetStatementType(cursor : pointer) : TStatementType;
+function TIBConnection.GetStatementType(cursor : TSQLhandle) : TStatementType;
 var
   x : integer;
   ResBuf : array [0..7] of char;
 begin
   Result := stNone;
-  x := isc_info_sql_stmt_type;
-  if isc_dsql_sql_info(@PIBCursor(cursor)^.Status, @PIBCursor(cursor)^.Statement, SizeOf(X),
-    @x, SizeOf(ResBuf), @ResBuf) <> 0 then
-    CheckError('TIBConnection.GetStatementType', PIBCursor(cursor)^.Status);
-  if Ord(ResBuf[0]) = isc_info_sql_stmt_type then
-  begin
-    x := isc_vax_integer(@ResBuf[1], 2);
-    Result := TStatementType(isc_vax_integer(@ResBuf[3], x));
-  end;
+  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
+      begin
+      x := isc_vax_integer(@ResBuf[1], 2);
+      Result := TStatementType(isc_vax_integer(@ResBuf[3], x));
+      end;
+    end;
 end;
 
 end.

+ 147 - 125
fcl/db/sqldb/sqldb.pp

@@ -35,6 +35,10 @@ type
     stDDL, stGetSegment, stPutSegment, stExecProcedure,
     stStartTrans, stCommit, stRollback, stSelectForUpd);
 
+  TSQLHandle = Class(TObject)
+//    Procedure FreeHandle ; Virtual; Abstract;
+  end;
+
 { TSQLConnection }
 
   TSQLConnection = class (TDatabase)
@@ -50,34 +54,34 @@ type
     procedure DoInternalConnect; override;
     procedure DoInternalDisconnect; override;
     function GetHandle : pointer; virtual; abstract;
-  public
-    procedure StartTransaction; override;
-    procedure EndTransaction; override;
-    destructor Destroy; override;
-    function GetCursor : pointer; virtual; abstract;
+
+    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 AllocStatement(cursor : pointer); virtual; abstract;
-    procedure FreeStatement(cursor : pointer); virtual; abstract;
-    procedure PrepareStatement(cursor: pointer;ATransaction : TSQLTransaction;buf : string); virtual; abstract;
-    procedure DescribeStatement(cursor : pointer); virtual; abstract;
-    procedure AllocFldBuffers(cursor : pointer); virtual; abstract;
-    procedure FreeFldBuffers(cursor : pointer); virtual; abstract;
-    procedure Execute(cursor: pointer;atransaction:tSQLtransaction); virtual; abstract;
-    procedure AddFieldDefs(cursor: pointer; FieldDefs : TfieldDefs); virtual; abstract;
-    function GetFieldSizes(cursor : pointer) : integer; virtual; abstract;
-    function Fetch(cursor : pointer) : boolean; virtual; abstract;
-    procedure LoadFieldsFromBuffer(cursor : pointer;buffer : pchar); virtual; abstract;
-    function GetFieldData(cursor : pointer; Field: TField; Buffer: Pointer;currbuff : pchar): Boolean; virtual; abstract;
-    function GetStatementType(cursor : pointer) : tStatementType; virtual; abstract;
-    function GetTransactionHandle(trans : pointer): pointer; virtual; abstract;
-    function Commit(trans : pointer) : boolean; virtual; abstract;
-    function RollBack(trans : pointer) : boolean; virtual; abstract;
-    function StartTransaction(trans : pointer) : boolean; virtual; abstract;
-    procedure CommitRetaining(trans : pointer); virtual; abstract;
-    procedure RollBackRetaining(trans : 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 GetTransactionHandle(trans : TSQLHandle): pointer; virtual; abstract;
+    function Commit(trans : TSQLHandle) : boolean; virtual; abstract;
+    function RollBack(trans : TSQLHandle) : boolean; virtual; abstract;
+    function StartTransaction(trans : TSQLHandle) : boolean; virtual; abstract;
+    procedure CommitRetaining(trans : TSQLHandle); virtual; abstract;
+    procedure RollBackRetaining(trans : TSQLHandle); virtual; abstract;
+  public
+    destructor Destroy; override;
     property Handle: Pointer read GetHandle;
   published
     property Password : string read FPassword write FPassword;
@@ -100,17 +104,18 @@ type
   TCommitRollbackAction = (caNone, caCommit, caCommitRetaining, caRollback,
     caRollbackRetaining);
 
-  TSQLTransaction = class (TComponent)
+  TSQLTransaction = class (TDBTransaction)
   private
-    FTrans               : pointer;
+    FTrans               : TSQLHandle;
     FAction              : TCommitRollbackAction;
     FActive              : boolean;
-    FDatabase            : TSQLConnection;
+//    FDatabase            : TSQLConnection;
 
     procedure SetActive(Value : boolean);
   protected
-    function GetHandle : pointer; virtual;
+    function GetHandle : Pointer; virtual;
   public
+    procedure EndTransaction; override;
     procedure Commit; virtual;
     procedure CommitRetaining; virtual;
     procedure Rollback; virtual;
@@ -122,30 +127,29 @@ 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 : TSQLConnection read FDatabase write FDatabase;
+    property Database;
   end;
 
 { TSQLQuery }
 
   TSQLQuery = class (Tbufdataset)
   private
-    FCursor              : pointer;
+    FCursor              : TSQLHandle;
     FOpen                : Boolean;
     FTransaction         : TSQLTransaction;
-    FDatabase            : TSQLConnection;
+//    FDatabase            : TSQLConnection;
     FSQL                 : TStrings;
     FIsEOF               : boolean;
     FStatementType       : TStatementType;
     FLoadingFieldDefs    : boolean;
     FRecordSize          : Integer;
 
-    procedure SetDatabase(Value : TSQLConnection);
     procedure SetTransaction(Value : TSQLTransaction);
-    procedure AllocStatement;
     procedure FreeStatement;
+    procedure FreeSelect;
     procedure PrepareStatement;
-    procedure DescribeStatement;
-    procedure AllocFldBuffers;
+    procedure PrepareSelect;
     procedure FreeFldBuffers;
     procedure Fetch;
     function LoadBuffer(Buffer : PChar): TGetResult;
@@ -158,6 +162,7 @@ type
 
   protected
     // abstract & virual methods of TDataset
+    procedure SetDatabase(Value : TDatabase); override;
     function AllocRecord: PChar; override;
     procedure FreeRecord(var Buffer: PChar); override;
     function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
@@ -177,13 +182,15 @@ type
     procedure ExecSQL; virtual;
     constructor Create(AOwner : TComponent); override;
     destructor Destroy; override;
+
+
   published
-    property Transaction : TSQLTransaction read FTransaction write SetTransaction;
-    property Database    : TSQLConnection read FDatabase write SetDatabase;
-    property SQL         : TStrings read FSQL write FSQL;
-    // Publish TDataset properties.
+    // redeclared data set properties
     property Active;
-    property AutoCalcFields;
+//    property FieldDefs stored FieldDefsStored;
+    property Filter;
+    property Filtered;
+    property FilterOptions;
     property BeforeOpen;
     property AfterOpen;
     property BeforeClose;
@@ -206,10 +213,23 @@ type
     property OnFilterRecord;
     property OnNewRecord;
     property OnPostError;
+    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;
 
 implementation
 
+ResourceString
+  SErrAssTransaction = 'Cannot assign transaction while old transaction active!';
+  SErrDatabasenAssigned = 'Database not assigned!';
+  SErrTransactionnSet = 'Transaction not set';
+  SErrNoStatement = 'SQL statement not set';
+
 { TSQLConnection }
 
 procedure TSQLConnection.SetTransaction(Value : TSQLTransaction);
@@ -229,7 +249,7 @@ begin
       FTransaction.Database := Self;
     end
     else
-      raise ESQLdbError.Create('Cannot assign transaction while old transaction active!');
+      DatabaseError(SErrAssTransaction);
 end;
 
 procedure TSQLConnection.DoInternalConnect;
@@ -238,22 +258,13 @@ begin
     Close;
 end;
 
-procedure TSQLConnection.DoInternalDisconnect;
-begin
-end;
-
-procedure TSQLConnection.StartTransaction;
+procedure TSQLQuery.GetStatementType;
 begin
-  if FTransaction = nil then
-    raise EDatabaseError.Create('TSQLConnection.StartTransaction: Transaction not set');
-  FTransaction.Active := True;
+  FStatementType := (Database as tsqlconnection).GetStatementType(Fcursor);
 end;
 
-procedure TSQLConnection.EndTransaction;
+procedure TSQLConnection.DoInternalDisconnect;
 begin
-  if FTransaction = nil then
-    raise EDatabaseError.Create('TSQLConnection.EndTransaction: Transaction not set');
-  FTransaction.Active := False;
 end;
 
 destructor TSQLConnection.Destroy;
@@ -278,45 +289,58 @@ end;
 
 function TSQLTransaction.GetHandle: pointer;
 begin
-  Result := FDatabase.GetTransactionHandle(FTrans);
+  Result := (Database as tsqlconnection).GetTransactionHandle(FTrans);
 end;
 
 procedure TSQLTransaction.Commit;
 begin
   if not FActive then Exit;
-  if FDatabase.commit(FTrans) then FActive := false;
+  if (Database as tsqlconnection).commit(FTrans) then FActive := false;
+  FTrans.free;
 end;
 
 procedure TSQLTransaction.CommitRetaining;
 begin
   if not FActive then Exit;
-  FDatabase.commitRetaining(FTrans);
+  (Database as tsqlconnection).commitRetaining(FTrans);
 end;
 
 procedure TSQLTransaction.Rollback;
 begin
   if not FActive then Exit;
-  if FDatabase.RollBack(FTrans) then FActive := false;
+  if (Database as tsqlconnection).RollBack(FTrans) then FActive := false;
+  FTrans.free;
+end;
+
+procedure TSQLTransaction.EndTransaction;
+begin
+  Rollback;
 end;
 
+
 procedure TSQLTransaction.RollbackRetaining;
 begin
   if not FActive then Exit;
-  FDatabase.RollBackRetaining(FTrans);
+  (Database as tsqlconnection).RollBackRetaining(FTrans);
 end;
 
 procedure TSQLTransaction.StartTransaction;
+
+var db : TSQLConnection;
+
 begin
   if Active then Active := False;
 
-  if FDatabase = nil then
-    raise ESQLdbError.Create('TSQLTransaction.StartTransaction: Database not assigned!');
+  db := (Database as tsqlconnection);
 
-  if not Database.Connected then
-    Database.Open;
-  if not assigned(FTrans) then FTrans := FDatabase.GetTrans;
+  if Db = nil then
+    DatabaseError(SErrDatabasenAssigned);
 
-  if FDatabase.StartTransaction(FTrans) then FActive := true;
+  if not Db.Connected then
+    Db.Open;
+  if not assigned(FTrans) then FTrans := Db.AllocateTransactionHandle;
+
+  if Db.StartTransaction(FTrans) then FActive := true;
 end;
 
 constructor TSQLTransaction.Create(AOwner : TComponent);
@@ -328,27 +352,14 @@ destructor TSQLTransaction.Destroy;
 begin
   // This will also do a Rollback, if the transaction is currently active
   Active := False;
-  
-  Database.FreeTrans(FTrans);
 
-  if Database <> nil then
-    Database.Transaction := nil;
+//  Database.Transaction := nil;
+
   inherited Destroy;
 end;
 
 { TSQLQuery }
 
-procedure TSQLQuery.AllocStatement;
-
-begin
-  if FDatabase = nil then
-    raise ESQLdbError.Create('TSQLQuery.Allocstatement: Database not assigned!');
-
-  if not FDatabase.Connected then
-    Fdatabase.Open;
-  FDatabase.AllocStatement(Fcursor);
-end;
-
 procedure TSQLQuery.SetTransaction(Value : TSQLTransaction);
 begin
   CheckInactive;
@@ -356,59 +367,71 @@ begin
     FTransaction := Value;
 end;
 
-procedure TSQLQuery.SetDatabase(Value : TSQLConnection);
+procedure TSQLQuery.SetDatabase(Value : TDatabase);
+
+var db : tsqlconnection;
+
 begin
-  CheckInactive;
-  if (FDatabase <> Value) then
-  begin
-    FDatabase := Value;
-    if (FTransaction = nil) and (Assigned(FDatabase.Transaction)) then
-      SetTransaction(FDatabase.Transaction);
-    if assigned(fcursor) then freemem(FCursor);
-    FCursor := FDatabase.getcursor;
-  end;
+  if (Database <> Value) then
+    begin
+    db := value as tsqlconnection;
+    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;
 
 procedure TSQLQuery.FreeStatement;
 begin
-  FDatabase.FreeStatement(FCursor);
+  (Database as tsqlconnection).FreeStatement(FCursor);
+end;
+
+procedure TSQLQuery.FreeSelect;
+begin
+  (Database as tsqlconnection).FreeSelect(FCursor);
 end;
 
 procedure TSQLQuery.PrepareStatement;
 var
   Buf : string;
   x   : integer;
+  db  : tsqlconnection;
 begin
+  db := (Database as tsqlconnection);
+  if Db = nil then
+    DatabaseError(SErrDatabasenAssigned);
+  if not Db.Connected then
+    db.Open;
   if FTransaction = nil then
-    raise EDatabaseError.Create('TSQLQuery.Execute: Transaction not set');
+    DatabaseError(SErrTransactionnSet);
+    
   if not FTransaction.Active then
     FTransaction.StartTransaction;
 
+  if assigned(fcursor) then FCursor.free;
+  FCursor := Db.AllocateCursorHandle;
+
   for x := 0 to FSQL.Count - 1 do
     Buf := Buf + FSQL[x] + ' ';
 
   if Buf='' then
     begin
-    DatabaseError('TSQLQuery: SQL statement not set');
+    DatabaseError(SErrNoStatement);
     exit;
     end;
-  FDatabase.PrepareStatement(Fcursor,FTransaction,buf);
-end;
-
-procedure TSQLQuery.DescribeStatement;
-begin
-  FDatabase.DescribeStatement(FCursor);
+  Db.PrepareStatement(Fcursor,FTransaction,buf);
 end;
 
-procedure TSQLQuery.AllocFldBuffers;
-
+procedure TSQLQuery.PrepareSelect;
 begin
-  FDatabase.AllocFldBuffers(FCursor);
+  (Database as tsqlconnection).PrepareSelect(FCursor);
 end;
 
 procedure TSQLQuery.FreeFldBuffers;
 begin
-  FDatabase.FreeFldBuffers(FCursor);
+  (Database as tsqlconnection).FreeFldBuffers(FCursor);
 end;
 
 procedure TSQLQuery.Fetch;
@@ -416,7 +439,7 @@ begin
   if not (FStatementType in [stSelect]) then
     Exit;
 
-  FIsEof := FDatabase.Fetch(Fcursor);
+  FIsEof := (Database as tsqlconnection).Fetch(Fcursor);
 end;
 
 function TSQLQuery.LoadBuffer(Buffer : PChar): TGetResult;
@@ -427,18 +450,13 @@ begin
     Result := grEOF;
     Exit;
   end;
-  FDatabase.LoadFieldsFromBuffer(FCursor,buffer);
+  (Database as tsqlconnection).LoadFieldsFromBuffer(FCursor,buffer);
   Result := grOK;
 end;
 
-procedure TSQLQuery.GetStatementType;
-begin
-  FStatementType := FDatabase.GetStatementType(Fcursor);
-end;
-
 procedure TSQLQuery.SetFieldSizes;
 begin
-  FRecordSize := FDatabase.GetfieldSizes(Fcursor);
+  FRecordSize := (Database as tsqlconnection).GetfieldSizes(Fcursor);
 end;
 
 procedure TSQLQuery.ExecuteImmediate;
@@ -453,15 +471,15 @@ end;
 procedure TSQLQuery.Execute;
 begin
   if FTransaction = nil then
-    raise EDatabaseError.Create('TSQLQuery.Execute: Transaction not set');
+    DatabaseError(SErrTransactionnSet);
   if not FTransaction.Active then
     FTransaction.StartTransaction;
-  FDatabase.execute(Fcursor,FTransaction);
+  (Database as tsqlconnection).execute(Fcursor,FTransaction);
 end;
 
 function TSQLQuery.AllocRecord: PChar;
 begin
-  writeln('AllocRecord, Recordsize:' + inttostr(FRecordSize));
+//  writeln('AllocRecord, Recordsize:' + inttostr(FRecordSize));
   Result := AllocMem(FRecordSize);
 end;
 
@@ -473,7 +491,7 @@ end;
 
 function TSQLQuery.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
 begin
-  result := FDatabase.GetFieldData(Fcursor,Field,buffer,activebuffer);
+  result := (Database as tsqlconnection).GetFieldData(Fcursor,Field,buffer,activebuffer);
 end;
 
 function TSQLQuery.GetNextRecord(Buffer: PChar): TGetResult;
@@ -491,13 +509,18 @@ end;
 
 procedure TSQLQuery.InternalClose;
 begin
-  FreeFldBuffers;
+  if FStatementType in [stSelect] then
+    begin
+    FreeFldBuffers;
+    FreeSelect;
+    end;
   FreeStatement;
   if DefaultFields then
     DestroyFields;
   FIsEOF := False;
   FRecordSize := 0;
   FOpen:=False;
+  FCursor.free;
   inherited internalclose;
 end;
 
@@ -520,7 +543,7 @@ begin
   try
     FieldDefs.Clear;
     
-    FDatabase.AddFieldDefs(fcursor,FieldDefs);
+    (Database as tsqlconnection).AddFieldDefs(fcursor,FieldDefs);
   finally
     FLoadingFieldDefs := False;
   end;
@@ -534,13 +557,11 @@ end;
 procedure TSQLQuery.InternalOpen;
 begin
   try
-    AllocStatement;
     PrepareStatement;
     GetStatementType;
     if FStatementType in [stSelect] then
     begin
-      DescribeStatement;
-      AllocFldBuffers;
+      PrepareSelect;
       Execute;
       FOpen:=True;
       InternalInitFieldDefs;
@@ -575,7 +596,6 @@ end;
 
 procedure TSQLQuery.ExecSQL;
 begin
-  AllocStatement;
   try
     PrepareStatement;
     GetStatementType;
@@ -594,8 +614,7 @@ end;
 destructor TSQLQuery.Destroy;
 begin
   if Active then Close;
-// This gives the strangest results?
-//  if assigned(Fdatabase) then FDatabase.freecursor(FCursor);
+//  if assigned(FCursor) then FCursor.destroy;
   FSQL.Free;
   inherited Destroy;
 end;
@@ -610,7 +629,10 @@ end.
 
 {
   $Log$
-  Revision 1.1  2004-08-31 09:49:47  michael
+  Revision 1.2  2004-09-26 16:56:32  michael
+  + Further fixes from Joost van der sluis for Postgresql
+
+  Revision 1.1  2004/08/31 09:49:47  michael
   + initial implementation of TSQLQuery
 
 }