📄 jvquib.pas
字号:
procedure TJvUIBDataBase.ClearTransactions;
begin
while (FTransactions <> nil) do
TJvUIBTransaction(FTransactions.Last).RemoveDatabase(Self);
end;
procedure TJvUIBDataBase.CloseTransactions;
var i: Integer;
begin
if (FTransactions <> nil) then
for i := 0 to FTransactions.Count - 1 do
TJvUIBTransaction(FTransactions.Items[i]).Close(etmDefault, True);
end;
constructor TJvUIBDataBase.Create(AOwner: TComponent);
begin
inherited;
FLibrary := TUIBLibrary.Create;
FLiBraryName := GetClientLibrary;
FLibrary.OnConnectionLost := DoOnConnectionLost;
FLibrary.OnGetDBExceptionClass := DoOnGetDBExceptionClass;
FDbHandle := nil;
FHandleShared := False;
FParams := TStringList.Create;
SQLDialect := 3;
CharacterSet := csNONE;
WriteParamString('sql_role_name', '');
FExceptions := TList.Create;
FMetadata := nil;
FMetaDataOptions := TMetaDataOptions.Create;
end;
destructor TJvUIBDataBase.Destroy;
begin
Lock;
try
Connected := False;
ClearTransactions;
TStringList(FParams).Free;
ClearExceptions;
FExceptions.Free;
FLibrary.Free;
FMetaDataOptions.Free;
finally
UnLock;
end;
inherited;
end;
procedure TJvUIBDataBase.DoOnConnectionLost(Lib: TUIBLibrary);
begin
Lib.RaiseErrors := False;
try
Connected := False;
finally
Lib.RaiseErrors := True;
if Assigned(FOnConnectionLost) then
FOnConnectionLost(Self);
end;
end;
function TJvUIBDataBase.GetCharacterSet: TCharacterSet;
var
i: TCharacterSet;
S: String;
begin
S := trim(UpperCase(ReadParamString('lc_ctype', 'NONE')));
Result := csNONE;
for i := low(TCharacterSet) to high(TCharacterSet) do
if (S = CharacterSetStr[i]) then
begin
Result := i;
Break;
end;
end;
function TJvUIBDataBase.GetConnected: Boolean;
begin
Lock;
try
result := FDbHandle <> nil;
finally
UnLock;
end;
end;
function TJvUIBDataBase.GetPassWord: string;
begin
result := ReadParamString('password');
end;
function TJvUIBDataBase.GetSQLDialect: Integer;
begin
try
Result := ReadParamInteger('sql_dialect', 3);
except
WriteParamInteger('sql_dialect', 3);
raise;
end;
end;
procedure TJvUIBDataBase.ExecuteImmediate(const Statement: string);
begin
FLibrary.Load(FLiBraryName);
FLibrary.DSQLExecuteImmediate(Statement, SQLDialect);
end;
procedure TJvUIBDataBase.CreateDatabase(PageSize: Integer = 2048);
var TrHandle: IscTrHandle;
const
CreateDb = 'CREATE DATABASE ''%s'' USER ''%s'' PASSWORD ''%s'' '+
'PAGE_SIZE %d DEFAULT CHARACTER SET %s';
begin
TrHandle := nil;
Connected := False;
FLibrary.Load(FLiBraryName);
FLibrary.DSQLExecuteImmediate(FDbHandle, TrHandle,
Format(CreateDb, [DatabaseName, UserName, PassWord, PageSize,
CharacterSetStr[CharacterSet]]), SQLDialect);
end;
function TJvUIBDataBase.GetUserName: string;
begin
result := ReadParamString('user_name');
end;
function TJvUIBDataBase.ReadParamInteger(Param: String;
Default: Integer): Integer;
begin
Result := StrToInt(ReadParamString(Param, IntToStr(Default)));
end;
function TJvUIBDataBase.ReadParamString(Param, Default: String): String;
var
I: Integer;
begin
Lock;
try
I := FParams.IndexOfName(Param);
if I >= 0 then
begin
Result := Copy(FParams[I], Length(Param) + 2, Maxint);
Exit;
end;
Result := Default;
finally
UnLock;
end;
end;
procedure TJvUIBDataBase.RemoveTransaction(Transaction: TJvUIBTransaction);
begin
if (FTransactions <> nil) then
begin
FTransactions.Remove(Transaction);
if FTransactions.Count = 0 then
begin
FTransactions.Free;
FTransactions := nil;
end;
end;
end;
procedure TJvUIBDataBase.SetCharacterSet(const Value: TCharacterSet);
begin
WriteParamString('lc_ctype', CharacterSetStr[Value]);
end;
procedure TJvUIBDataBase.SetConnected(const Value: Boolean);
begin
if (Value = Connected) then Exit;
Lock;
try
with FLibrary do
case Value of
True :
begin
if Assigned(BeforeConnect) then BeforeConnect(Self);
FLibrary.Load(FLiBraryName);
if not FHandleShared then
AttachDatabase(FDatabaseName, FDbHandle, FParams.Text, BreakLine);
if Assigned(AfterConnect) then AfterConnect(Self);
end;
False :
begin
if Assigned(BeforeDisconnect) then BeforeDisconnect(Self);
CloseTransactions;
if FMetadata <> nil then
FreeAndNil(FMetadata);
if FHandleShared then
begin
FDbHandle := nil;
FHandleShared := False;
end else
DetachDatabase(FDbHandle);
if Assigned(AfterDisconnect) then AfterDisconnect(Self);
end;
end;
finally
UnLock;
end;
end;
procedure TJvUIBDataBase.SetDatabaseName(const Value: TFileName);
begin
FDatabaseName := Value;
if (csDesigning in ComponentState) then
Connected := False;
end;
procedure TJvUIBDataBase.SetDbHandle(const Value: IscDbHandle);
begin
if (FDbHandle = nil) or ((FDbHandle <> nil) and FHandleShared) then
begin
FLibrary.Load(FLiBraryName);
FDbHandle := Value;
FHandleShared := (FDbHandle <> nil);
end else
raise Exception.Create(EUIB_DBHANDLEALLREADYSET);
end;
procedure TJvUIBDataBase.SetLibraryName(const Lib: TFileName);
begin
SetConnected(False);
FLibrary.UnLoad;
FLiBraryName := Lib;
end;
function TJvUIBDataBase.GetTransactions(const Index: Cardinal): TJvUIBTransaction;
begin
if FTransactions <> nil then
Result := FTransactions.Items[Index] else
raise EListError.CreateFmt(EUIB_INDEXERROR,[Index]);
end;
function TJvUIBDataBase.GetTransactionsCount: Cardinal;
begin
if FTransactions <> nil then
Result := FTransactions.Count else
Result := 0;
end;
procedure TJvUIBDataBase.SetParams(const Value: TStrings);
begin
FParams.Assign(Value);
end;
procedure TJvUIBDataBase.SetPassWord(const Value: string);
begin
WriteParamString('password', Value);
end;
procedure TJvUIBDataBase.SetSQLDialect(const Value: Integer);
begin
WriteParamInteger('sql_dialect', Value);
end;
procedure TJvUIBDataBase.SetUserName(const Value: string);
begin
WriteParamString('user_name', Value);
end;
procedure TJvUIBDataBase.WriteParamInteger(Param: String; Value: Integer);
begin
WriteParamString(Param, IntToStr(Value));
end;
procedure TJvUIBDataBase.WriteParamString(Param, Value: String);
var
I: Integer;
S: string;
begin
Lock;
try
S := Param + '=' + Value;
I := FParams.IndexOfName(Param);
if I >= 0 then
FParams[I] := S
else
FParams.Add(S);
finally
UnLock;
end;
end;
procedure TJvUIBDataBase.ClearExceptions;
var i: Integer;
begin
for i := 0 to FExceptions.Count - 1 do
FreeMem(FExceptions[i]);
FExceptions.Clear;
end;
procedure TJvUIBDataBase.RegisterException(Excpt: EUIBExceptionClass;
ID: Integer);
var
ExcepInfo: PExceptionInfo;
i: Integer;
begin
for i := 0 to FExceptions.Count - 1 do
if PExceptionInfo(FExceptions[i]).ID = ID then
raise Exception.CreateFmt(EUIB_EXPTIONREGISTERED, [ID]);
GetMem(ExcepInfo, SizeOf(TExceptionInfo));
ExcepInfo.ExepClass := Excpt;
ExcepInfo.ID := ID;
FExceptions.Add(ExcepInfo);
end;
function TJvUIBDataBase.RegisterException(Excpt: EUIBExceptionClass;
const Name: string): Integer;
var
Transaction: TJvUIBTransaction;
Query: TJvUIBQuery;
begin
Result := -1;
Transaction := TJvUIBTransaction.Create(nil);
Query := TJvUIBQuery.Create(nil);
try
Transaction.DataBase := Self;
Query.Transaction := Transaction;
Query.CachedFetch := False;
Query.SQL.Text := 'SELECT RDB$EXCEPTION_NUMBER FROM RDB$EXCEPTIONS WHERE RDB$EXCEPTION_NAME = ?';
Query.Params.AsString[0] := UpperCase(Name);
Query.Open;
if not Query.Eof then
begin
Result := Query.Fields.AsInteger[0];
RegisterException(Excpt, Result);
end;
Query.Close(etmCommit);
if (Result = - 1) then
raise Exception.CreateFmt(EUIB_EXCEPTIONNOTFOUND, [Name]);
finally
Query.Free;
Transaction.Free;
end;
end;
procedure TJvUIBDataBase.UnRegisterException(Number: Integer);
var i: Integer;
begin
for i := 0 to FExceptions.Count - 1 do
if PExceptionInfo(FExceptions[i]).ID = Number then
begin
FreeMem(FExceptions[i]);
FExceptions.Delete(i);
Break;
end;
end;
procedure TJvUIBDataBase.UnRegisterExceptions(Excpt: EUIBExceptionClass);
var i: Integer;
begin
i := 0;
while i < FExceptions.Count do
begin
if (PExceptionInfo(FExceptions[i]).ExepClass = Excpt) then
begin
FreeMem(FExceptions[i]);
FExceptions.Delete(i);
end else
inc(i);
end;
end;
procedure TJvUIBDataBase.DoOnGetDBExceptionClass(Number: Integer; out Excep: EUIBExceptionClass);
var i: Integer;
begin
for i := 0 to FExceptions.Count - 1 do
if (PExceptionInfo(FExceptions[i]).ID = Number) then
begin
Excep := PExceptionInfo(FExceptions[i]).ExepClass;
Exit;
end;
Excep := EUIBException;
end;
function TJvUIBDataBase.GetMetadata(Refresh: boolean = False): TObject;
var
Transaction: TJvUIBTransaction;
begin
if Refresh and (FMetadata <> nil) then
FreeAndNil(FMetadata);
if (FMetadata = nil) then
begin
Transaction := TJvUIBTransaction.Create(nil);
try
Transaction.Database := Self;
FMetadata := TMetaDataBase.Create(nil, -1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -