|
@@ -19,6 +19,7 @@
|
|
unit Interbase;
|
|
unit Interbase;
|
|
|
|
|
|
{$H+}
|
|
{$H+}
|
|
|
|
+{$M+} // ### remove this!!!
|
|
|
|
|
|
interface
|
|
interface
|
|
|
|
|
|
@@ -33,7 +34,10 @@ type
|
|
TIBTransaction = class;
|
|
TIBTransaction = class;
|
|
TIBQuery = class;
|
|
TIBQuery = class;
|
|
TIBStoredProc = class;
|
|
TIBStoredProc = class;
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ EInterBaseError = class(Exception);
|
|
|
|
+
|
|
|
|
+
|
|
{ TIBDatabase }
|
|
{ TIBDatabase }
|
|
|
|
|
|
TIBDatabase = class (TDatabase)
|
|
TIBDatabase = class (TDatabase)
|
|
@@ -43,6 +47,7 @@ type
|
|
FStatus : array [0..19] of ISC_STATUS;
|
|
FStatus : array [0..19] of ISC_STATUS;
|
|
FTransaction : TIBTransaction;
|
|
FTransaction : TIBTransaction;
|
|
FUserName : string;
|
|
FUserName : string;
|
|
|
|
+ FCharSet : string;
|
|
FDialect : integer;
|
|
FDialect : integer;
|
|
|
|
|
|
procedure SetDBDialect;
|
|
procedure SetDBDialect;
|
|
@@ -64,8 +69,8 @@ type
|
|
public
|
|
public
|
|
procedure StartTransaction; override;
|
|
procedure StartTransaction; override;
|
|
procedure EndTransaction; override;
|
|
procedure EndTransaction; override;
|
|
- constructor Create(AOwner : TComponent); override;
|
|
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
|
|
+ property Handle: Pointer read GetHandle;
|
|
published
|
|
published
|
|
{ On connect, TIBDatabase object retrieve SQL dialect of database file,
|
|
{ On connect, TIBDatabase object retrieve SQL dialect of database file,
|
|
and sets this property to responding value }
|
|
and sets this property to responding value }
|
|
@@ -80,6 +85,8 @@ type
|
|
{ Before firing Open method you must set @link(Password),@link(DatabaseName),
|
|
{ Before firing Open method you must set @link(Password),@link(DatabaseName),
|
|
@link(UserName) properties in order of successfull connect to database }
|
|
@link(UserName) properties in order of successfull connect to database }
|
|
property UserName : string read FUserName write FUserName;
|
|
property UserName : string read FUserName write FUserName;
|
|
|
|
+ { The character set used in SQL statements }
|
|
|
|
+ property CharSet : string read FCharSet write FCharSet;
|
|
|
|
|
|
{ Identifies, if connection to Interbase server is established, or not.
|
|
{ Identifies, if connection to Interbase server is established, or not.
|
|
Instead of calling Open, Close methods you can connect or disconnect
|
|
Instead of calling Open, Close methods you can connect or disconnect
|
|
@@ -151,6 +158,7 @@ type
|
|
procedure StartTransaction;
|
|
procedure StartTransaction;
|
|
constructor Create(AOwner : TComponent); override;
|
|
constructor Create(AOwner : TComponent); override;
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
|
|
+ property Handle: Pointer read GetHandle;
|
|
published
|
|
published
|
|
{ Default action while closing transaction by setting
|
|
{ Default action while closing transaction by setting
|
|
@link(Active) property. For details see @link(TCommitRollbackAction)}
|
|
@link(Active) property. For details see @link(TCommitRollbackAction)}
|
|
@@ -306,7 +314,7 @@ begin
|
|
p := @Status;
|
|
p := @Status;
|
|
while isc_interprete(Buf, @p) > 0 do
|
|
while isc_interprete(Buf, @p) > 0 do
|
|
Msg := Msg + #10' -' + StrPas(Buf);
|
|
Msg := Msg + #10' -' + StrPas(Buf);
|
|
- raise Exception.Create(ProcName + ': ' + Msg);
|
|
|
|
|
|
+ raise EInterBaseError.Create(ProcName + ': ' + Msg);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -343,8 +351,9 @@ begin
|
|
if FTransaction = nil then
|
|
if FTransaction = nil then
|
|
begin
|
|
begin
|
|
FTransaction := Value;
|
|
FTransaction := Value;
|
|
- FTransaction.Database := Self;
|
|
|
|
- Exit;
|
|
|
|
|
|
+ if Assigned(FTransaction) then
|
|
|
|
+ FTransaction.Database := Self;
|
|
|
|
+ exit;
|
|
end;
|
|
end;
|
|
|
|
|
|
if (Value <> FTransaction) and (Value <> nil) then
|
|
if (Value <> FTransaction) and (Value <> nil) then
|
|
@@ -353,7 +362,8 @@ begin
|
|
FTransaction := Value;
|
|
FTransaction := Value;
|
|
FTransaction.Database := Self;
|
|
FTransaction.Database := Self;
|
|
end
|
|
end
|
|
- else Exception.Create('Cannot assign transaction while old transaction active!');
|
|
|
|
|
|
+ else
|
|
|
|
+ raise EInterBaseError.Create('Cannot assign transaction while old transaction active!');
|
|
end;
|
|
end;
|
|
|
|
|
|
function TIBDatabase.GetHandle: pointer;
|
|
function TIBDatabase.GetHandle: pointer;
|
|
@@ -374,8 +384,11 @@ begin
|
|
if (FPassword <> '') then
|
|
if (FPassword <> '') then
|
|
DPB := DPB + chr(isc_dpb_password) + chr(Length(FPassword)) + FPassword;
|
|
DPB := DPB + chr(isc_dpb_password) + chr(Length(FPassword)) + FPassword;
|
|
end;
|
|
end;
|
|
|
|
+ if Length(CharSet) > 0 then
|
|
|
|
+ DPB := DPB + Chr(isc_dpb_lc_ctype) + Chr(Length(CharSet)) + CharSet;
|
|
|
|
+
|
|
if (DatabaseName = '') then
|
|
if (DatabaseName = '') then
|
|
- raise Exception.Create('TIBDatabase.Open: Database connect string not filled in!');
|
|
|
|
|
|
+ raise EInterBaseError.Create('TIBDatabase.Open: Database connect string not filled in!');
|
|
FIBDatabaseHandle := nil;
|
|
FIBDatabaseHandle := nil;
|
|
if isc_attach_database(@FStatus, Length(DatabaseName), @DatabaseName[1], @FIBDatabaseHandle,
|
|
if isc_attach_database(@FStatus, Length(DatabaseName), @DatabaseName[1], @FIBDatabaseHandle,
|
|
Length(DPB), @DPB[1]) <> 0 then
|
|
Length(DPB), @DPB[1]) <> 0 then
|
|
@@ -408,16 +421,6 @@ begin
|
|
FTransaction.Active := False;
|
|
FTransaction.Active := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
-constructor TIBDatabase.Create(AOwner : TComponent);
|
|
|
|
-begin
|
|
|
|
- inherited Create(AOwner);
|
|
|
|
- FIBDatabaseHandle := nil;
|
|
|
|
- FPassword := '';
|
|
|
|
- FTransaction := nil;
|
|
|
|
- FUserName := '';
|
|
|
|
- FillChar(FStatus, SizeOf(FStatus), #0);
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
destructor TIBDatabase.Destroy;
|
|
destructor TIBDatabase.Destroy;
|
|
begin
|
|
begin
|
|
if FTransaction <> nil then
|
|
if FTransaction <> nil then
|
|
@@ -432,17 +435,9 @@ end;
|
|
|
|
|
|
procedure TIBTransaction.SetActive(Value : boolean);
|
|
procedure TIBTransaction.SetActive(Value : boolean);
|
|
begin
|
|
begin
|
|
- if FActive = Value then Exit;
|
|
|
|
- if (FActive) and (not Value) then
|
|
|
|
- case FAction of
|
|
|
|
- caCommit : Commit;
|
|
|
|
- caCommitRetaining : CommitRetaining;
|
|
|
|
- caRollback : Rollback;
|
|
|
|
- caRollbackRetaining : RollbackRetaining;
|
|
|
|
- else
|
|
|
|
- Exception.Create('TIBTransaction.SetActive: Transaction is already active.');
|
|
|
|
- end;
|
|
|
|
- if (not FActive) and (Value) then
|
|
|
|
|
|
+ if FActive and (not Value) then
|
|
|
|
+ Rollback
|
|
|
|
+ else if (not FActive) and Value then
|
|
StartTransaction;
|
|
StartTransaction;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -523,7 +518,7 @@ begin
|
|
if Active then Active := False;
|
|
if Active then Active := False;
|
|
|
|
|
|
if FDatabase = nil then
|
|
if FDatabase = nil then
|
|
- Exception.Create('TIBTransaction.StartTransaction: Database not assigned!');
|
|
|
|
|
|
+ raise EInterBaseError.Create('TIBTransaction.StartTransaction: Database not assigned!');
|
|
|
|
|
|
if not Database.Connected then
|
|
if not Database.Connected then
|
|
Database.Open;
|
|
Database.Open;
|
|
@@ -541,34 +536,16 @@ end;
|
|
constructor TIBTransaction.Create(AOwner : TComponent);
|
|
constructor TIBTransaction.Create(AOwner : TComponent);
|
|
begin
|
|
begin
|
|
inherited Create(AOwner);
|
|
inherited Create(AOwner);
|
|
-
|
|
|
|
- FAction := caNone;
|
|
|
|
- FActive := False;
|
|
|
|
- FAccessMode := amReadWrite;
|
|
|
|
FIsolationLevel := ilReadCommitted;
|
|
FIsolationLevel := ilReadCommitted;
|
|
- FLockResolution := lrWait;
|
|
|
|
- FTableReservation := trNone;
|
|
|
|
- FTransactionHandle := nil;
|
|
|
|
- FDatabase := nil;
|
|
|
|
-
|
|
|
|
- FillChar(FStatus, SizeOf(FStatus), #0);
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TIBTransaction.Destroy;
|
|
destructor TIBTransaction.Destroy;
|
|
begin
|
|
begin
|
|
|
|
+ // This will also do a Rollback, if the transaction is currently active
|
|
|
|
+ Active := False;
|
|
|
|
+
|
|
if Database <> nil then
|
|
if Database <> nil then
|
|
Database.Transaction := nil;
|
|
Database.Transaction := nil;
|
|
-
|
|
|
|
-{ // i really can't allow commit of transaction
|
|
|
|
- // on destroy...
|
|
|
|
-}
|
|
|
|
-{
|
|
|
|
- try
|
|
|
|
- if Active then
|
|
|
|
- Active := False;
|
|
|
|
- except
|
|
|
|
- end;
|
|
|
|
-}
|
|
|
|
|
|
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
end;
|
|
end;
|
|
@@ -596,8 +573,11 @@ end;
|
|
procedure TIBQuery.AllocSQLDA(Count : integer);
|
|
procedure TIBQuery.AllocSQLDA(Count : integer);
|
|
begin
|
|
begin
|
|
if FSQLDAAllocated > 0 then
|
|
if FSQLDAAllocated > 0 then
|
|
- FreeMem(FSQLDA, XSQLDA_Length * FSQLDAAllocated);
|
|
|
|
- GetMem(FSQLDA, XSQLDA_Length * Count);
|
|
|
|
|
|
+ FreeMem(FSQLDA);
|
|
|
|
+ GetMem(FSQLDA, XSQLDA_Length(Count));
|
|
|
|
+ { Zero out the memory block to avoid problems with exceptions within the
|
|
|
|
+ constructor of this class. }
|
|
|
|
+ FillChar(FSQLDA^, XSQLDA_Length(Count), 0);
|
|
FSQLDAAllocated := Count;
|
|
FSQLDAAllocated := Count;
|
|
FSQLDA^.Version := sqlda_version1;
|
|
FSQLDA^.Version := sqlda_version1;
|
|
FSQLDA^.SQLN := Count;
|
|
FSQLDA^.SQLN := Count;
|
|
@@ -618,7 +598,7 @@ end;
|
|
procedure TIBQuery.FreeStatement;
|
|
procedure TIBQuery.FreeStatement;
|
|
begin
|
|
begin
|
|
if isc_dsql_free_statement(@FStatus, @FStatement, DSQL_Drop) <> 0 then
|
|
if isc_dsql_free_statement(@FStatus, @FStatement, DSQL_Drop) <> 0 then
|
|
- CheckError('TIBQuery.DeallocStatement', FStatus);
|
|
|
|
|
|
+ CheckError('TIBQuery.FreeStatement', FStatus);
|
|
FStatement := nil;
|
|
FStatement := nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -633,7 +613,7 @@ begin
|
|
for x := 0 to FSQL.Count - 1 do
|
|
for x := 0 to FSQL.Count - 1 do
|
|
Buf := Buf + FSQL[x] + ' ';
|
|
Buf := Buf + FSQL[x] + ' ';
|
|
|
|
|
|
- if isc_dsql_prepare(@FStatus, @tr, @FStatement, 0, @Buf[1], 1, nil) <> 0 then
|
|
|
|
|
|
+ if isc_dsql_prepare(@FStatus, @tr, @FStatement, 0, @Buf[1], Database.Dialect, nil) <> 0 then
|
|
CheckError('TIBQuery.PrepareStatement', FStatus);
|
|
CheckError('TIBQuery.PrepareStatement', FStatus);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -678,14 +658,12 @@ end;
|
|
|
|
|
|
procedure TIBQuery.AllocFldBuffers;
|
|
procedure TIBQuery.AllocFldBuffers;
|
|
var
|
|
var
|
|
- Buf: pointer;
|
|
|
|
x : shortint;
|
|
x : shortint;
|
|
begin
|
|
begin
|
|
{$R-}
|
|
{$R-}
|
|
for x := 0 to FSQLDA^.SQLD - 1 do
|
|
for x := 0 to FSQLDA^.SQLD - 1 do
|
|
begin
|
|
begin
|
|
- Buf := AllocMem(FSQLDA^.SQLVar[x].SQLLen);
|
|
|
|
- FSQLDA^.SQLVar[x].SQLData := Buf;
|
|
|
|
|
|
+ FSQLDA^.SQLVar[x].SQLData := AllocMem(FSQLDA^.SQLVar[x].SQLLen);
|
|
FSQLDA^.SQLVar[x].SQLInd := @FFieldFlag[x];
|
|
FSQLDA^.SQLVar[x].SQLInd := @FFieldFlag[x];
|
|
end;
|
|
end;
|
|
{$R+}
|
|
{$R+}
|
|
@@ -1161,24 +1139,20 @@ end;
|
|
procedure TIBQuery.ExecSQL;
|
|
procedure TIBQuery.ExecSQL;
|
|
begin
|
|
begin
|
|
AllocStatement;
|
|
AllocStatement;
|
|
- PrepareStatement;
|
|
|
|
- GetStatementType;
|
|
|
|
- Execute;
|
|
|
|
- FreeStatement;
|
|
|
|
|
|
+ try
|
|
|
|
+ PrepareStatement;
|
|
|
|
+ GetStatementType;
|
|
|
|
+ Execute;
|
|
|
|
+ finally
|
|
|
|
+ FreeStatement;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TIBQuery.Create(AOwner : TComponent);
|
|
constructor TIBQuery.Create(AOwner : TComponent);
|
|
begin
|
|
begin
|
|
inherited Create(AOwner);
|
|
inherited Create(AOwner);
|
|
- FillChar(FFieldFlag, SizeOf(FFieldFlag), #0);
|
|
|
|
FSQL := TStringList.Create;
|
|
FSQL := TStringList.Create;
|
|
- FStatement := nil;
|
|
|
|
FCurrentRecord := -1;
|
|
FCurrentRecord := -1;
|
|
- FDatabase := nil;
|
|
|
|
- FTransaction := nil;
|
|
|
|
- FSQLDAAllocated := 0;
|
|
|
|
- FLoadingFieldDefs := False;
|
|
|
|
- FPrepared := False;
|
|
|
|
AllocSQLDA(10);
|
|
AllocSQLDA(10);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1187,7 +1161,7 @@ begin
|
|
if Active then Close;
|
|
if Active then Close;
|
|
FSQL.Free;
|
|
FSQL.Free;
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
- FreeMem(FSQLDA, XSQLDA_Length * FSQLDAAllocated);
|
|
|
|
|
|
+ FreeMem(FSQLDA);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TIBStoredProc }
|
|
{ TIBStoredProc }
|