📄 ibdatabase.pas
字号:
Length(Params[IndexOfUser]));
IndexOfPassword := IndexOfDBConst(DPBConstantNames[isc_dpb_password]);
if IndexOfPassword <> -1 then
begin
Password := Copy(Params[IndexOfPassword],
Pos('=', Params[IndexOfPassword]) + 1, {mbcs ok}
Length(Params[IndexOfPassword]));
OldPassword := password;
end;
result := false;
if Assigned(LoginDialogExProc) then
result := LoginDialogExProc(DatabaseName, Username, Password, False);
if result then
begin
if IndexOfUser = -1 then
Params.Add(DPBConstantNames[isc_dpb_user_name] + '=' + Username)
else
Params[IndexOfUser] := DPBConstantNames[isc_dpb_user_name] +
'=' + Username;
if (Password = OldPassword) then
FHiddenPassword := ''
else
begin
FHiddenPassword := Password;
if OldPassword <> '' then
HidePassword;
end;
end;
end;
end;
procedure TIBDatabase.DoConnect;
var
DPB: String;
TempDBParams: TStrings;
i : Integer;
begin
CheckInactive;
CheckDatabaseName;
if (not LoginPrompt) and (FHiddenPassword <> '') then
begin
FHiddenPassword := '';
FDBParamsChanged := True;
end;
{ Use builtin login prompt if requested }
if LoginPrompt and not Login then
IBError(ibxeOperationCancelled, [nil]);
{ Generate a new DPB if necessary }
if (FDBParamsChanged) then
begin
FDBParamsChanged := False;
if (not LoginPrompt) or (FHiddenPassword = '') then
GenerateDPB(FDBParams, DPB, FDPBLength)
else
begin
TempDBParams := TStringList.Create;
try
TempDBParams.Assign(FDBParams);
TempDBParams.Add('password=' + FHiddenPassword);
GenerateDPB(TempDBParams, DPB, FDPBLength);
finally
TempDBParams.Free;
end;
end;
IBAlloc(FDPB, 0, FDPBLength);
Move(DPB[1], FDPB[0], FDPBLength);
end;
if Call(isc_attach_database(StatusVector, Length(FDBName),
PChar(FDBName), @FHandle,
FDPBLength, FDPB), False) > 0 then
begin
FHandle := nil;
IBDataBaseError;
end;
FDBSQLDialect := GetDBSQLDialect;
ValidateClientSQLDialect;
if not (csDesigning in ComponentState) then
MonitorHook.DBConnect(Self);
for i := 0 to FEventNotifiers.Count - 1 do
if IIBEventNotifier(FEventNotifiers[i]).GetAutoRegister then
IIBEventNotifier(FEventNotifiers[i]).RegisterEvents;
end;
procedure TIBDatabase.RemoveSQLObject(Idx: Integer);
var
ds: TIBBase;
begin
if (Idx >= 0) and (FSQLObjects[Idx] <> nil) then
begin
ds := SQLObjects[Idx];
FSQLObjects[Idx] := nil;
ds.Database := nil;
if (ds.owner is TDataSet) then
UnregisterClient(TDataSet(ds.Owner));
end;
end;
procedure TIBDatabase.RemoveSQLObjects;
var
i: Integer;
begin
for i := 0 to FSQLObjects.Count - 1 do if FSQLObjects[i] <> nil then
begin
RemoveSQLObject(i);
if (TIBBase(FSQLObjects[i]).owner is TDataSet) then
UnregisterClient(TDataSet(TIBBase(FSQLObjects[i]).owner));
end;
end;
procedure TIBDatabase.RemoveTransaction(Idx: Integer);
var
TR: TIBTransaction;
begin
if ((Idx >= 0) and (FTransactions[Idx] <> nil)) then
begin
TR := Transactions[Idx];
FTransactions[Idx] := nil;
TR.RemoveDatabase(TR.FindDatabase(Self));
if TR = FDefaultTransaction then
FDefaultTransaction := nil;
end;
end;
procedure TIBDatabase.RemoveTransactions;
var
i: Integer;
begin
for i := 0 to FTransactions.Count - 1 do if FTransactions[i] <> nil then
RemoveTransaction(i);
end;
procedure TIBDatabase.SetDatabaseName(const Value: TIBFileName);
begin
if FDBName <> Value then
begin
EnsureInactive;
CheckInactive;
FDBName := Value;
FSchema.FreeNodes;
end;
end;
procedure TIBDatabase.SetDBParamByDPB(const Idx: Integer; Value: String);
var
ConstIdx: Integer;
begin
ConstIdx := IndexOfDBConst(DPBConstantNames[Idx]);
if (Value = '') then
begin
if ConstIdx <> -1 then
Params.Delete(ConstIdx);
end
else
begin
if (ConstIdx = -1) then
Params.Add(DPBConstantNames[Idx] + '=' + Value)
else
Params[ConstIdx] := DPBConstantNames[Idx] + '=' + Value;
end;
end;
procedure TIBDatabase.SetDBParams(Value: TStrings);
begin
FDBParams.Assign(Value);
end;
procedure TIBDatabase.SetDefaultTransaction(Value: TIBTransaction);
var
i: Integer;
begin
if (FDefaultTransaction <> nil) and (FDefaultTransaction <> Value) then
begin
i := FindTransaction(FDefaultTransaction);
if (i <> -1) and (FDefaultTransaction.DefaultDatabase <> self) then
RemoveTransaction(i);
end;
if (Value <> nil) and (FDefaultTransaction <> Value) then
begin
Value.AddDatabase(Self);
AddTransaction(Value);
end;
FDefaultTransaction := Value;
end;
procedure TIBDatabase.SetHandle(Value: TISC_DB_HANDLE);
begin
if HandleIsShared then
Close
else
CheckInactive;
FHandle := Value;
FHandleIsShared := (Value <> nil);
end;
procedure TIBDatabase.SetIdleTimer(Value: Integer);
begin
if Value < 0 then
IBError(ibxeTimeoutNegative, [nil])
else
if (Value = 0) then
begin
FTimer.Enabled := False;
FTimer.Interval := 0;
end
else
if (Value > 0) then
begin
FTimer.Interval := Value;
if not (csDesigning in ComponentState) then
FTimer.Enabled := True;
end;
end;
function TIBDatabase.TestConnected: Boolean;
var
DatabaseInfo: TIBDatabaseInfo;
begin
result := Connected;
if result then
begin
DatabaseInfo := TIBDatabaseInfo.Create(self);
try
DatabaseInfo.Database := self;
{ poke the server to see if connected }
if DatabaseInfo.BaseLevel = 0 then ;
DatabaseInfo.Free;
except
ForceClose;
result := False;
DatabaseInfo.Free;
end;
end;
end;
procedure TIBDatabase.TimeoutConnection(Sender: TObject);
begin
if Connected then
begin
if FCanTimeout then
begin
ForceClose;
if Assigned(FOnIdleTimer) then
FOnIdleTimer(Self);
end
else
FCanTimeout := True;
end;
end;
function TIBDatabase.GetIsReadOnly: Boolean;
var
DatabaseInfo: TIBDatabaseInfo;
begin
DatabaseInfo := TIBDatabaseInfo.Create(self);
DatabaseInfo.Database := self;
if (DatabaseInfo.ODSMajorVersion < 10) then
result := false
else
begin
if (DatabaseInfo.ReadOnly = 0) then
result := false
else
result := true;
end;
DatabaseInfo.Free;
end;
function TIBDatabase.GetSQLDialect: Integer;
begin
Result := FSQLDialect;
end;
procedure TIBDatabase.SetSQLDialect(const Value: Integer);
begin
if (Value < 1) then IBError(ibxeSQLDialectInvalid, [nil]);
if ((FHandle = nil) or (Value <= FDBSQLDialect)) then
FSQLDialect := Value
else
IBError(ibxeSQLDialectInvalid, [nil]);
end;
function TIBDatabase.GetDBSQLDialect: Integer;
var
DatabaseInfo: TIBDatabaseInfo;
begin
DatabaseInfo := TIBDatabaseInfo.Create(self);
DatabaseInfo.Database := self;
result := DatabaseInfo.DBSQLDialect;
DatabaseInfo.Free;
end;
procedure TIBDatabase.ValidateClientSQLDialect;
begin
if (FDBSQLDialect < FSQLDialect) then
begin
FSQLDialect := FDBSQLDialect;
if Assigned (FOnDialectDowngradeWarning) then
FOnDialectDowngradeWarning(self);
end;
end;
procedure TIBDatabase.ApplyUpdates(const DataSets: array of TDataSet);
var
I: Integer;
DS: TIBCustomDataSet;
TR: TIBTransaction;
begin
TR := nil;
for I := 0 to High(DataSets) do
begin
DS := TIBCustomDataSet(DataSets[I]);
if DS.Database <> Self then
IBError(ibxeUpdateWrongDB, [nil]);
if TR = nil then
TR := DS.Transaction;
if (DS.Transaction <> TR) or (TR = nil) then
IBError(ibxeUpdateWrongTR, [nil]);
end;
TR.CheckInTransaction;
for I := 0 to High(DataSets) do
begin
DS := TIBCustomDataSet(DataSets[I]);
DS.ApplyUpdates;
end;
TR.CommitRetaining;
end;
procedure TIBDatabase.CloseDataSets;
var
i: Integer;
begin
for i := 0 to DataSetCount - 1 do
if (DataSets[i] <> nil) then
DataSets[i].close;
end;
procedure TIBDatabase.GetFieldNames(const TableName: string; List: TStrings);
var
Query: TIBSQL;
begin
if TableName = '' then
IBError(ibxeNoTableName, [nil]);
if not Connected then
Open;
if not FInternalTransaction.Active then
FInternalTransaction.StartTransaction;
Query := TIBSQL.Create(self);
try
Query.GoToFirstRecordOnExecute := False;
Query.Database := Self;
Query.Transaction := FInternalTransaction;
Query.SQL.Text := 'Select R.RDB$FIELD_NAME ' + {do not localize}
'from RDB$RELATION_FIELDS R, RDB$FIELDS F ' + {do not localize}
'where R.RDB$RELATION_NAME = ' + {do not localize}
'''' +
FormatIdentifierValue(SQLDialect, TableName) +
''' ' +
'and R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME ' + {do not localize}
'ORDER BY R.RDB$FIELD_NAME'; {do not localize}
Query.Prepare;
Query.ExecQuery;
with List do
begin
BeginUpdate;
try
Clear;
while (not Query.EOF) and (Query.Next <> nil) do
List.Add(TrimRight(Query.Current.ByName('RDB$FIELD_NAME').AsString)); {do not localize}
finally
EndUpdate;
end;
end;
finally
Query.free;
FInternalTransaction.Commit;
end;
end;
procedure TIBDatabase.GetTableNames(List: TStrings; SystemTables: Boolean);
var
Query : TIBSQL;
begin
if not (csReading in ComponentState) then
begin
if not Connected then
Open;
if not FInternalTransaction.Active then
FInternalTransaction.StartTransaction;
Query := TIBSQL.Create(self);
try
Query.GoToFirstRecordOnExecute := False;
Query.Database := Self;
Query.Transaction := FInternalTransaction;
if SystemTables then
Query.SQL.Text := 'Select RDB$RELATION_NAME from RDB$RELATIONS ' + {do not localize}
' where RDB$VIEW_BLR is NULL ' + {do not localize}
'ORDER BY RDB$RELATION_NAME' {do not localize}
else
Query.SQL.Text := 'Select RDB$RELATION_NAME from RDB$RELATIONS ' + {do not localize}
' where RDB$VIEW_BLR is NULL and RDB$SYSTEM_FLAG = 0 ' + {do not localize}
'ORDER BY RDB$RELATION_NAME'; {do not localize}
Query.Prepare;
Query.ExecQuery;
with List do
begin
BeginUpdate;
try
Clear;
while (not Query.EOF) and (Query.Next <> nil) do
List.Add(TrimRight(Query.Current[0].AsString));
finally
EndUpdate;
end;
end;
finally
Query.Free;
FInternalTransaction.Commit;
end;
end;
end;
procedure TIBDataBase.AddEventNotifier(Notifier: IIBEventNotifier);
begin
FEventNotifiers.Add(Pointer(Notifier));
end;
procedure TIBDataBase.RemoveEventNotifier(Notifier: IIBEventNotifier);
var
Index : Integer;
begin
Index := FEventNotifiers.IndexOf(Pointer(Notifier));
if Index >= 0 then
FEventNotifiers.Delete(Index);
end;
{ TIBTransaction }
constructor TIBTransaction.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FIBLoaded := False;
CheckIBLoaded;
FIBLoaded := True;
CheckIBLoaded;
FDatabases := TList.Create;
FSQLObjects := TList.Create;
FHandle := nil;
FTPB := nil;
FTPBLength := 0;
FTRParams := TStringList.Create;
FTRParamsChanged := True;
TStringList(FTRParams).OnChange := TRParamsChange;
TStringList(FTRParams).OnChanging := TRParamsChanging;
FTimer := TIBTimer.Create(Self);
FTimer.Enabled := False;
FTimer.Interval := 0;
FTimer.OnTimer := TimeoutTransaction;
FDefaultAction := taCommit;
end;
destructor TIBTransaction.Destroy;
var
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -