Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions runtime/nongui/IBDatabase.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,13 @@ constructor TIBTransaction.Create(AOwner: TComponent);
FTimer.Interval := 0;
FTimer.OnTimer := TimeoutTransaction;
FDefaultAction := taCommit;
FTransactionList.Add(self);
{ Guarded the way Destroy's Remove already is. A transaction can be
constructed after this unit has finalized - the LCL frees documents from
Application's async queue during Application.Destroy, and tearing a
data-aware control down there reaches IBX again - and the list is gone by
then. Unguarded, that is an access violation on the way out. }
if Assigned(FTransactionList) then
FTransactionList.Add(self);
if (FTransactionName = '') and (CreateGUID(uuid) = 0) then
FTransactionName := GUIDToString(uuid);
end;
Expand Down Expand Up @@ -2407,10 +2413,18 @@ function TIBDataBase.GenerateDPB(FirebirdAPI: IFirebirdAPI; sl: TStrings): IDPB;
case DPBItem.getParamType of
isc_dpb_user_name, isc_dpb_password, isc_dpb_password_enc,
isc_dpb_sys_user_name, isc_dpb_license, isc_dpb_encrypt_key,
isc_dpb_lc_messages, isc_dpb_lc_ctype, isc_dpb_page_size,
isc_dpb_lc_messages, isc_dpb_lc_ctype,
isc_dpb_sql_role_name:
DPBItem.SetAsString(ParamValue);

{isc_dpb_page_size is an integer parameter, not a string one. Writing it
with SetAsString stores the digits as text, which the clumplet writer
rejects outright once there are more than four of them - so
Params.Values['page_size'] := '16384' failed with "length of integer
exceeds 4 bytes (5)", and only the four-digit sizes appeared to work.}
isc_dpb_page_size:
DPBItem.SetAsInteger(StrToUInt(ParamValue));

isc_dpb_sql_dialect:
begin
if (ParamValue = '') or (ParamValue[1] = '3') then
Expand Down Expand Up @@ -2492,8 +2506,13 @@ function TIBTransaction.GenerateTPB(FirebirdAPI: IFirebirdAPI; sl: TStrings): IT
TIBTransaction.FTransactionList := TList.Create;

Finalization
if assigned(TIBTransaction.FCriticalSection) then TIBTransaction.FCriticalSection.Free;
if assigned(TIBTransaction.FTransactionList) then TIBTransaction.FTransactionList.Free;
{ FreeAndNil rather than Free: these are class vars that outlive the unit's
finalization in the sense that something can still reach them afterwards,
and Free leaves the reference dangling - so the Assigned tests guarding
them stayed true and went on reading released memory. Nil is what makes
those guards mean anything. }
if assigned(TIBTransaction.FCriticalSection) then FreeAndNil(TIBTransaction.FCriticalSection);
if assigned(TIBTransaction.FTransactionList) then FreeAndNil(TIBTransaction.FTransactionList);

end.

Expand Down
25 changes: 24 additions & 1 deletion runtime/nongui/IBXServices.pas
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,17 @@ TIBXBackupRestoreService = class(TIBXControlAndQueryService)
private
FStatisticsRequested: TBackupStatsOptions;
FVerbose: Boolean;
FParallelWorkers: Integer;
protected
procedure SetServiceStartOptions; override;
property Verbose : Boolean read FVerbose write FVerbose default False;
property StatisticsRequested: TBackupStatsOptions read FStatisticsRequested write FStatisticsRequested;
published
{Number of workers the server should use for the backup or restore, as
gbak -par does. Firebird 5 and later; an older server rejects the
parameter, so it is only sent when the server can take it. Zero or one
means the default, single-threaded behaviour.}
property ParallelWorkers: Integer read FParallelWorkers write FParallelWorkers default 0;
end;

TBackupOption = (IgnoreChecksums, IgnoreLimbo, MetadataOnly, NoGarbageCollection,
Expand Down Expand Up @@ -479,8 +485,10 @@ TIBXOnlineValidationService = class(TIBXControlAndQueryService)
property DatabaseName;
end;

{UpgradeODS is appended rather than inserted so that the existing values keep
their ordinals for anything already compiled against this unit.}
TValidateOption = (CheckDB, IgnoreChecksum, KillShadows, MendDB,
SweepDB, ValidateDB, ValidateFull);
SweepDB, ValidateDB, ValidateFull, UpgradeODS);
TValidateOptions = set of TValidateOption;

{ TIBXValidationService }
Expand Down Expand Up @@ -1694,6 +1702,13 @@ procedure TIBXValidationService.SetServiceStartOptions;
if not (MendDB in Options) then
param := param or isc_spb_rpr_validate_db;
end;
{Firebird 5 and later: upgrade the on-disk structure in place, as
gfix -upgrade does, rather than by backup and restore. Only sent to a
server that knows the option, since an older one rejects it.}
if (UpgradeODS in Options) then
with ServicesConnection do
if ServerVersionNo[1] >= 5 then
param := param or isc_spb_rpr_upgrade_db;
if param > 0 then
SRB.Add(isc_spb_options).AsInteger := param;
end;
Expand Down Expand Up @@ -1928,6 +1943,14 @@ procedure TIBXBackupRestoreService.SetServiceStartOptions;
if Verbose then
SRB.Add(isc_spb_verbose);

{Firebird 5 and later. isc_spb_bkp_parallel_workers and
isc_spb_res_parallel_workers are the same parameter code, so one property
serves both directions.}
if FParallelWorkers > 1 then
with ServicesConnection do
if ServerVersionNo[1] >= 5 then
SRB.Add(isc_spb_bkp_parallel_workers).AsInteger := FParallelWorkers;

with ServicesConnection do
{Firebird 2.5.5 and later}
if (ServerVersionNo[1] < 2) or
Expand Down