ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IBServices.pas
Revision: 143
Committed: Fri Feb 23 12:11:21 2018 UTC (6 years, 9 months ago) by tony
Content type: text/x-pascal
File size: 68193 byte(s)
Log Message:
Fixes Merged

File Contents

# User Rev Content
1 tony 33 {************************************************************************}
2     { }
3     { Borland Delphi Visual Component Library }
4     { InterBase Express core components }
5     { }
6     { Copyright (c) 1998-2000 Inprise Corporation }
7     { }
8     { InterBase Express is based in part on the product }
9     { Free IB Components, written by Gregory H. Deatz for }
10     { Hoagland, Longo, Moran, Dunst & Doukas Company. }
11     { Free IB Components is used under license. }
12     { }
13     { The contents of this file are subject to the InterBase }
14     { Public License Version 1.0 (the "License"); you may not }
15     { use this file except in compliance with the License. You }
16     { may obtain a copy of the License at http://www.Inprise.com/IPL.html }
17     { Software distributed under the License is distributed on }
18     { an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either }
19     { express or implied. See the License for the specific language }
20     { governing rights and limitations under the License. }
21     { The Original Code was created by InterBase Software Corporation }
22     { and its successors. }
23     { Portions created by Inprise Corporation are Copyright (C) Inprise }
24     { Corporation. All Rights Reserved. }
25     { Contributor(s): Jeff Overcash }
26     { }
27     { IBX For Lazarus (Firebird Express) }
28     { Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
29     { Portions created by MWA Software are copyright McCallum Whyman }
30 tony 143 { Associates Ltd 2011 - 2018 }
31 tony 33 { }
32     {************************************************************************}
33    
34     {
35     InterBase Express provides component interfaces to
36     functions introduced in InterBase 6.0. The Services
37     components (TIB*Service, TIBServerProperties)
38     function only if you have installed InterBase 6.0 or
39     later software, including Firebird
40     }
41    
42     unit IBServices;
43    
44     {$Mode Delphi}
45 tony 39 {$codepage UTF8}
46 tony 33
47     interface
48    
49     uses
50     {$IFDEF WINDOWS }
51     Windows,
52     {$ELSE}
53     unix,
54     {$ENDIF}
55 tony 139 SysUtils, Classes, IB, IBExternals, CustApp, IBTypes;
56 tony 33
57     const
58     DefaultBufferSize = 32000;
59    
60     SPBPrefix = 'isc_spb_';
61 tony 143 isc_spb_last_spb_constant = 13;
62 tony 33 SPBConstantNames: array[1..isc_spb_last_spb_constant] of String = (
63     'user_name',
64     'sys_user_name',
65     'sys_user_name_enc',
66     'password',
67     'password_enc',
68     'command_line',
69     'db_name',
70     'verbose',
71     'options',
72     'connect_timeout',
73     'dummy_packet_interval',
74 tony 143 'sql_role_name',
75     'expected_db'
76 tony 33 );
77    
78     SPBConstantValues: array[1..isc_spb_last_spb_constant] of Integer = (
79 tony 45 isc_spb_user_name,
80     isc_spb_sys_user_name,
81     isc_spb_sys_user_name_enc,
82     isc_spb_password,
83     isc_spb_password_enc,
84     isc_spb_command_line,
85     isc_spb_dbname,
86     isc_spb_verbose,
87     isc_spb_options,
88     isc_spb_connect_timeout,
89     isc_spb_dummy_packet_interval,
90 tony 143 isc_spb_sql_role_name,
91     isc_spb_expected_db
92 tony 33 );
93    
94     type
95     TOutputBufferOption = (ByLine, ByChunk);
96    
97     TIBCustomService = class;
98    
99 tony 143 TLoginEvent = procedure(Service: TIBCustomService;
100 tony 33 LoginParams: TStrings) of object;
101    
102     { TIBCustomService }
103    
104     TIBCustomService = class(TComponent)
105     private
106     FParamsChanged : Boolean;
107 tony 143 FPortNo: string;
108 tony 45 FSRB: ISRB;
109     FSQPB: ISQPB;
110 tony 33 FTraceFlags: TTraceFlags;
111     FOnLogin: TLoginEvent;
112     FLoginPrompt: Boolean;
113     FServerName: string;
114 tony 45 FService: IServiceManager;
115 tony 33 FStreamedActive : Boolean;
116     FOnAttach: TNotifyEvent;
117     FProtocol: TProtocol;
118     FParams: TStrings;
119 tony 143 FServerVersionNo: array [1..4] of integer;
120 tony 45 FServiceQueryResults: IServiceQueryResults;
121 tony 33 function GetActive: Boolean;
122     function GetServiceParamBySPB(const Idx: Integer): String;
123 tony 45 function GetSQPB: ISQPB;
124     function GetSRB: ISRB;
125 tony 143 function GetServerVersionNo(index: integer): integer;
126 tony 33 procedure SetActive(const Value: Boolean);
127     procedure SetParams(const Value: TStrings);
128     procedure SetServerName(const Value: string);
129     procedure SetProtocol(const Value: TProtocol);
130 tony 45 procedure SetService(AValue: IServiceManager);
131 tony 33 procedure SetServiceParamBySPB(const Idx: Integer;
132     const Value: String);
133 tony 143 function IndexOfSPBConst(action: byte; List: TStrings): Integer;
134 tony 45 function GetSPBConstName(action: byte): string;
135 tony 33 procedure ParamsChange(Sender: TObject);
136     procedure ParamsChanging(Sender: TObject);
137     procedure CheckServerName;
138 tony 45 function GenerateSPB(sl: TStrings): ISPB;
139 tony 33
140     protected
141     procedure Loaded; override;
142 tony 143 function Login(var aServerName: string; LOginParams: TStrings): Boolean;
143 tony 33 procedure CheckActive;
144     procedure CheckInactive;
145     procedure HandleException(Sender: TObject);
146     procedure InternalServiceQuery;
147 tony 45 property SRB: ISRB read GetSRB;
148     property SQPB: ISQPB read GetSQPB;
149     property ServiceQueryResults: IServiceQueryResults read FServiceQueryResults;
150 tony 33
151     public
152     constructor Create(AOwner: TComponent); override;
153     destructor Destroy; override;
154     procedure Attach;
155     procedure Detach;
156 tony 143 procedure Assign(Source: TPersistent); override;
157 tony 80
158     {Copies database parameters as give in the DBParams to the Service
159     omitting any parameters not appropriate for TIBService. Typically, the
160     DBParams are TIBDatabase.Params}
161     procedure SetDBParams(DBParams: TStrings);
162    
163 tony 45 property ServiceIntf: IServiceManager read FService write SetService;
164 tony 33 property ServiceParamBySPB[const Idx: Integer]: String read GetServiceParamBySPB
165     write SetServiceParamBySPB;
166 tony 143 property ServerVersionNo[index: integer]: integer read GetServerVersionNo;
167 tony 33 published
168     property Active: Boolean read GetActive write SetActive default False;
169     property ServerName: string read FServerName write SetServerName;
170     property Protocol: TProtocol read FProtocol write SetProtocol default Local;
171 tony 143 property PortNo: string read FPortNo write FPortNo;
172 tony 33 property Params: TStrings read FParams write SetParams;
173     property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt default True;
174     property TraceFlags: TTraceFlags read FTraceFlags write FTraceFlags;
175     property OnAttach: TNotifyEvent read FOnAttach write FOnAttach;
176     property OnLogin: TLoginEvent read FOnLogin write FOnLogin;
177     end;
178    
179     TDatabaseInfo = class
180     public
181     NoOfAttachments: Integer;
182     NoOfDatabases: Integer;
183     DbName: array of string;
184     constructor Create;
185     destructor Destroy; override;
186     end;
187    
188     TLicenseInfo = class
189     public
190     Key: array of string;
191     Id: array of string;
192     Desc: array of string;
193     LicensedUsers: Integer;
194     constructor Create;
195     destructor Destroy; override;
196     end;
197    
198     TLicenseMaskInfo = class
199     public
200     LicenseMask: Integer;
201     CapabilityMask: Integer;
202     end;
203    
204     TConfigFileData = class
205     public
206     ConfigFileValue: array of integer;
207     ConfigFileKey: array of integer;
208     constructor Create;
209     destructor Destroy; override;
210     end;
211    
212     TConfigParams = class
213     public
214     ConfigFileData: TConfigFileData;
215     ConfigFileParams: array of string;
216     BaseLocation: string;
217     LockFileLocation: string;
218     MessageFileLocation: string;
219     SecurityDatabaseLocation: string;
220     constructor Create;
221     destructor Destroy; override;
222     end;
223    
224     TVersionInfo = class
225     ServerVersion: String;
226     ServerImplementation: string;
227     ServiceVersion: Integer;
228     end;
229    
230     TPropertyOption = (Database, License, LicenseMask, ConfigParameters, Version);
231     TPropertyOptions = set of TPropertyOption;
232    
233     TIBServerProperties = class(TIBCustomService)
234     private
235     FOptions: TPropertyOptions;
236     FDatabaseInfo: TDatabaseInfo;
237     FLicenseInfo: TLicenseInfo;
238     FLicenseMaskInfo: TLicenseMaskInfo;
239     FVersionInfo: TVersionInfo;
240     FConfigParams: TConfigParams;
241     public
242     constructor Create(AOwner: TComponent); override;
243     destructor Destroy; override;
244     procedure Fetch;
245     procedure FetchDatabaseInfo;
246     procedure FetchLicenseInfo;
247     procedure FetchLicenseMaskInfo;
248     procedure FetchConfigParams;
249     procedure FetchVersionInfo;
250     property DatabaseInfo: TDatabaseInfo read FDatabaseInfo;
251     property LicenseInfo: TLicenseInfo read FLicenseInfo;
252     property LicenseMaskInfo: TLicenseMaskInfo read FLicenseMaskInfo;
253     property VersionInfo: TVersionInfo read FVersionInfo;
254     property ConfigParams: TConfigParams read FConfigParams;
255     published
256     property Options : TPropertyOptions read FOptions write FOptions;
257     end;
258    
259 tony 45 { TIBControlService }
260    
261 tony 33 TIBControlService = class (TIBCustomService)
262     private
263     function GetIsServiceRunning: Boolean;
264     protected
265 tony 45 procedure CheckServiceNotRunning;
266     procedure InternalServiceStart;
267 tony 33 procedure SetServiceStartOptions; virtual;
268    
269     public
270     constructor Create(AOwner: TComponent); override;
271     procedure ServiceStart; virtual;
272     property IsServiceRunning : Boolean read GetIsServiceRunning;
273     end;
274    
275 tony 45 { TIBControlAndQueryService }
276    
277 tony 33 TIBControlAndQueryService = class (TIBControlService)
278     private
279     FEof: Boolean;
280     FAction: Integer;
281     procedure SetAction(Value: Integer);
282     protected
283     property Action: Integer read FAction write SetAction;
284     public
285     constructor create (AOwner: TComponent); override;
286     function GetNextLine : String;
287     function GetNextChunk : String;
288 tony 143 procedure ServiceStart; override;
289 tony 45 function WriteNextChunk(stream: TStream): integer;
290 tony 33 property Eof: boolean read FEof;
291     end;
292    
293     TShutdownMode = (Forced, DenyTransaction, DenyAttachment);
294    
295 tony 143 { TIBConfigService }
296    
297 tony 33 TIBConfigService = class(TIBControlService)
298     private
299     FDatabaseName: string;
300     procedure SetDatabaseName(const Value: string);
301     protected
302    
303     public
304     procedure ServiceStart; override;
305     procedure ShutdownDatabase (Options: TShutdownMode; Wait: Integer);
306     procedure SetSweepInterval (Value: Integer);
307     procedure SetDBSqlDialect (Value: Integer);
308     procedure SetPageBuffers (Value: Integer);
309     procedure ActivateShadow;
310     procedure BringDatabaseOnline;
311     procedure SetReserveSpace (Value: Boolean);
312     procedure SetAsyncMode (Value: Boolean);
313     procedure SetReadOnly (Value: Boolean);
314 tony 143 procedure SetAutoAdmin(Value: Boolean);
315     procedure SetNoLinger;
316 tony 33 published
317     property DatabaseName: string read FDatabaseName write SetDatabaseName;
318     end;
319    
320     TIBLogService = class(TIBControlAndQueryService)
321     private
322    
323     protected
324     procedure SetServiceStartOptions; override;
325     public
326     published
327     end;
328    
329 tony 43 TStatOption = (DataPages, {DbLog,} HeaderPages, IndexPages, SystemRelations);
330 tony 33 TStatOptions = set of TStatOption;
331    
332     TIBStatisticalService = class(TIBControlAndQueryService)
333     private
334     FDatabaseName: string;
335     FOptions: TStatOptions;
336     procedure SetDatabaseName(const Value: string);
337     protected
338     procedure SetServiceStartOptions; override;
339     public
340     published
341     property DatabaseName: string read FDatabaseName write SetDatabaseName;
342     property Options : TStatOptions read FOptions write FOptions;
343     end;
344    
345 tony 45 TBackupLocation = (flServerSide,flClientSide);
346 tony 143 TBackupStatsOption = (bsTotalTime,bsTimeDelta,bsPageReads,bsPageWrites);
347     TBackupStatsOptions = set of TBackupStatsOption;
348 tony 33
349 tony 45 { TIBBackupRestoreService }
350    
351 tony 33 TIBBackupRestoreService = class(TIBControlAndQueryService)
352     private
353 tony 45 FBackupFileLocation: TBackupLocation;
354 tony 143 FStatisticsRequested: TBackupStatsOptions;
355 tony 33 FVerbose: Boolean;
356     protected
357 tony 143 procedure SetServiceStartOptions; override;
358 tony 33 public
359 tony 45 constructor Create(AOwner: TComponent); override;
360 tony 33 published
361     property Verbose : Boolean read FVerbose write FVerbose default False;
362 tony 143 property StatisticsRequested: TBackupStatsOptions read FStatisticsRequested write FStatisticsRequested;
363 tony 45 property BackupFileLocation: TBackupLocation read FBackupFileLocation
364     write FBackupFileLocation default flServerSide;
365 tony 33 end;
366    
367     TBackupOption = (IgnoreChecksums, IgnoreLimbo, MetadataOnly, NoGarbageCollection,
368 tony 143 OldMetadataDesc, NonTransportable, ConvertExtTables, NoDBTriggers);
369 tony 33 TBackupOptions = set of TBackupOption;
370    
371     TIBBackupService = class (TIBBackupRestoreService)
372     private
373     FDatabaseName: string;
374     FOptions: TBackupOptions;
375     FBackupFile: TStrings;
376     FBlockingFactor: Integer;
377     procedure SetBackupFile(const Value: TStrings);
378     protected
379     procedure SetServiceStartOptions; override;
380     public
381     constructor Create(AOwner: TComponent); override;
382     destructor Destroy; override;
383    
384     published
385     { a name=value pair of filename and length }
386     property BackupFile: TStrings read FBackupFile write SetBackupFile;
387     property BlockingFactor: Integer read FBlockingFactor write FBlockingFactor;
388     property DatabaseName: string read FDatabaseName write FDatabaseName;
389     property Options : TBackupOptions read FOptions write FOptions;
390     end;
391    
392     TRestoreOption = (DeactivateIndexes, NoShadow, NoValidityCheck, OneRelationAtATime,
393 tony 143 Replace, CreateNewDB, UseAllSpace, RestoreMetaDataOnly);
394 tony 33
395     TRestoreOptions = set of TRestoreOption;
396 tony 45
397     { TIBRestoreService }
398    
399 tony 33 TIBRestoreService = class (TIBBackupRestoreService)
400     private
401     FDatabaseName: TStrings;
402     FBackupFile: TStrings;
403     FOptions: TRestoreOptions;
404     FPageSize: Integer;
405     FPageBuffers: Integer;
406 tony 45 FSendBytes: integer;
407 tony 33 procedure SetBackupFile(const Value: TStrings);
408     procedure SetDatabaseName(const Value: TStrings);
409     protected
410     procedure SetServiceStartOptions; override;
411     public
412     constructor Create(AOwner: TComponent); override;
413     destructor Destroy; override;
414 tony 45 function SendNextChunk(stream: TStream; var line: String): integer;
415 tony 33 published
416     { a name=value pair of filename and length }
417     property DatabaseName: TStrings read FDatabaseName write SetDatabaseName;
418     property BackupFile: TStrings read FBackupFile write SetBackupFile;
419     property PageSize: Integer read FPageSize write FPageSize;
420     property PageBuffers: Integer read FPageBuffers write FPageBuffers;
421     property Options : TRestoreOptions read FOptions write FOptions default [CreateNewDB];
422     end;
423    
424     TValidateOption = (LimboTransactions, CheckDB, IgnoreChecksum, KillShadows, MendDB,
425     SweepDB, ValidateDB, ValidateFull);
426     TValidateOptions = set of TValidateOption;
427    
428     TTransactionGlobalAction = (CommitGlobal, RollbackGlobal, RecoverTwoPhaseGlobal,
429     NoGlobalAction);
430     TTransactionState = (LimboState, CommitState, RollbackState, UnknownState);
431     TTransactionAdvise = (CommitAdvise, RollbackAdvise, UnknownAdvise);
432     TTransactionAction = (CommitAction, RollbackAction);
433    
434     TLimboTransactionInfo = class
435     public
436     MultiDatabase: Boolean;
437     ID: Integer;
438     HostSite: String;
439     RemoteSite: String;
440     RemoteDatabasePath: String;
441     State: TTransactionState;
442     Advise: TTransactionAdvise;
443     Action: TTransactionAction;
444     end;
445    
446     TIBValidationService = class(TIBControlAndQueryService)
447     private
448     FDatabaseName: string;
449     FOptions: TValidateOptions;
450     FLimboTransactionInfo: array of TLimboTransactionInfo;
451     FGlobalAction: TTransactionGlobalAction;
452     procedure SetDatabaseName(const Value: string);
453     function GetLimboTransactionInfo(index: integer): TLimboTransactionInfo;
454     function GetLimboTransactionInfoCount: integer;
455    
456     protected
457     procedure SetServiceStartOptions; override;
458     public
459     constructor Create(AOwner: TComponent); override;
460     destructor Destroy; override;
461     procedure FetchLimboTransactionInfo;
462     procedure FixLimboTransactionErrors;
463     property LimboTransactionInfo[Index: integer]: TLimboTransactionInfo read GetLimboTransactionInfo;
464     property LimboTransactionInfoCount: Integer read GetLimboTransactionInfoCount;
465    
466     published
467     property DatabaseName: string read FDatabaseName write SetDatabaseName;
468     property Options: TValidateOptions read FOptions write FOptions;
469     property GlobalAction: TTransactionGlobalAction read FGlobalAction
470     write FGlobalAction;
471     end;
472    
473 tony 143 { TIBOnlineValidationService }
474    
475     TIBOnlineValidationService = class(TIBControlAndQueryService)
476     private
477     FDatabaseName: string;
478     FExcludeIndexes: string;
479     FExcludeTables: string;
480     FIncludeIndexes: string;
481     FIncludeTables: string;
482     FLockTimeout: integer;
483     procedure SetDatabaseName(AValue: string);
484     protected
485     procedure SetServiceStartOptions; override;
486     public
487     constructor Create(AOwner: TComponent); override;
488     procedure ServiceStart; override;
489     published
490     property IncludeTables: string read FIncludeTables write FIncludeTables;
491     property ExcludeTables: string read FExcludeTables write FExcludeTables;
492     property IncludeIndexes: string read FIncludeIndexes write FIncludeIndexes;
493     property ExcludeIndexes: string read FExcludeIndexes write FExcludeIndexes;
494     property LockTimeout: integer read FLockTimeout write FLockTimeout default 10;
495     property DatabaseName: string read FDatabaseName write SetDatabaseName;
496     end;
497    
498 tony 33 TUserInfo = class
499     public
500     UserName: string;
501     FirstName: string;
502     MiddleName: string;
503     LastName: string;
504     GroupID: Integer;
505     UserID: Integer;
506 tony 143 AdminRole: boolean;
507 tony 33 end;
508    
509     TSecurityAction = (ActionAddUser, ActionDeleteUser, ActionModifyUser, ActionDisplayUser);
510     TSecurityModifyParam = (ModifyFirstName, ModifyMiddleName, ModifyLastName, ModifyUserId,
511 tony 143 ModifyGroupId, ModifyPassword, ModifyAdminRole);
512 tony 33 TSecurityModifyParams = set of TSecurityModifyParam;
513    
514 tony 143 { TIBSecurityService }
515    
516 tony 33 TIBSecurityService = class(TIBControlAndQueryService)
517     private
518 tony 143 FAdminRole: boolean;
519 tony 33 FUserID: Integer;
520     FGroupID: Integer;
521     FFirstName: string;
522     FUserName: string;
523     FPassword: string;
524     FSQLRole: string;
525     FLastName: string;
526     FMiddleName: string;
527     FUserInfo: array of TUserInfo;
528     FSecurityAction: TSecurityAction;
529     FModifyParams: TSecurityModifyParams;
530     procedure ClearParams;
531 tony 143 procedure SetAdminRole(AValue: boolean);
532 tony 33 procedure SetSecurityAction (Value: TSecurityAction);
533     procedure SetFirstName (Value: String);
534     procedure SetMiddleName (Value: String);
535     procedure SetLastName (Value: String);
536     procedure SetPassword (Value: String);
537     procedure SetUserId (Value: Integer);
538     procedure SetGroupId (Value: Integer);
539    
540     procedure FetchUserInfo;
541     function GetUserInfo(Index: Integer): TUserInfo;
542     function GetUserInfoCount: Integer;
543    
544     protected
545     procedure Loaded; override;
546     procedure SetServiceStartOptions; override;
547     public
548     constructor Create(AOwner: TComponent); override;
549     destructor Destroy; override;
550     procedure DisplayUsers;
551     procedure DisplayUser(UserName: string);
552     procedure AddUser;
553     procedure DeleteUser;
554     procedure ModifyUser;
555 tony 143 function HasAdminRole: boolean;
556 tony 33 property UserInfo[Index: Integer]: TUserInfo read GetUserInfo;
557     property UserInfoCount: Integer read GetUserInfoCount;
558    
559     published
560     property SecurityAction: TSecurityAction read FSecurityAction
561     write SetSecurityAction;
562     property SQlRole : string read FSQLRole write FSQLrole;
563     property UserName : string read FUserName write FUserName;
564     property FirstName : string read FFirstName write SetFirstName;
565     property MiddleName : string read FMiddleName write SetMiddleName;
566     property LastName : string read FLastName write SetLastName;
567     property UserID : Integer read FUserID write SetUserID;
568     property GroupID : Integer read FGroupID write SetGroupID;
569     property Password : string read FPassword write setPassword;
570 tony 143 property AdminRole: boolean read FAdminRole write SetAdminRole;
571 tony 33 end;
572    
573    
574     implementation
575    
576     uses
577 tony 143 IBSQLMonitor, FBMessages, RegExpr;
578 tony 33
579 tony 143 { TIBOnlineValidationService }
580    
581     procedure TIBOnlineValidationService.SetDatabaseName(AValue: string);
582     begin
583     if FDatabaseName = AValue then Exit;
584     FDatabaseName := AValue;
585     end;
586    
587     procedure TIBOnlineValidationService.SetServiceStartOptions;
588     begin
589     inherited SetServiceStartOptions;
590     Action := isc_action_svc_validate;
591     if FDatabaseName = '' then
592     IBError(ibxeStartParamsError, [nil]);
593     SRB.Add(isc_action_svc_validate);
594     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
595     if IncludeTables <> '' then
596     SRB.Add(isc_spb_val_tab_incl).AsString := IncludeTables;
597     if ExcludeTables <> '' then
598     SRB.Add(isc_spb_val_tab_excl).AsString := ExcludeTables;
599     if IncludeIndexes <> '' then
600     SRB.Add(isc_spb_val_idx_incl).AsString := IncludeIndexes;
601     if ExcludeIndexes <> '' then
602     SRB.Add(isc_spb_val_idx_excl).AsString := ExcludeIndexes;
603     if LockTimeout <> 0 then
604     SRB.Add(isc_spb_val_lock_timeout).AsInteger := LockTimeout;
605     end;
606    
607     constructor TIBOnlineValidationService.Create(AOwner: TComponent);
608     begin
609     inherited Create(AOwner);
610     FLockTimeout := 10;
611     end;
612    
613     procedure TIBOnlineValidationService.ServiceStart;
614     begin
615     {Firebird 2.5 and later}
616     if (ServerVersionNo[1] < 2) or
617     ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] < 5)) then
618     IBError(ibxeServiceUnavailable,[]);
619     inherited ServiceStart;
620     end;
621    
622 tony 45 { TIBBackupRestoreService }
623    
624 tony 143 procedure TIBBackupRestoreService.SetServiceStartOptions;
625     var options: string;
626     begin
627     {Firebird 2.5 and later}
628     if (ServerVersionNo[1] < 2) or
629     ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] < 5)) then Exit;
630    
631     if StatisticsRequested <> [] then
632     begin
633     options := '';
634     if bsTotalTime in StatisticsRequested then
635     options += 'T';
636     if bsTimeDelta in StatisticsRequested then
637     options += 'D';
638     if bsPageReads in StatisticsRequested then
639     options += 'R';
640     if bsPageWrites in StatisticsRequested then
641     options += 'W';
642     SRB.Add(isc_spb_bkp_stat).AsString := options;
643     end;
644     end;
645    
646 tony 45 constructor TIBBackupRestoreService.Create(AOwner: TComponent);
647     begin
648     inherited Create(AOwner);
649     FBackupFileLocation := flServerSide;
650     end;
651    
652 tony 33 { TIBCustomService }
653    
654     procedure TIBCustomService.Attach;
655 tony 143
656     procedure GetServerVersionNo;
657     var Req: ISRB;
658     Results: IServiceQueryResults;
659     RegexObj: TRegExpr;
660     s: string;
661     begin
662     Req := FService.AllocateSRB;
663     Req.Add(isc_info_svc_server_version);
664     Results := FService.Query(nil,Req);
665     if (Results.Count = 1) and (Results[0].getItemType = isc_info_svc_server_version) then
666     RegexObj := TRegExpr.Create;
667     try
668     {extact database file spec}
669     RegexObj.ModifierG := false; {turn off greedy matches}
670     RegexObj.Expression := '[A-Z][A-Z]-V([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+) .*';
671     s := Results[0].AsString;
672     if RegexObj.Exec(s) then
673     begin
674     FServerVersionNo[1] := StrToInt(system.copy(s,RegexObj.MatchPos[1],RegexObj.MatchLen[1]));
675     FServerVersionNo[2] := StrToInt(system.copy(s,RegexObj.MatchPos[2],RegexObj.MatchLen[2]));
676     FServerVersionNo[3] := StrToInt(system.copy(s,RegexObj.MatchPos[3],RegexObj.MatchLen[3]));
677     FServerVersionNo[4] := StrToInt(system.copy(s,RegexObj.MatchPos[4],RegexObj.MatchLen[4]));
678     end;
679     finally
680     RegexObj.Free;
681     end;
682     end;
683    
684 tony 45 var aServerName: string;
685 tony 143 TempSvcParams: TStrings;
686     SPB: ISPB;
687     PW: ISPBItem;
688 tony 33 begin
689     CheckInactive;
690     CheckServerName;
691    
692 tony 39 aServerName := FServerName;
693 tony 45
694 tony 143 TempSvcParams := TStringList.Create;
695     try
696     TempSvcParams.Assign(FParams);
697     if FLoginPrompt and not Login(aServerName,TempSvcParams) then
698     IBError(ibxeOperationCancelled, [nil]);
699     SPB := GenerateSPB(TempSvcParams);
700     finally
701     TempSvcParams.Free;
702 tony 33 end;
703    
704 tony 143 FService := FirebirdAPI.GetServiceManager(aServerName,PortNo,FProtocol,SPB);
705     PW := FService.getSPB.Find(isc_spb_password);
706     if PW <> nil then PW.AsString := 'xxxxxxxx'; {Hide password}
707 tony 45
708 tony 143 GetServerVersionNo;
709    
710 tony 33 if Assigned(FOnAttach) then
711     FOnAttach(Self);
712    
713     MonitorHook.ServiceAttach(Self);
714     end;
715    
716     procedure TIBCustomService.Loaded;
717     begin
718     inherited Loaded;
719     try
720     if FStreamedActive and (not Active) then
721     Attach;
722     except
723     if csDesigning in ComponentState then
724     HandleException(self)
725     else
726     raise;
727     end;
728     end;
729    
730 tony 143 function TIBCustomService.Login(var aServerName: string; LoginParams: TStrings
731     ): Boolean;
732 tony 33 var
733     IndexOfUser, IndexOfPassword: Integer;
734     Username, Password: String;
735 tony 143 ExtLoginParams: TStrings;
736 tony 33 begin
737     if Assigned(FOnLogin) then begin
738     result := True;
739 tony 143 ExtLoginParams := TStringList.Create;
740 tony 33 try
741 tony 143 ExtLoginParams.Assign(Params);
742     FOnLogin(Self, ExtLoginParams);
743     LoginParams.Assign (ExtLoginParams);
744 tony 39 aServerName := ServerName;
745 tony 33 finally
746 tony 143 ExtLoginParams.Free;
747 tony 33 end;
748     end
749     else
750     if assigned(IBGUIInterface) then
751     begin
752 tony 143 IndexOfUser := LoginParams.IndexOfName(GetSPBConstName(isc_spb_user_name));
753 tony 33 if IndexOfUser <> -1 then
754 tony 143 Username := LoginParams.ValueFromIndex[IndexOfUser]
755     else
756     UserName := '';
757     IndexOfPassword :=LoginParams.IndexOfName(GetSPBConstName(isc_spb_password));
758 tony 33 if IndexOfPassword <> -1 then
759 tony 143 Password := LoginParams.ValueFromIndex[IndexOfPassword]
760     else
761     Password := '';
762    
763 tony 39 result := IBGUIInterface.ServerLoginDialog(aServerName, Username, Password);
764 tony 33 if result then
765     begin
766 tony 143 LoginParams.Values[GetSPBConstName(isc_spb_user_name)] := UserName;
767     LoginParams.Values[GetSPBConstName(isc_spb_password)] := Password;
768 tony 33 end
769     end
770     else
771     IBError(ibxeNoLoginDialog,[]);
772     end;
773    
774     procedure TIBCustomService.CheckActive;
775     begin
776     if FStreamedActive and (not Active) then
777     Loaded;
778 tony 45 if FService = nil then
779 tony 33 IBError(ibxeServiceActive, [nil]);
780     end;
781    
782     procedure TIBCustomService.CheckInactive;
783     begin
784 tony 45 if FService <> nil then
785 tony 33 IBError(ibxeServiceInActive, [nil]);
786     end;
787    
788     procedure TIBCustomService.HandleException(Sender: TObject);
789     var aParent: TComponent;
790     begin
791     aParent := Owner;
792     while aParent <> nil do
793     begin
794     if aParent is TCustomApplication then
795     begin
796     TCustomApplication(aParent).HandleException(Sender);
797     Exit;
798     end;
799     aParent := aParent.Owner;
800     end;
801     SysUtils.ShowException(ExceptObject,ExceptAddr);
802     end;
803    
804     constructor TIBCustomService.Create(AOwner: TComponent);
805     begin
806     inherited Create(AOwner);
807     FserverName := '';
808     FParams := TStringList.Create;
809     FParamsChanged := True;
810     TStringList(FParams).OnChange := ParamsChange;
811     TStringList(FParams).OnChanging := ParamsChanging;
812     FLoginPrompt := True;
813     FTraceFlags := [];
814 tony 45 FService := nil;
815     FSRB := nil;
816     FServiceQueryResults := nil;
817 tony 33 FProtocol := Local;
818     if (AOwner <> nil) and
819     (AOwner is TCustomApplication) and
820     TCustomApplication(AOwner).ConsoleApplication then
821     LoginPrompt := false;
822     end;
823    
824     destructor TIBCustomService.Destroy;
825     begin
826 tony 45 if FService <> nil then
827 tony 33 Detach;
828 tony 45 FSRB := nil;
829     FParams.Free;
830     FServiceQueryResults := nil;
831 tony 33 inherited Destroy;
832     end;
833    
834     procedure TIBCustomService.Detach;
835     begin
836     CheckActive;
837 tony 45 FService := nil;
838 tony 33 MonitorHook.ServiceDetach(Self);
839     end;
840    
841 tony 143 procedure TIBCustomService.Assign(Source: TPersistent);
842     begin
843     if Source = self then Exit;
844     if Source is TIBCustomService then
845     with Source as TIBCustomService do
846     begin
847     self.FService := nil; {Now appears inactive}
848     self.FServerName := FServerName;
849     self.Params.Assign(Params);
850     self.FServerVersionNo := FServerVersionNo;
851     self.FProtocol := FProtocol;
852     self.FLoginPrompt := FLoginPrompt;
853     self.FService := FService;
854     end
855     else
856     inherited Assign(Source);
857     end;
858    
859 tony 80 procedure TIBCustomService.SetDBParams(DBParams: TStrings);
860     var i: integer;
861     j: integer;
862     k: integer;
863     ParamName: string;
864     begin
865     Params.Clear;
866     for i := 0 to DBParams.Count - 1 do
867     begin
868     ParamName := DBParams[i];
869     k := Pos('=',ParamName);
870     if k > 0 then system.Delete(ParamName,k,Length(ParamName)-k+1);
871     for j := 1 to isc_spb_last_spb_constant do
872     if ParamName = SPBConstantNames[j] then
873     begin
874     Params.Add(DBParams[i]);
875     break;
876     end;
877     end;
878     end;
879    
880 tony 33 function TIBCustomService.GetActive: Boolean;
881     begin
882 tony 45 result := FService <> nil;
883 tony 33 end;
884    
885     function TIBCustomService.GetServiceParamBySPB(const Idx: Integer): String;
886     var
887     ConstIdx, EqualsIdx: Integer;
888     begin
889     if (Idx > 0) and (Idx <= isc_spb_last_spb_constant) then
890     begin
891 tony 143 ConstIdx := IndexOfSPBConst(Idx,Params);
892 tony 33 if ConstIdx = -1 then
893     result := ''
894     else
895     begin
896     result := Params[ConstIdx];
897     EqualsIdx := Pos('=', result); {mbcs ok}
898     if EqualsIdx = 0 then
899     result := ''
900     else
901     result := Copy(result, EqualsIdx + 1, Length(result));
902     end;
903     end
904     else
905     result := '';
906     end;
907    
908 tony 45 function TIBCustomService.GetSQPB: ISQPB;
909     begin
910     CheckActive;
911     if FSQPB = nil then
912     FSQPB := FService.AllocateSQPB;
913     Result := FSQPB;
914     end;
915    
916     function TIBCustomService.GetSRB: ISRB;
917     begin
918     CheckActive;
919     if FSRB = nil then
920     FSRB := FService.AllocateSRB;
921     Result := FSRB;
922     end;
923    
924 tony 143 function TIBCustomService.GetServerVersionNo(index: integer): integer;
925     begin
926     CheckActive;
927     if (index >= Low(FServerVersionNo)) and (index <= High(FServerVersionNo)) then
928     Result := FServerVersionNo[index]
929     else
930     IBError(ibxeInfoBufferIndexError,[index]);
931     end;
932    
933 tony 33 procedure TIBCustomService.InternalServiceQuery;
934     begin
935 tony 80 CheckActive;
936 tony 143 try
937     FServiceQueryResults := FService.Query(FSQPB,FSRB);
938     finally
939     FSQPB := nil;
940     FSRB := nil;
941     end;
942 tony 33 MonitorHook.ServiceQuery(Self);
943     end;
944    
945     procedure TIBCustomService.SetActive(const Value: Boolean);
946     begin
947     if csReading in ComponentState then
948     FStreamedActive := Value
949     else
950 tony 143 if Value = Active then Exit;
951    
952     if Value then
953     Attach
954     else
955     Detach;
956 tony 33 end;
957    
958     procedure TIBCustomService.SetParams(const Value: TStrings);
959     begin
960     FParams.Assign(Value);
961     end;
962    
963     procedure TIBCustomService.SetServerName(const Value: string);
964     begin
965     if FServerName <> Value then
966     begin
967     CheckInactive;
968     FServerName := Value;
969     end;
970     end;
971    
972     procedure TIBCustomService.SetProtocol(const Value: TProtocol);
973     begin
974     if FProtocol <> Value then
975     begin
976     CheckInactive;
977     FProtocol := Value;
978     if (Value = Local) then
979     FServerName := '';
980     end;
981     end;
982    
983 tony 45 procedure TIBCustomService.SetService(AValue: IServiceManager);
984     begin
985     if FService = AValue then Exit;
986     FService := AValue;
987     if AValue <> nil then
988     FServerName := FService.getServerName;
989     end;
990    
991 tony 33 procedure TIBCustomService.SetServiceParamBySPB(const Idx: Integer;
992     const Value: String);
993     var
994     ConstIdx: Integer;
995     begin
996 tony 143 ConstIdx := IndexOfSPBConst(Idx,Params);
997 tony 33 if (Value = '') then
998     begin
999     if ConstIdx <> -1 then
1000     Params.Delete(ConstIdx);
1001     end
1002     else
1003     begin
1004     if (ConstIdx = -1) then
1005 tony 45 Params.Add(GetSPBConstName(Idx) + '=' + Value)
1006 tony 33 else
1007 tony 45 Params[ConstIdx] := GetSPBConstName(Idx) + '=' + Value;
1008 tony 33 end;
1009     end;
1010    
1011 tony 143 function TIBCustomService.IndexOfSPBConst(action: byte; List: TStrings): Integer;
1012 tony 33 var
1013 tony 45 i, pos_of_str: Integer;
1014     st: string;
1015 tony 33 begin
1016     result := -1;
1017 tony 45 st := GetSPBConstName(action);
1018     if st <> '' then
1019 tony 143 for i := 0 to List.Count - 1 do
1020 tony 33 begin
1021 tony 143 pos_of_str := Pos(st, List[i]); {mbcs ok}
1022 tony 33 if (pos_of_str = 1) or (pos_of_str = Length(SPBPrefix) + 1) then
1023     begin
1024     result := i;
1025     break;
1026     end;
1027     end;
1028     end;
1029    
1030 tony 45 function TIBCustomService.GetSPBConstName(action: byte): string;
1031     var i: integer;
1032     begin
1033     Result := '';
1034     for i := Low(SPBConstantValues) to High(SPBConstantValues) do
1035     if SPBConstantValues[i] = action then
1036     begin
1037     Result := SPBConstantNames[i];
1038     break;
1039     end;
1040     end;
1041    
1042 tony 33 procedure TIBCustomService.ParamsChange(Sender: TObject);
1043     begin
1044     FParamsChanged := True;
1045     end;
1046    
1047     procedure TIBCustomService.ParamsChanging(Sender: TObject);
1048     begin
1049     CheckInactive;
1050     end;
1051    
1052     procedure TIBCustomService.CheckServerName;
1053     begin
1054     if (FServerName = '') and (FProtocol <> Local) then
1055     IBError(ibxeServerNameMissing, [nil]);
1056     end;
1057    
1058     {
1059     * GenerateSPB -
1060     * Given a string containing a textual representation
1061     * of the Service parameters, generate a service
1062 tony 45 * parameter buffer, and return it .
1063 tony 33 }
1064 tony 45 function TIBCustomService.GenerateSPB(sl: TStrings): ISPB;
1065 tony 33 var
1066 tony 143 i, j, SPBServerVal: UShort;
1067 tony 33 param_name, param_value: String;
1068     begin
1069     { The SPB is initially empty, with the exception that
1070     the SPB version must be the first byte of the string.
1071     }
1072 tony 45 Result := FirebirdAPI.AllocateSPB;
1073    
1074 tony 33 { Iterate through the textual service parameters, constructing
1075     a SPB on-the-fly }
1076     if sl.Count > 0 then
1077     for i := 0 to sl.Count - 1 do
1078     begin
1079     { Get the parameter's name and value from the list,
1080     and make sure that the name is all lowercase with
1081     no leading 'isc_spb_' prefix }
1082     if (Trim(sl.Names[i]) = '') then continue;
1083     param_name := LowerCase(sl.Names[i]); {mbcs ok}
1084     param_value := Copy(sl[i], Pos('=', sl[i]) + 1, Length(sl[i])); {mbcs ok}
1085     if (Pos(SPBPrefix, param_name) = 1) then {mbcs ok}
1086     Delete(param_name, 1, Length(SPBPrefix));
1087     { We want to translate the parameter name to some integer
1088     value. We do this by scanning through a list of known
1089     service parameter names (SPBConstantNames, defined above). }
1090     SPBServerVal := 0;
1091     { Find the parameter }
1092     for j := 1 to isc_spb_last_spb_constant do
1093     if (param_name = SPBConstantNames[j]) then
1094     begin
1095     SPBServerVal := SPBConstantValues[j];
1096     break;
1097     end;
1098 tony 45 case SPBServerVal of
1099 tony 143 isc_spb_user_name,
1100     isc_spb_password,
1101     isc_spb_sql_role_name,
1102     isc_spb_expected_db:
1103 tony 45 Result.Add(SPBServerVal).AsString := param_value;
1104 tony 33 else
1105     begin
1106 tony 45 if GetSPBConstName(SPBServerVal) <> '' then
1107 tony 33 IBError(ibxeSPBConstantNotSupported,
1108 tony 45 [GetSPBConstName(SPBServerVal)])
1109 tony 33 else
1110 tony 45 IBError(ibxeSPBConstantUnknown, [SPBServerVal]);
1111 tony 33 end;
1112     end;
1113     end;
1114     end;
1115    
1116     { TIBServerProperties }
1117     constructor TIBServerProperties.Create(AOwner: TComponent);
1118     begin
1119     inherited Create(AOwner);
1120     FDatabaseInfo := TDatabaseInfo.Create;
1121     FLicenseInfo := TLicenseInfo.Create;
1122     FLicenseMaskInfo := TLicenseMaskInfo.Create;
1123     FVersionInfo := TVersionInfo.Create;
1124     FConfigParams := TConfigParams.Create;
1125     end;
1126    
1127     destructor TIBServerProperties.Destroy;
1128     begin
1129     FDatabaseInfo.Free;
1130     FLicenseInfo.Free;
1131     FLicenseMaskInfo.Free;
1132     FVersionInfo.Free;
1133     FConfigParams.Free;
1134     inherited Destroy;
1135     end;
1136    
1137     procedure TIBServerProperties.Fetch;
1138     begin
1139     if (Database in Options) then
1140     FetchDatabaseInfo;
1141     if (License in Options) then
1142     FetchLicenseInfo;
1143     if (LicenseMask in Options) then
1144     FetchLicenseMaskInfo;
1145     if (ConfigParameters in Options) then
1146     FetchConfigParams;
1147     if (Version in Options) then
1148     FetchVersionInfo;
1149     end;
1150    
1151     procedure TIBServerProperties.FetchConfigParams;
1152     var
1153 tony 45 i, j: Integer;
1154 tony 33
1155     begin
1156 tony 45 SRB.Add(isc_info_svc_get_config);
1157     SRB.Add(isc_info_svc_get_env);
1158     SRB.Add(isc_info_svc_get_env_lock);
1159     SRB.Add(isc_info_svc_get_env_msg);
1160     SRB.Add(isc_info_svc_user_dbpath);
1161 tony 33
1162     InternalServiceQuery;
1163 tony 45
1164     for i := 0 to FServiceQueryResults.Count - 1 do
1165     with FServiceQueryResults[i] do
1166 tony 33 begin
1167 tony 45 case getItemType of
1168 tony 33 isc_info_svc_get_config:
1169     begin
1170 tony 45 SetLength (FConfigParams.ConfigFileData.ConfigFileValue, Count);
1171     SetLength (FConfigParams.ConfigFileData.ConfigFileKey, Count);
1172    
1173     for j := 0 to Count - 1 do
1174     begin
1175 tony 80 FConfigParams.ConfigFileData.ConfigFileKey[j] := Items[j].getItemType;
1176     FConfigParams.ConfigFileData.ConfigFileValue[j] := Items[j].AsInteger;
1177 tony 45 end;
1178 tony 33 end;
1179    
1180     isc_info_svc_get_env:
1181 tony 45 FConfigParams.BaseLocation := AsString;
1182 tony 33
1183     isc_info_svc_get_env_lock:
1184 tony 45 FConfigParams.LockFileLocation := AsString;
1185 tony 33
1186     isc_info_svc_get_env_msg:
1187 tony 45 FConfigParams.MessageFileLocation := AsString;
1188 tony 33
1189     isc_info_svc_user_dbpath:
1190 tony 45 FConfigParams.SecurityDatabaseLocation := AsString;
1191    
1192 tony 33 else
1193 tony 45 IBError(ibxeOutputParsingError, [getItemType]);
1194 tony 33 end;
1195     end;
1196     end;
1197    
1198     procedure TIBServerProperties.FetchDatabaseInfo;
1199     var
1200 tony 45 i,j: Integer;
1201 tony 33 begin
1202 tony 45 SRB.Add(isc_info_svc_svr_db_info);
1203 tony 33 InternalServiceQuery;
1204 tony 45
1205     SetLength(FDatabaseInfo.DbName,0);
1206     for i := 0 to FServiceQueryResults.Count - 1 do
1207     with FServiceQueryResults[i] do
1208 tony 33 begin
1209 tony 45 case getItemType of
1210     isc_info_svc_svr_db_info:
1211     for j := 0 to FServiceQueryResults[i].Count - 1 do
1212     with FServiceQueryResults[i][j] do
1213     case getItemType of
1214     isc_spb_num_att:
1215     FDatabaseInfo.NoOfAttachments := AsInteger;
1216    
1217     isc_spb_num_db:
1218     FDatabaseInfo.NoOfDatabases := AsInteger;
1219    
1220     isc_spb_dbname:
1221     begin
1222     SetLength(FDatabaseInfo.DbName,length(FDatabaseInfo.DbName)+1);
1223     FDatabaseInfo.DbName[length(FDatabaseInfo.DbName)-1] := AsString;
1224     end;
1225     else
1226     IBError(ibxeOutputParsingError, [getItemType]);
1227     end;
1228     else
1229     IBError(ibxeOutputParsingError, [getItemType]);
1230     end;
1231     end;
1232 tony 33 end;
1233    
1234     procedure TIBServerProperties.FetchLicenseInfo;
1235     var
1236 tony 45 i,j : Integer;
1237 tony 33 begin
1238 tony 45 SRB.Add(isc_info_svc_get_license);
1239     SRB.Add(isc_info_svc_get_licensed_users);
1240 tony 33 InternalServiceQuery;
1241    
1242 tony 45 SetLength(FLicenseInfo.key, 0);
1243     SetLength(FLicenseInfo.id, 0);
1244     SetLength(FLicenseInfo.desc, 0);
1245    
1246     for i := 0 to FServiceQueryResults.Count - 1 do
1247     with FServiceQueryResults[i] do
1248     begin
1249     case getItemType of
1250 tony 33 isc_info_svc_get_license:
1251     begin
1252 tony 45 SetLength(FLicenseInfo.key, Count);
1253     SetLength(FLicenseInfo.id, Count);
1254     SetLength(FLicenseInfo.desc, Count);
1255    
1256     for j := 0 to Count -1 do
1257     with Items[j] do
1258     case getItemType of
1259     isc_spb_lic_id:
1260     FLicenseInfo.id[j] := AsString;
1261    
1262     isc_spb_lic_key:
1263     FLicenseInfo.key[j] := AsString;
1264    
1265     isc_spb_lic_desc:
1266     FLicenseInfo.desc[j] := AsString;
1267     else
1268     IBError(ibxeOutputParsingError, [getItemType]);
1269 tony 33 end;
1270     end;
1271     else
1272 tony 45 IBError(ibxeOutputParsingError, [getItemType]);
1273 tony 33 end;
1274     end;
1275     end;
1276    
1277     procedure TIBServerProperties.FetchLicenseMaskInfo();
1278     var
1279 tony 45 i : Integer;
1280 tony 33 begin
1281 tony 45 SRB.Add(isc_info_svc_get_license_mask);
1282     SRB.Add(isc_info_svc_capabilities);
1283 tony 33 InternalServiceQuery;
1284 tony 45
1285     for i := 0 to FServiceQueryResults.Count - 1 do
1286     with FServiceQueryResults[i] do
1287 tony 33 begin
1288 tony 45 case getItemType of
1289 tony 33 isc_info_svc_get_license_mask:
1290 tony 45 FLicenseMaskInfo.LicenseMask := AsInteger;
1291 tony 33 isc_info_svc_capabilities:
1292 tony 45 FLicenseMaskInfo.CapabilityMask := AsInteger;
1293 tony 33 else
1294 tony 45 IBError(ibxeOutputParsingError, [getItemType]);
1295 tony 33 end;
1296     end;
1297     end;
1298    
1299    
1300     procedure TIBServerProperties.FetchVersionInfo;
1301     var
1302 tony 45 i : Integer;
1303 tony 33 begin
1304 tony 45 SRB.Add(isc_info_svc_version);
1305     SRB.Add(isc_info_svc_server_version);
1306     SRB.Add(isc_info_svc_implementation);
1307 tony 33 InternalServiceQuery;
1308    
1309 tony 45 for i := 0 to FServiceQueryResults.Count - 1 do
1310     with FServiceQueryResults[i] do
1311 tony 33 begin
1312 tony 45 case getItemType of
1313 tony 33 isc_info_svc_version:
1314 tony 45 FVersionInfo.ServiceVersion := AsInteger;
1315 tony 33 isc_info_svc_server_version:
1316 tony 45 FVersionInfo.ServerVersion := AsString;
1317 tony 33 isc_info_svc_implementation:
1318 tony 45 FVersionInfo.ServerImplementation := AsString;
1319 tony 33 else
1320 tony 45 IBError(ibxeOutputParsingError, [getItemType]);
1321 tony 33 end;
1322     end;
1323     end;
1324    
1325     { TIBControlService }
1326 tony 45
1327 tony 33 procedure TIBControlService.SetServiceStartOptions;
1328     begin
1329    
1330     end;
1331    
1332     function TIBControlService.GetIsServiceRunning: Boolean;
1333     begin
1334 tony 45 SRB.Add(isc_info_svc_running);
1335 tony 33 InternalServiceQuery;
1336    
1337 tony 45 Result := (FServiceQueryResults.Count > 0) and
1338     (FServiceQueryResults[0].getItemType = isc_info_svc_running) and
1339     (FServiceQueryResults[0].AsInteger = 1);
1340 tony 33 end;
1341    
1342 tony 45 procedure TIBControlService.CheckServiceNotRunning;
1343 tony 33 begin
1344 tony 45 if IsServiceRunning then
1345     IBError(ibxeServiceRunning,[nil]);
1346 tony 33 end;
1347    
1348     constructor TIBControlService.Create(AOwner: TComponent);
1349     begin
1350     inherited create(AOwner);
1351 tony 45 FSRB := nil;
1352 tony 33 end;
1353    
1354     procedure TIBControlService.InternalServiceStart;
1355     begin
1356 tony 45 if SRB = nil then
1357 tony 33 IBError(ibxeStartParamsError, [nil]);
1358 tony 45
1359 tony 33 try
1360 tony 45 FService.Start(SRB);
1361 tony 33 finally
1362 tony 45 FSRB := nil;
1363 tony 33 end;
1364     MonitorHook.ServiceStart(Self);
1365     end;
1366    
1367     procedure TIBControlService.ServiceStart;
1368     begin
1369     CheckActive;
1370 tony 45 CheckServiceNotRunning;
1371 tony 33 SetServiceStartOptions;
1372     InternalServiceStart;
1373     end;
1374    
1375     { TIBConfigService }
1376    
1377     procedure TIBConfigService.ServiceStart;
1378     begin
1379     IBError(ibxeUseSpecificProcedures, [nil]);
1380     end;
1381    
1382     procedure TIBConfigService.ActivateShadow;
1383     begin
1384 tony 45 SRB.Add(isc_action_svc_properties);
1385     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1386     SRB.Add(isc_spb_options).AsInteger := isc_spb_prp_activate;
1387 tony 33 InternalServiceStart;
1388     end;
1389    
1390     procedure TIBConfigService.BringDatabaseOnline;
1391     begin
1392 tony 45 SRB.Add(isc_action_svc_properties);
1393     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1394     SRB.Add(isc_spb_options).AsInteger := isc_spb_prp_db_online;
1395 tony 33 InternalServiceStart;
1396     end;
1397    
1398     procedure TIBConfigService.SetAsyncMode(Value: Boolean);
1399     begin
1400 tony 45 SRB.Add(isc_action_svc_properties);
1401     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1402     with SRB.Add(isc_spb_prp_write_mode) do
1403 tony 33 if Value then
1404 tony 80 AsByte := isc_spb_prp_wm_async
1405 tony 33 else
1406 tony 80 AsByte := isc_spb_prp_wm_sync;
1407 tony 33 InternalServiceStart;
1408     end;
1409    
1410     procedure TIBConfigService.SetDatabaseName(const Value: string);
1411     begin
1412     FDatabaseName := Value;
1413     end;
1414    
1415     procedure TIBConfigService.SetPageBuffers(Value: Integer);
1416     begin
1417 tony 45 SRB.Add(isc_action_svc_properties);
1418     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1419     SRB.Add(isc_spb_prp_page_buffers).AsInteger := Value;
1420 tony 33 InternalServiceStart;
1421     end;
1422    
1423     procedure TIBConfigService.SetReadOnly(Value: Boolean);
1424     begin
1425 tony 45 SRB.Add(isc_action_svc_properties);
1426     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1427     with SRB.Add(isc_spb_prp_access_mode) do
1428 tony 33 if Value then
1429 tony 80 AsByte := isc_spb_prp_am_readonly
1430 tony 33 else
1431 tony 80 AsByte := isc_spb_prp_am_readwrite;
1432 tony 33 InternalServiceStart;
1433     end;
1434    
1435 tony 143 procedure TIBConfigService.SetAutoAdmin(Value: Boolean);
1436     begin
1437     {only available for Firebird 2.5 and later}
1438     if (ServerVersionNo[1] < 2) or
1439     ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] < 5)) then Exit;
1440     if Value then
1441     SRB.Add(isc_action_svc_set_mapping)
1442     else
1443     SRB.Add(isc_action_svc_drop_mapping);
1444     InternalServiceStart;
1445     end;
1446    
1447     procedure TIBConfigService.SetNoLinger;
1448     begin
1449     SRB.Add(isc_action_svc_properties);
1450     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1451     SRB.Add(isc_spb_options).AsInteger := isc_spb_prp_nolinger;
1452     InternalServiceStart;
1453     end;
1454    
1455 tony 33 procedure TIBConfigService.SetReserveSpace(Value: Boolean);
1456     begin
1457 tony 45 SRB.Add(isc_action_svc_properties);
1458     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1459     with SRB.Add(isc_spb_prp_reserve_space) do
1460 tony 33 if Value then
1461 tony 80 AsByte := isc_spb_prp_res
1462 tony 33 else
1463 tony 80 AsByte := isc_spb_prp_res_use_full;
1464 tony 33 InternalServiceStart;
1465     end;
1466    
1467     procedure TIBConfigService.SetSweepInterval(Value: Integer);
1468     begin
1469 tony 45 SRB.Add(isc_action_svc_properties);
1470     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1471     SRB.Add(isc_spb_prp_sweep_interval).AsInteger := Value;
1472 tony 33 InternalServiceStart;
1473     end;
1474    
1475     procedure TIBConfigService.SetDBSqlDialect(Value: Integer);
1476     begin
1477 tony 45 SRB.Add(isc_action_svc_properties);
1478     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1479     SRB.Add(isc_spb_prp_set_sql_dialect).AsInteger := Value;
1480 tony 33 InternalServiceStart;
1481     end;
1482    
1483     procedure TIBConfigService.ShutdownDatabase(Options: TShutdownMode;
1484     Wait: Integer);
1485     begin
1486 tony 45 SRB.Add(isc_action_svc_properties);
1487     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1488 tony 33 if (Options = Forced) then
1489 tony 45 SRB.Add(isc_spb_prp_shutdown_db).AsInteger := Wait
1490 tony 33 else if (Options = DenyTransaction) then
1491 tony 45 SRB.Add(isc_spb_prp_deny_new_transactions).AsInteger := Wait
1492 tony 33 else
1493 tony 45 SRB.Add(isc_spb_prp_deny_new_attachments).AsInteger := Wait;
1494 tony 33 InternalServiceStart;
1495     end;
1496    
1497 tony 45
1498 tony 33 { TIBStatisticalService }
1499    
1500     procedure TIBStatisticalService.SetDatabaseName(const Value: string);
1501     begin
1502     FDatabaseName := Value;
1503     end;
1504    
1505     procedure TIBStatisticalService.SetServiceStartOptions;
1506 tony 45 var param: integer;
1507 tony 33 begin
1508     if FDatabaseName = '' then
1509     IBError(ibxeStartParamsError, [nil]);
1510 tony 45
1511 tony 33 param := 0;
1512     if (DataPages in Options) then
1513     param := param or isc_spb_sts_data_pages;
1514 tony 43 { if (DbLog in Options) then
1515     param := param or isc_spb_sts_db_log; -- removed from Firebird 2}
1516 tony 33 if (HeaderPages in Options) then
1517     param := param or isc_spb_sts_hdr_pages;
1518     if (IndexPages in Options) then
1519     param := param or isc_spb_sts_idx_pages;
1520     if (SystemRelations in Options) then
1521     param := param or isc_spb_sts_sys_relations;
1522     Action := isc_action_svc_db_stats;
1523 tony 45 SRB.Add(isc_action_svc_db_stats);
1524     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1525     SRB.Add(isc_spb_options).AsInteger := param;
1526 tony 33 end;
1527    
1528     { TIBBackupService }
1529     procedure TIBBackupService.SetServiceStartOptions;
1530     var
1531     param, i: Integer;
1532     value: String;
1533     begin
1534     if FDatabaseName = '' then
1535     IBError(ibxeStartParamsError, [nil]);
1536     param := 0;
1537     if (IgnoreChecksums in Options) then
1538     param := param or isc_spb_bkp_ignore_checksums;
1539     if (IgnoreLimbo in Options) then
1540     param := param or isc_spb_bkp_ignore_limbo;
1541     if (MetadataOnly in Options) then
1542     param := param or isc_spb_bkp_metadata_only;
1543     if (NoGarbageCollection in Options) then
1544     param := param or isc_spb_bkp_no_garbage_collect;
1545     if (OldMetadataDesc in Options) then
1546     param := param or isc_spb_bkp_old_descriptions;
1547     if (NonTransportable in Options) then
1548     param := param or isc_spb_bkp_non_transportable;
1549     if (ConvertExtTables in Options) then
1550     param := param or isc_spb_bkp_convert;
1551 tony 143 {Firebird 2.5 and later}
1552     if (ServerVersionNo[1] > 2) or
1553     ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] = 5)) then
1554     begin
1555     if (NoDBTriggers in Options) then
1556     param := param or isc_spb_bkp_no_triggers;
1557     end;
1558 tony 33 Action := isc_action_svc_backup;
1559 tony 45 SRB.Add(isc_action_svc_backup);
1560     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1561     SRB.Add(isc_spb_options).AsInteger := param;
1562     if Verbose and (BackupFileLocation = flServerSide) then
1563 tony 143 begin
1564 tony 45 SRB.Add(isc_spb_verbose);
1565 tony 143 inherited SetServiceStartOptions;
1566     end;
1567 tony 33 if FBlockingFactor > 0 then
1568 tony 45 SRB.Add(isc_spb_bkp_factor).AsInteger := FBlockingFactor;
1569     if BackupFileLocation = flServerSide then
1570 tony 33 for i := 0 to FBackupFile.Count - 1 do
1571     begin
1572     if (Trim(FBackupFile[i]) = '') then
1573     continue;
1574     if (Pos('=', FBackupFile[i]) <> 0) then
1575     begin {mbcs ok}
1576 tony 45 SRB.Add(isc_spb_bkp_file).AsString := FBackupFile.Names[i];
1577 tony 33 value := Copy(FBackupFile[i], Pos('=', FBackupFile[i]) + 1, Length(FBackupFile.Names[i])); {mbcs ok}
1578 tony 45 SRB.Add(isc_spb_bkp_length).AsInteger := StrToInt(value);;
1579 tony 33 end
1580     else
1581 tony 45 SRB.Add(isc_spb_bkp_file).AsString := FBackupFile[i];
1582     end
1583     else
1584     SRB.Add(isc_spb_bkp_file).AsString := 'stdout';
1585 tony 33 end;
1586    
1587     constructor TIBBackupService.Create(AOwner: TComponent);
1588     begin
1589     inherited Create(AOwner);
1590     FBackupFile := TStringList.Create;
1591     end;
1592    
1593     destructor TIBBackupService.Destroy;
1594     begin
1595     FBackupFile.Free;
1596     inherited Destroy;
1597     end;
1598    
1599     procedure TIBBackupService.SetBackupFile(const Value: TStrings);
1600     begin
1601     FBackupFile.Assign(Value);
1602     end;
1603    
1604     { TIBRestoreService }
1605    
1606     procedure TIBRestoreService.SetServiceStartOptions;
1607     var
1608     param, i: Integer;
1609     value: String;
1610     begin
1611     param := 0;
1612     if (DeactivateIndexes in Options) then
1613     param := param or isc_spb_res_deactivate_idx;
1614     if (NoShadow in Options) then
1615     param := param or isc_spb_res_no_shadow;
1616     if (NoValidityCheck in Options) then
1617     param := param or isc_spb_res_no_validity;
1618     if (OneRelationAtATime in Options) then
1619     param := param or isc_spb_res_one_at_a_time;
1620     if (Replace in Options) then
1621     param := param or isc_spb_res_replace;
1622     if (CreateNewDB in Options) then
1623     param := param or isc_spb_res_create;
1624     if (UseAllSpace in Options) then
1625     param := param or isc_spb_res_use_all_space;
1626 tony 143 if (RestoreMetaDataOnly in Options) then
1627     param := param or isc_spb_res_metadata_only;
1628 tony 33 Action := isc_action_svc_restore;
1629 tony 45 SRB.Add(isc_action_svc_restore);
1630     SRB.Add(isc_spb_options).AsInteger := param;
1631     if Verbose then
1632 tony 143 begin
1633 tony 45 SRB.Add(isc_spb_verbose);
1634 tony 143 inherited SetServiceStartOptions;
1635     end;
1636 tony 33 if FPageSize > 0 then
1637 tony 45 SRB.Add(isc_spb_res_page_size).AsInteger := FPageSize;
1638 tony 33 if FPageBuffers > 0 then
1639 tony 45 SRB.Add(isc_spb_res_buffers).AsInteger := FPageBuffers;
1640     if BackupFileLocation = flServerSide then
1641 tony 33 for i := 0 to FBackupFile.Count - 1 do
1642     begin
1643     if (Trim(FBackupFile[i]) = '') then continue;
1644     if (Pos('=', FBackupFile[i]) <> 0) then {mbcs ok}
1645     begin
1646 tony 45 SRB.Add(isc_spb_bkp_file).AsString := FBackupFile.Names[i];
1647 tony 33 value := Copy(FBackupFile[i], Pos('=', FBackupFile[i]) + 1, Length(FBackupFile.Names[i])); {mbcs ok}
1648 tony 45 SRB.Add(isc_spb_bkp_length).AsInteger := StrToInt(value);;
1649 tony 33 end
1650     else
1651 tony 45 SRB.Add(isc_spb_bkp_file).AsString := FBackupFile[i];
1652     end
1653     else
1654     SRB.Add(isc_spb_bkp_file).AsString := 'stdin';
1655    
1656 tony 33 for i := 0 to FDatabaseName.Count - 1 do
1657     begin
1658     if (Trim(FDatabaseName[i]) = '') then continue;
1659     if (Pos('=', FDatabaseName[i]) <> 0) then {mbcs ok}
1660 tony 45 begin
1661     SRB.Add(isc_spb_dbname).AsString := FDatabaseName.Names[i];
1662 tony 33 value := Copy(FDatabaseName[i], Pos('=', FDatabaseName[i]) + 1, Length(FDatabaseName[i])); {mbcs ok}
1663 tony 45 SRB.Add(isc_spb_res_length).AsInteger := StrToInt(value);
1664 tony 33 end
1665     else
1666 tony 45 SRB.Add(isc_spb_dbname).AsString := FDatabaseName[i];
1667 tony 33 end;
1668     end;
1669    
1670     constructor TIBRestoreService.Create(AOwner: TComponent);
1671     begin
1672     inherited Create(AOwner);
1673     FDatabaseName := TStringList.Create;
1674     FBackupFile := TStringList.Create;
1675     Include (FOptions, CreateNewDB);
1676     end;
1677    
1678     destructor TIBRestoreService.Destroy;
1679     begin
1680     FDatabaseName.Free;
1681     FBackupFile.Free;
1682     inherited Destroy;
1683     end;
1684    
1685 tony 45 function TIBRestoreService.SendNextChunk(stream: TStream; var line: String
1686     ): integer;
1687     var
1688     i: Integer;
1689     begin
1690     Result := 0;
1691     line := '';
1692     if (FEof = True) then
1693     exit;
1694    
1695     if (FAction = 0) then
1696     IBError(ibxeQueryParamsError, [nil]);
1697    
1698     SRB.Add(isc_info_svc_line);
1699     SRB.Add(isc_info_svc_stdin);
1700    
1701     SQPB.Add(isc_info_svc_timeout).AsInteger := 1;
1702     if FSendBytes > 0 then
1703     Result := SQPB.Add(isc_info_svc_line).CopyFrom(stream,FSendBytes);
1704 tony 143 try
1705     InternalServiceQuery;
1706     except
1707     FSendBytes := 0;
1708     raise;
1709     end;
1710 tony 45
1711     FSendBytes := 0;
1712     for i := 0 to FServiceQueryResults.Count - 1 do
1713     with FServiceQueryResults[i] do
1714     begin
1715     case getItemType of
1716     isc_info_svc_line:
1717     line := AsString;
1718    
1719     isc_info_svc_stdin:
1720     FSendBytes := AsInteger;
1721    
1722     isc_info_svc_timeout,
1723     isc_info_data_not_ready:
1724     {ignore};
1725     else
1726     IBError(ibxeOutputParsingError, [getItemType]);
1727     end;
1728     end;
1729     FEOF := (FSendBytes = 0) and (line = '');
1730     end;
1731    
1732 tony 33 procedure TIBRestoreService.SetBackupFile(const Value: TStrings);
1733     begin
1734     FBackupFile.Assign(Value);
1735     end;
1736    
1737     procedure TIBRestoreService.SetDatabaseName(const Value: TStrings);
1738     begin
1739     FDatabaseName.Assign(Value);
1740     end;
1741    
1742     { TIBValidationService }
1743     constructor TIBValidationService.Create(AOwner: TComponent);
1744     begin
1745     inherited Create(AOwner);
1746     end;
1747    
1748     destructor TIBValidationService.Destroy;
1749     var
1750     i : Integer;
1751     begin
1752     for i := 0 to High(FLimboTransactionInfo) do
1753     FLimboTransactionInfo[i].Free;
1754     FLimboTransactionInfo := nil;
1755     inherited Destroy;
1756     end;
1757    
1758     procedure TIBValidationService.FetchLimboTransactionInfo;
1759 tony 45
1760     procedure NextLimboTransaction(index: integer);
1761     begin
1762     SetLength(FLimboTransactionInfo, index+1);
1763     FLimboTransactionInfo[index] := TLimboTransactionInfo.Create;
1764     { if no advice commit as default }
1765     FLimboTransactionInfo[index].Advise := UnknownAdvise;
1766     FLimboTransactionInfo[index].Action:= CommitAction;
1767     end;
1768    
1769 tony 33 var
1770 tony 45 i,j, k: Integer;
1771 tony 33 begin
1772     for i := 0 to High(FLimboTransactionInfo) do
1773     FLimboTransactionInfo[i].Free;
1774 tony 45 SetLength(FLimboTransactionInfo,0);
1775    
1776     SRB.Add(isc_info_svc_limbo_trans);
1777     InternalServiceQuery;
1778    
1779     k := -1;
1780     for i := 0 to FServiceQueryResults.Count - 1 do
1781     with FServiceQueryResults[i] do
1782     case getItemType of
1783     isc_info_svc_limbo_trans:
1784 tony 33 begin
1785 tony 45 if FServiceQueryResults[i].Count = 0 then continue;
1786     NextLimboTransaction(0);
1787     for j := 0 to FServiceQueryResults[i].Count - 1 do
1788 tony 33 begin
1789 tony 45 with FServiceQueryResults[i][j] do
1790     begin
1791     case getItemType of
1792     isc_spb_single_tra_id:
1793     begin
1794     Inc(k);
1795     if k > 0 then
1796     NextLimboTransaction(k);
1797     FLimboTransactionInfo[k].MultiDatabase := False;
1798     FLimboTransactionInfo[k].ID := AsInteger;
1799     end;
1800    
1801     isc_spb_multi_tra_id:
1802     begin
1803     Inc(k);
1804     if k > 0 then
1805     NextLimboTransaction(k);
1806     FLimboTransactionInfo[k].MultiDatabase := True;
1807     FLimboTransactionInfo[k].ID := AsInteger;
1808     end;
1809    
1810     isc_spb_tra_host_site:
1811     FLimboTransactionInfo[k].HostSite := AsString;
1812    
1813     isc_spb_tra_state:
1814     case AsByte of
1815     isc_spb_tra_state_limbo:
1816     FLimboTransactionInfo[k].State := LimboState;
1817    
1818     isc_spb_tra_state_commit:
1819     FLimboTransactionInfo[k].State := CommitState;
1820    
1821     isc_spb_tra_state_rollback:
1822     FLimboTransactionInfo[k].State := RollbackState;
1823    
1824     else
1825     FLimboTransactionInfo[k].State := UnknownState;
1826     end;
1827    
1828     isc_spb_tra_remote_site:
1829     FLimboTransactionInfo[k].RemoteSite := AsString;
1830    
1831     isc_spb_tra_db_path:
1832     FLimboTransactionInfo[k].RemoteDatabasePath := AsString;
1833    
1834     isc_spb_tra_advise:
1835     with FLimboTransactionInfo[k] do
1836     begin
1837     case (AsByte) of
1838     isc_spb_tra_advise_commit:
1839     begin
1840     Advise := CommitAdvise;
1841     Action:= CommitAction;
1842     end;
1843    
1844     isc_spb_tra_advise_rollback:
1845     begin
1846     Advise := RollbackAdvise;
1847     Action := RollbackAction;
1848     end;
1849    
1850     else
1851     Advise := UnknownAdvise;
1852     end;
1853     end;
1854    
1855 tony 33 else
1856 tony 45 IBError(ibxeOutputParsingError, [getItemType]);
1857 tony 33 end;
1858 tony 45 end;
1859 tony 33 end;
1860     end;
1861 tony 45 else
1862     IBError(ibxeOutputParsingError, [getItemType]);
1863 tony 33 end;
1864     end;
1865    
1866     procedure TIBValidationService.FixLimboTransactionErrors;
1867     var
1868     i: Integer;
1869     begin
1870 tony 45 SRB.Add(isc_action_svc_repair);
1871     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1872     case FGlobalAction of
1873     NoGlobalAction:
1874 tony 33 begin
1875 tony 45 for i := 0 to LimboTransactionInfoCount - 1 do
1876     begin
1877     if (FLimboTransactionInfo[i].Action = CommitAction) then
1878     SRB.Add(isc_spb_rpr_commit_trans).AsInteger := FLimboTransactionInfo[i].ID
1879     else
1880     SRB.Add(isc_spb_rpr_rollback_trans).AsInteger := FLimboTransactionInfo[i].ID;
1881     end;
1882 tony 33 end;
1883 tony 45
1884     CommitGlobal:
1885     begin
1886     for i := 0 to LimboTransactionInfoCount - 1 do
1887     SRB.Add(isc_spb_rpr_commit_trans).AsInteger := FLimboTransactionInfo[i].ID;
1888     end;
1889    
1890     RollbackGlobal:
1891 tony 33 begin
1892 tony 45 for i := 0 to LimboTransactionInfoCount - 1 do
1893     SRB.Add(isc_spb_rpr_rollback_trans).AsInteger := FLimboTransactionInfo[i].ID;
1894 tony 33 end;
1895 tony 45
1896     RecoverTwoPhaseGlobal:
1897     begin
1898     for i := 0 to LimboTransactionInfoCount - 1 do
1899     SRB.Add(isc_spb_rpr_recover_two_phase).AsInteger := FLimboTransactionInfo[i].ID;
1900     end;
1901 tony 33 end;
1902     InternalServiceStart;
1903     end;
1904    
1905     function TIBValidationService.GetLimboTransactionInfo(index: integer): TLimboTransactionInfo;
1906     begin
1907     if index <= High(FLimboTransactionInfo) then
1908     result := FLimboTransactionInfo[index]
1909     else
1910     result := nil;
1911     end;
1912    
1913     function TIBValidationService.GetLimboTransactionInfoCount: integer;
1914     begin
1915 tony 45 Result := Length(FLimboTransactionInfo);
1916 tony 33 end;
1917    
1918     procedure TIBValidationService.SetDatabaseName(const Value: string);
1919     begin
1920     FDatabaseName := Value;
1921     end;
1922    
1923     procedure TIBValidationService.SetServiceStartOptions;
1924     var
1925     param: Integer;
1926     begin
1927     Action := isc_action_svc_repair;
1928     if FDatabaseName = '' then
1929     IBError(ibxeStartParamsError, [nil]);
1930 tony 45 SRB.Add(isc_action_svc_repair);
1931     SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1932 tony 33 param := 0;
1933     if (SweepDB in Options) then
1934     param := param or isc_spb_rpr_sweep_db;
1935     if (ValidateDB in Options) then
1936     param := param or isc_spb_rpr_validate_db;
1937 tony 45
1938 tony 33 if (LimboTransactions in Options) then
1939     param := param or isc_spb_rpr_list_limbo_trans;
1940     if (CheckDB in Options) then
1941     param := param or isc_spb_rpr_check_db;
1942     if (IgnoreChecksum in Options) then
1943     param := param or isc_spb_rpr_ignore_checksum;
1944     if (KillShadows in Options) then
1945     param := param or isc_spb_rpr_kill_shadows;
1946     if (MendDB in Options) then
1947     param := param or isc_spb_rpr_mend_db;
1948     if (ValidateFull in Options) then
1949     begin
1950     param := param or isc_spb_rpr_full;
1951     if not (MendDB in Options) then
1952     param := param or isc_spb_rpr_validate_db;
1953     end;
1954     if param > 0 then
1955 tony 45 SRB.Add(isc_spb_options).AsInteger := param;
1956 tony 33 end;
1957    
1958     { TIBSecurityService }
1959     constructor TIBSecurityService.Create(AOwner: TComponent);
1960     begin
1961     inherited Create(AOwner);
1962     FModifyParams := [];
1963     end;
1964    
1965     destructor TIBSecurityService.Destroy;
1966     var
1967     i : Integer;
1968     begin
1969     for i := 0 to High(FUserInfo) do
1970     FUserInfo[i].Free;
1971     FUserInfo := nil;
1972     inherited Destroy;
1973     end;
1974    
1975     procedure TIBSecurityService.FetchUserInfo;
1976     var
1977 tony 45 i, j, k: Integer;
1978 tony 33 begin
1979 tony 45 SRB.Add(isc_info_svc_get_users);
1980 tony 33 InternalServiceQuery;
1981 tony 45
1982 tony 33 for i := 0 to High(FUserInfo) do
1983     FUserInfo[i].Free;
1984 tony 45 for i := 0 to FServiceQueryResults.Count - 1 do
1985     with FServiceQueryResults[i] do
1986 tony 33 begin
1987 tony 45 case getItemType of
1988     isc_info_svc_get_users:
1989     begin
1990     SetLength(FUserInfo,1);
1991     k := 0;
1992     FUserInfo[0] := TUserInfo.Create;
1993     FUserInfo[0].UserName := '';
1994     for j := 0 to FServiceQueryResults[i].Count - 1 do
1995     begin
1996     with FServiceQueryResults[i][j] do
1997     case getItemType of
1998     isc_spb_sec_username:
1999     begin
2000     if FUserInfo[k].UserName <> '' then
2001     begin
2002     Inc(k);
2003     SetLength(FUserInfo,k+1);
2004     if FUserInfo[k] = nil then
2005     FUserInfo[k] := TUserInfo.Create;
2006     end;
2007     FUserInfo[k].UserName := AsString;
2008     end;
2009    
2010     isc_spb_sec_firstname:
2011     FUserInfo[k].FirstName := AsString;
2012    
2013     isc_spb_sec_middlename:
2014     FUserInfo[k].MiddleName := AsString;
2015    
2016     isc_spb_sec_lastname:
2017     FUserInfo[k].LastName := AsString;
2018    
2019     isc_spb_sec_userId:
2020     FUserInfo[k].UserId := AsInteger;
2021    
2022     isc_spb_sec_groupid:
2023     FUserInfo[k].GroupID := AsInteger;
2024    
2025 tony 143 isc_spb_sec_admin:
2026     FUserInfo[k].AdminRole := AsInteger <> 0;
2027    
2028 tony 45 else
2029     IBError(ibxeOutputParsingError, [getItemType]);
2030     end;
2031     end;
2032     end;
2033     else
2034     IBError(ibxeOutputParsingError, [getItemType]);
2035     end;
2036 tony 33 end;
2037     end;
2038    
2039     function TIBSecurityService.GetUserInfo(Index: Integer): TUserInfo;
2040     begin
2041     if Index <= High(FUSerInfo) then
2042     result := FUserInfo[Index]
2043     else
2044     result := nil;
2045     end;
2046    
2047     function TIBSecurityService.GetUserInfoCount: Integer;
2048     begin
2049 tony 45 Result := Length(FUserInfo);
2050 tony 33 end;
2051    
2052     procedure TIBSecurityService.AddUser;
2053     begin
2054     SecurityAction := ActionAddUser;
2055     ServiceStart;
2056     end;
2057    
2058     procedure TIBSecurityService.DeleteUser;
2059     begin
2060     SecurityAction := ActionDeleteUser;
2061     ServiceStart;
2062     end;
2063    
2064     procedure TIBSecurityService.DisplayUsers;
2065     begin
2066     SecurityAction := ActionDisplayUser;
2067 tony 143 if HasAdminRole then
2068     SRB.Add(isc_action_svc_display_user_adm) {Firebird 2.5 and later only}
2069     else
2070     SRB.Add(isc_action_svc_display_user);
2071 tony 33 InternalServiceStart;
2072     FetchUserInfo;
2073     end;
2074    
2075 tony 143 procedure TIBSecurityService.DisplayUser(UserName: string);
2076 tony 33 begin
2077     SecurityAction := ActionDisplayUser;
2078 tony 143 if HasAdminRole then
2079     SRB.Add(isc_action_svc_display_user_adm) {Firebird 2.5 and later only}
2080     else
2081     SRB.Add(isc_action_svc_display_user);
2082 tony 45 SRB.Add(isc_spb_sec_username).AsString := UserName;
2083 tony 33 InternalServiceStart;
2084     FetchUserInfo;
2085     end;
2086    
2087     procedure TIBSecurityService.ModifyUser;
2088     begin
2089     SecurityAction := ActionModifyUser;
2090     ServiceStart;
2091     end;
2092    
2093 tony 143 function TIBSecurityService.HasAdminRole: boolean;
2094     begin
2095     Result := (ServerVersionNo[1] > 2) or
2096     ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] = 5));
2097     end;
2098    
2099 tony 33 procedure TIBSecurityService.SetSecurityAction (Value: TSecurityAction);
2100     begin
2101     FSecurityAction := Value;
2102     if Value = ActionDeleteUser then
2103     ClearParams;
2104     end;
2105    
2106     procedure TIBSecurityService.ClearParams;
2107     begin
2108     FModifyParams := [];
2109     FFirstName := '';
2110     FMiddleName := '';
2111     FLastName := '';
2112     FGroupID := 0;
2113     FUserID := 0;
2114     FPassword := '';
2115     end;
2116    
2117 tony 143 procedure TIBSecurityService.SetAdminRole(AValue: boolean);
2118     begin
2119     FAdminRole := AValue;
2120     Include (FModifyParams, ModifyAdminRole);
2121     end;
2122    
2123 tony 33 procedure TIBSecurityService.SetFirstName (Value: String);
2124     begin
2125     FFirstName := Value;
2126     Include (FModifyParams, ModifyFirstName);
2127     end;
2128    
2129     procedure TIBSecurityService.SetMiddleName (Value: String);
2130     begin
2131     FMiddleName := Value;
2132     Include (FModifyParams, ModifyMiddleName);
2133     end;
2134    
2135     procedure TIBSecurityService.SetLastName (Value: String);
2136     begin
2137     FLastName := Value;
2138     Include (FModifyParams, ModifyLastName);
2139     end;
2140    
2141     procedure TIBSecurityService.SetPassword (Value: String);
2142     begin
2143     FPassword := Value;
2144     Include (FModifyParams, ModifyPassword);
2145     end;
2146    
2147     procedure TIBSecurityService.SetUserId (Value: Integer);
2148     begin
2149     FUserId := Value;
2150     Include (FModifyParams, ModifyUserId);
2151     end;
2152    
2153     procedure TIBSecurityService.SetGroupId (Value: Integer);
2154     begin
2155     FGroupId := Value;
2156     Include (FModifyParams, ModifyGroupId);
2157     end;
2158    
2159     procedure TIBSecurityService.Loaded;
2160     begin
2161     inherited Loaded;
2162     ClearParams;
2163     end;
2164    
2165     procedure TIBSecurityService.SetServiceStartOptions;
2166     var
2167     Len: UShort;
2168    
2169     begin
2170     case FSecurityAction of
2171     ActionAddUser:
2172     begin
2173     Action := isc_action_svc_add_user;
2174     if ( Pos(' ', FUserName) > 0 ) then
2175     IBError(ibxeStartParamsError, [nil]);
2176     Len := Length(FUserName);
2177     if (Len = 0) then
2178     IBError(ibxeStartParamsError, [nil]);
2179 tony 45 SRB.Add(isc_action_svc_add_user);
2180     SRB.Add(isc_spb_sec_username).AsString := FUserName;
2181 tony 143 if FSQLRole <> '' then
2182     SRB.Add(isc_spb_sql_role_name).AsString := FSQLRole;
2183 tony 45 SRB.Add(isc_spb_sec_userid).AsInteger := FUserID;
2184     SRB.Add(isc_spb_sec_groupid).AsInteger := FGroupID;
2185     SRB.Add(isc_spb_sec_password).AsString := FPassword;
2186     SRB.Add(isc_spb_sec_firstname).AsString := FFirstName;
2187     SRB.Add(isc_spb_sec_middlename).AsString := FMiddleName;
2188     SRB.Add(isc_spb_sec_lastname).AsString := FLastName;
2189 tony 143 if HasAdminRole then
2190     SRB.Add(isc_spb_sec_admin).AsInteger := ord(FAdminRole);
2191 tony 33 end;
2192     ActionDeleteUser:
2193     begin
2194     Action := isc_action_svc_delete_user;
2195     Len := Length(FUserName);
2196     if (Len = 0) then
2197     IBError(ibxeStartParamsError, [nil]);
2198 tony 45 SRB.Add(isc_action_svc_delete_user);
2199     SRB.Add(isc_spb_sec_username).AsString := FUserName;
2200 tony 143 if FSQLRole <> '' then
2201     SRB.Add(isc_spb_sql_role_name).AsString := FSQLRole;
2202 tony 33 end;
2203     ActionModifyUser:
2204     begin
2205     Action := isc_action_svc_modify_user;
2206     Len := Length(FUserName);
2207     if (Len = 0) then
2208     IBError(ibxeStartParamsError, [nil]);
2209 tony 45 SRB.Add(isc_action_svc_modify_user);
2210     SRB.Add(isc_spb_sec_username).AsString := FUserName;
2211 tony 143 if FSQLRole <> '' then
2212     SRB.Add(isc_spb_sql_role_name).AsString := FSQLRole;
2213 tony 33 if (ModifyUserId in FModifyParams) then
2214 tony 45 SRB.Add(isc_spb_sec_userid).AsInteger := FUserID;
2215 tony 33 if (ModifyGroupId in FModifyParams) then
2216 tony 45 SRB.Add(isc_spb_sec_groupid).AsInteger := FGroupID;
2217 tony 33 if (ModifyPassword in FModifyParams) then
2218 tony 45 SRB.Add(isc_spb_sec_password).AsString := FPassword;
2219 tony 33 if (ModifyFirstName in FModifyParams) then
2220 tony 45 SRB.Add(isc_spb_sec_firstname).AsString := FFirstName;
2221 tony 33 if (ModifyMiddleName in FModifyParams) then
2222 tony 45 SRB.Add(isc_spb_sec_middlename).AsString := FMiddleName;
2223 tony 33 if (ModifyLastName in FModifyParams) then
2224 tony 45 SRB.Add(isc_spb_sec_lastname).AsString := FLastName;
2225 tony 143 if (ModifyAdminRole in FModifyParams) and HasAdminRole then
2226     begin
2227     if FAdminRole then
2228     SRB.Add(isc_spb_sec_admin).AsInteger := 1
2229     else
2230     SRB.Add(isc_spb_sec_admin).AsInteger := 0;
2231     end;
2232 tony 33 end;
2233     end;
2234     ClearParams;
2235     end;
2236    
2237     { TIBUnStructuredService }
2238 tony 45 constructor TIBControlAndQueryService.create(AOwner: TComponent);
2239 tony 33 begin
2240     inherited Create(AOwner);
2241     FEof := False;
2242     FAction := 0;
2243     end;
2244    
2245     procedure TIBControlAndQueryService.SetAction(Value: Integer);
2246     begin
2247     FEof := False;
2248     FAction := Value;
2249     end;
2250    
2251    
2252     function TIBControlAndQueryService.GetNextChunk: String;
2253     var
2254 tony 45 i: Integer;
2255 tony 33 begin
2256     if (FEof = True) then
2257     begin
2258     result := '';
2259     exit;
2260     end;
2261     if (FAction = 0) then
2262     IBError(ibxeQueryParamsError, [nil]);
2263 tony 45
2264     SRB.Add(isc_info_svc_to_eof);
2265 tony 33 InternalServiceQuery;
2266 tony 45
2267     FEof := True;
2268     for i := 0 to FServiceQueryResults.Count - 1 do
2269     with FServiceQueryResults[i] do
2270     begin
2271     case getItemType of
2272     isc_info_svc_to_eof:
2273     Result := AsString;
2274    
2275     isc_info_truncated:
2276     FEof := False;
2277 tony 33 else
2278 tony 45 IBError(ibxeOutputParsingError, [getItemType]);
2279     end;
2280     end;
2281 tony 33 end;
2282    
2283 tony 143 procedure TIBControlAndQueryService.ServiceStart;
2284     begin
2285     FEof := false;
2286     inherited ServiceStart;
2287     end;
2288    
2289 tony 45 function TIBControlAndQueryService.WriteNextChunk(stream: TStream): integer;
2290     var
2291     i: Integer;
2292 tony 143 TimeOut: boolean;
2293 tony 45 begin
2294     result := 0;
2295 tony 143 TimeOut := false;
2296 tony 45 if (FEof = True) then
2297     exit;
2298     if (FAction = 0) then
2299     IBError(ibxeQueryParamsError, [nil]);
2300    
2301     SQPB.Add(isc_info_svc_timeout).AsInteger := 1;
2302     SRB.Add(isc_info_svc_to_eof);
2303     InternalServiceQuery;
2304    
2305     FEof := True;
2306     for i := 0 to FServiceQueryResults.Count - 1 do
2307     with FServiceQueryResults[i] do
2308     begin
2309     case getItemType of
2310     isc_info_svc_to_eof:
2311     begin
2312     Result := CopyTo(stream,0);
2313 tony 143 FEof := (Result = 0) and not TimeOut;
2314 tony 45 end;
2315    
2316     isc_info_truncated:
2317     FEof := False;
2318    
2319     isc_info_svc_timeout:
2320 tony 143 begin
2321     FEof := False;
2322     TimeOut := true;
2323     end
2324    
2325 tony 45 else
2326     IBError(ibxeOutputParsingError, [getItemType]);
2327     end;
2328     end;
2329     end;
2330    
2331 tony 33 function TIBControlAndQueryService.GetNextLine: String;
2332     var
2333 tony 45 i: Integer;
2334 tony 33 begin
2335 tony 45 Result := '';
2336 tony 33 if (FEof = True) then
2337     exit;
2338 tony 45
2339 tony 33 if (FAction = 0) then
2340     IBError(ibxeQueryParamsError, [nil]);
2341 tony 45
2342     SRB.Add(isc_info_svc_line);
2343 tony 33 InternalServiceQuery;
2344 tony 45
2345     for i := 0 to FServiceQueryResults.Count - 1 do
2346     with FServiceQueryResults[i] do
2347 tony 33 begin
2348 tony 45 case getItemType of
2349     isc_info_svc_line:
2350     Result := AsString;
2351     else
2352     IBError(ibxeOutputParsingError, [getItemType]);
2353     end;
2354 tony 33 end;
2355 tony 45 FEOF := Result = '';
2356 tony 33 end;
2357    
2358     { TIBLogService }
2359    
2360     procedure TIBLogService.SetServiceStartOptions;
2361     begin
2362     Action := isc_action_svc_get_ib_log;
2363 tony 45 SRB.Add(isc_action_svc_get_ib_log);
2364 tony 33 end;
2365    
2366     { TDatabaseInfo }
2367    
2368     constructor TDatabaseInfo.Create;
2369     begin
2370     DbName := nil;
2371     end;
2372    
2373     destructor TDatabaseInfo.Destroy;
2374     begin
2375     DbName := nil;
2376     inherited Destroy;
2377     end;
2378    
2379     { TLicenseInfo }
2380    
2381     constructor TLicenseInfo.Create;
2382     begin
2383     Key := nil;
2384     Id := nil;
2385     Desc := nil;
2386     end;
2387    
2388     destructor TLicenseInfo.Destroy;
2389     begin
2390     Key := nil;
2391     Id := nil;
2392     Desc := nil;
2393     inherited Destroy;
2394     end;
2395    
2396     { TConfigFileData }
2397    
2398     constructor TConfigFileData.Create;
2399     begin
2400     ConfigFileValue := nil;
2401     ConfigFileKey := nil;
2402     end;
2403    
2404     destructor TConfigFileData.Destroy;
2405     begin
2406     ConfigFileValue := nil;
2407     ConfigFileKey := nil;
2408     inherited Destroy;
2409     end;
2410    
2411     { TConfigParams }
2412    
2413     constructor TConfigParams.Create;
2414     begin
2415     ConfigFileData := TConfigFileData.Create;
2416     ConfigFileParams := nil;
2417     end;
2418    
2419     destructor TConfigParams.Destroy;
2420     begin
2421     ConfigFileData.Free;
2422     ConfigFileParams := nil;
2423     inherited Destroy;
2424     end;
2425    
2426     end.