📄 fibmiscellaneous.pas
字号:
function EquelQUADs(const Value1,Value2:TISC_QUAD):boolean;
procedure ValidateBlobCacheDirectory(Database:TFIBDataBase);
implementation
uses
StrUtil,FIBDataSet,IBBlobFilter,FIBConsts
{$IFDEF D6+}
,Variants, pFIBProps
{$ENDIF}
;
function EquelQUADs(const Value1,Value2:TISC_QUAD):boolean;
begin
Result:=
(Value1.gds_quad_high=Value2.gds_quad_high)
and
(Value1.gds_quad_low=Value2.gds_quad_low)
end;
var
SwapVersion:integer=1;
BlobCacheSignature:string='FIB$BLOB_BODY';
BlobCacheOperation: TRTLCriticalSection;
procedure DoValidateBlobCacheFile(Database:TFIBDataBase; Transaction:TFIBTransaction;const FileName:string);
var
Stream: TStream;
tmpStr:string;
tmpInt:integer;
tmpBlobId:TISC_QUAD;
vFileIsValid:boolean;
begin
vFileIsValid:=False;
EnterCriticalSection(BlobCacheOperation);
try
Stream := TFileStream.Create(FileName, fmOpenRead);
try
Stream.Position := 0;
SetLength(tmpStr,Length(BlobCacheSignature));
Stream.Read(tmpStr[1],Length(BlobCacheSignature));
if tmpStr=BlobCacheSignature then
begin
Stream.Read(tmpInt,SizeOf(tmpInt));
if tmpInt=SwapVersion then
begin
Stream.Read(tmpBlobId,SizeOf(TISC_QUAD));
if not Transaction.DefaultDatabase.Connected then
Transaction.DefaultDatabase.Connected:=True;
if not Transaction.InTransaction then
Transaction.StartTransaction;
vFileIsValid:=
BlobExist(Database.ClientLibrary,
Database.Handle,Transaction.Handle,tmpBlobId
);
end;
end;
finally
Stream.Free;
end;
except
end;
try
if not vFileIsValid then
DeleteFile(FileName);
finally
LeaveCriticalSection(BlobCacheOperation);
end;
end;
procedure DoValidateBlobCacheDirectory(Database:TFIBDataBase; Transaction:TFIBTransaction; const Dir:string);
var
sr: TSearchRec;
FileAttrs: Integer;
begin
FileAttrs:=faAnyFile;
if FindFirst(Dir+'*.blb', FileAttrs, sr) = 0 then
begin
repeat
if (sr.Attr and FileAttrs) = sr.Attr then
begin
DoValidateBlobCacheFile(Database,Transaction,Dir+sr.Name);
end;
until FindNext(sr) <> 0;
FindClose(sr);
end;
FileAttrs:=faDirectory;
if FindFirst(Dir+'*', FileAttrs, sr) = 0 then
begin
repeat
if (sr.Attr and FileAttrs) = sr.Attr then
if (sr.Name<>'.') and (sr.Name<>'..') then
DoValidateBlobCacheDirectory(Database,Transaction,Dir+sr.Name+'\');
until FindNext(sr) <> 0;
FindClose(sr);
end;
end;
type
TValidateBlobCacheThread = class(TThread)
private
FDatabase:TFIBDataBase;
FTransaction:TFIBTransaction;
FCacheDir:string;
protected
procedure Execute; override;
public
constructor Create(Database:TFIBDataBase);
destructor Destroy; override;
end;
{ TValidateBlobCacheThread }
constructor TValidateBlobCacheThread.Create(Database: TFIBDataBase);
begin
FDatabase:=TFIBDatabase.Create(nil);
with FDatabase do
begin
if Database.IsRemoteConnect then
DBName :=Database.DBName
else
DBName :='localhost:'+Database.DBName;
DBParams:=Database.DBParams;
UseLoginPrompt:=False;
SynchronizeTime:=False;
Name:='dbValidateBlobCache';
// Connected:=True;
end;
FTransaction:=TFIBTransaction.Create(nil);
with FTransaction do
begin
DefaultDatabase:=FDatabase;
Name:='trValidateBlobCache';
TRParams.Add('read');
TRParams.Add('isc_tpb_nowait');
TRParams.Add('read_committed');
TRParams.Add('rec_version');
end;
FCacheDir:=Database.BlobSwapSupport.SwapDirectory;
FreeOnTerminate:=True;
inherited Create(False);
end;
destructor TValidateBlobCacheThread.Destroy;
begin
if FTransaction.InTransaction then
FTransaction.Commit;
FTransaction.Free;
FDatabase.Connected:=False;
FDatabase.Free;
inherited Destroy;
end;
procedure TValidateBlobCacheThread.Execute;
begin
DoValidateBlobCacheDirectory(FDatabase,FTransaction,FCacheDir);
end;
procedure ValidateBlobCacheDirectory(Database:TFIBDataBase);
begin
if not Assigned(Database) or not (Database.Connected)
or (Length(Database.BlobSwapSupport.SwapDirectory) = 0)
or not DirectoryExists(Database.BlobSwapSupport.SwapDirectory)
then
Exit;
TValidateBlobCacheThread.Create(Database);
end;
procedure GetBlobInfo(ClientLibrary:IIbClientLibrary; hBlobHandle: PISC_BLOB_HANDLE;
var NumSegments, MaxSegmentSize, TotalSize: Long; var BlobType: Short);
var
items: array[0..3] of Char;
results: array[0..99] of Char;
i, item_length: Integer;
item: Integer;
begin
if not Assigned(ClientLibrary) then
raise
EAPICallException.Create(Format(SUnknownClientLibrary,['GetBlobInfo']));
items[0] := Char(isc_info_blob_num_segments);
items[1] := Char(isc_info_blob_max_segment);
items[2] := Char(isc_info_blob_total_length);
items[3] := Char(isc_info_blob_type);
if ClientLibrary.isc_blob_info(StatusVector, hBlobHandle, 4, @items[0], SizeOf(results),
@results[0]) > 0 then
IBError(ClientLibrary,nil);
i := 0;
while (i < SizeOf(results)) and (results[i] <> Char(isc_info_end)) do
begin
item := Integer(results[i]); Inc(i);
item_length := ClientLibrary.isc_vax_integer(@results[i], 2); Inc(i, 2);
case item of
isc_info_blob_num_segments:
NumSegments := ClientLibrary.isc_vax_integer(@results[i], item_length);
isc_info_blob_max_segment:
MaxSegmentSize := ClientLibrary.isc_vax_integer(@results[i], item_length);
isc_info_blob_total_length:
TotalSize := ClientLibrary.isc_vax_integer(@results[i], item_length);
isc_info_blob_type:
BlobType := ClientLibrary.isc_vax_integer(@results[i], item_length);
end;
Inc(i, item_length);
end;
end;
procedure OldReadBlob(ClientLibrary:IIbClientLibrary; hBlobHandle: PISC_BLOB_HANDLE; var Buffer: PChar;
var BlobSize: Long);
var
BytesRead, SegLen: UShort;
LocalBuffer: PChar;
AllReadBytes:integer;
begin
if not Assigned(ClientLibrary) then
raise
EAPICallException.Create(Format(SUnknownClientLibrary,['ReadBlob']));
LocalBuffer := Buffer;
if BlobSize<DefaultBlobSegmentSize then
SegLen:=BlobSize // 软圜
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -