ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/examples/DBAdmin/DataModule.pas
Revision: 380
Committed: Mon Jan 10 10:13:17 2022 UTC (2 years, 3 months ago) by tony
Content type: text/x-pascal
File size: 50804 byte(s)
Log Message:
propset for eol-style

File Contents

# Content
1 (*
2 * DataModule.pas
3 * Copyright (C) 2018 Tony Whyman <tony@mwasoftware.co.uk>
4 *
5 * DBAdmin is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * DBAdmin is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 *)
18 unit DataModule;
19
20 {$mode objfpc}{$H+}
21
22 interface
23
24 uses
25 Classes, SysUtils, FileUtil, db, memds, IBDatabase, IBSQL, IBQuery,
26 IBCustomDataSet, IBUpdate, IBDatabaseInfo, IBXServices, IB,
27 Dialogs, Controls, Forms;
28
29 type
30
31 { TDBDataModule }
32
33 TDBDataModule = class(TDataModule)
34 AccessRightsCHILDCOUNT: TIBIntegerField;
35 AccessRightsDisplayName: TStringField;
36 AccessRightsID: TIBStringField;
37 AccessRightsImageIndex: TLongintField;
38 AccessRightsPARENT: TIBStringField;
39 AccessRightsSUBJECT_NAME: TIBStringField;
40 AccessRightsSUBJECT_TYPE: TIBSmallintField;
41 ApplicationProperties1: TApplicationProperties;
42 AttachmentsMONATTACHMENT_ID: TIBLargeIntField;
43 AttachmentsMONATTACHMENT_NAME: TIBStringField;
44 AttachmentsMONAUTH_METHOD: TIBStringField;
45 AttachmentsMONCHARACTER_SET_ID: TIBSmallintField;
46 AttachmentsMONCLIENT_VERSION: TIBStringField;
47 AttachmentsMONGARBAGE_COLLECTION: TIBSmallintField;
48 AttachmentsMONREMOTE_ADDRESS: TIBStringField;
49 AttachmentsMONREMOTE_HOST: TIBStringField;
50 AttachmentsMONREMOTE_OS_USER: TIBStringField;
51 AttachmentsMONREMOTE_PID: TIBIntegerField;
52 AttachmentsMONREMOTE_PROCESS: TIBStringField;
53 AttachmentsMONREMOTE_PROTOCOL: TIBStringField;
54 AttachmentsMONREMOTE_VERSION: TIBStringField;
55 AttachmentsMONROLE: TIBStringField;
56 AttachmentsMONSERVER_PID: TIBIntegerField;
57 AttachmentsMONSTATE: TIBSmallintField;
58 AttachmentsMONSTAT_ID: TIBIntegerField;
59 AttachmentsMONSYSTEM_FLAG: TIBSmallintField;
60 AttachmentsMONTIMESTAMP: TDateTimeField;
61 AttachmentsMONUSER: TIBStringField;
62 AttachmentsRDBBYTES_PER_CHARACTER: TIBSmallintField;
63 AttachmentsRDBCHARACTER_SET_ID: TIBSmallintField;
64 AttachmentsRDBCHARACTER_SET_NAME: TIBStringField;
65 AttachmentsRDBDEFAULT_COLLATE_NAME: TIBStringField;
66 AttachmentsRDBDESCRIPTION: TIBMemoField;
67 AttachmentsRDBFORM_OF_USE: TIBStringField;
68 AttachmentsRDBFUNCTION_NAME: TIBStringField;
69 AttachmentsRDBNUMBER_OF_CHARACTERS: TIBIntegerField;
70 AttachmentsRDBOWNER_NAME: TIBStringField;
71 AttachmentsRDBSECURITY_CLASS: TIBStringField;
72 AttachmentsRDBSYSTEM_FLAG: TIBSmallintField;
73 CharSetLookup: TIBQuery;
74 ConfigDataset: TMemDataset;
75 CurrentTransaction: TIBTransaction;
76 DatabaseQuery: TIBQuery;
77 Attachments: TIBQuery;
78 DBTables: TIBQuery;
79 AuthMappings: TIBQuery;
80 AccessRights: TIBQuery;
81 IBConfigService1: TIBXConfigService;
82 IBServerProperties1: TIBXServerProperties;
83 IBLogService1: TIBXLogService;
84 IBSecurityService1: TIBXSecurityService;
85 IBOnlineValidationService1: TIBXOnlineValidationService;
86
87 IBLimboTrans: TIBXLimboTransactionResolutionService;
88 IBXServicesConnection1: TIBXServicesConnection;
89 IBStatisticalService1: TIBXStatisticalService;
90 IBValidationService1: TIBXValidationService;
91 InLimboList: TIBXServicesLimboTransactionsList;
92 LegacyUserList: TIBXServicesUserList;
93 SubjectAccessRights: TIBQuery;
94 AttUpdate: TIBUpdate;
95 AdminUserQuery: TIBSQL;
96 DBTablesUpdate: TIBUpdate;
97 UserListGROUPID: TLongintField;
98 UserListSECPASSWORD: TIBStringField;
99 UserListSECUSER_NAME: TIBStringField;
100 UserListSource: TDataSource;
101 DBCharSet: TIBQuery;
102 DBSecFiles: TIBQuery;
103 ExecDDL: TIBSQL;
104 IBDatabase1: TIBDatabase;
105 IBDatabaseInfo: TIBDatabaseInfo;
106 AttmtQuery: TIBQuery;
107 RoleNameList: TIBQuery;
108 TableNameLookup: TIBQuery;
109 TagsUpdate: TIBUpdate;
110 UpdateCharSet: TIBUpdate;
111 SecGlobalAuth: TIBQuery;
112 ShadowFiles: TIBQuery;
113 ShadowFilesFileMode: TStringField;
114 ShadowFilesRDBFILE_FLAGS: TSmallintField;
115 ShadowFilesRDBFILE_LENGTH: TIntegerField;
116 ShadowFilesRDBFILE_NAME: TIBStringField;
117 ShadowFilesRDBFILE_SEQUENCE: TSmallintField;
118 ShadowFilesRDBFILE_START: TIntegerField;
119 ShadowFilesRDBSHADOW_NUMBER: TSmallintField;
120 UpdateUserRoles: TIBUpdate;
121 UpdateUsers: TIBUpdate;
122 UserList: TIBQuery;
123 UserListCURRENT_CONNECTION: TIBLargeIntField;
124 UserListDBCREATOR: TBooleanField;
125 UserListLOGGEDIN: TBooleanField;
126 UserListSECACTIVE: TBooleanField;
127 UserListSECADMIN: TBooleanField;
128 UserListSECFIRST_NAME: TIBStringField;
129 UserListSECLAST_NAME: TIBStringField;
130 UserListSECMIDDLE_NAME: TIBStringField;
131 UserListSECPLUGIN: TIBStringField;
132 UserListUSERID: TLongintField;
133 UserTags: TIBQuery;
134 procedure AccessRightsCalcFields(DataSet: TDataSet);
135 procedure ApplicationProperties1Exception(Sender: TObject; E: Exception);
136 procedure AttachmentsAfterDelete(DataSet: TDataSet);
137 procedure AttachmentsAfterOpen(DataSet: TDataSet);
138 procedure AttachmentsBeforeOpen(DataSet: TDataSet);
139 procedure ConfigDatasetAfterClose(DataSet: TDataSet);
140 procedure CurrentTransactionAfterTransactionEnd(Sender: TObject);
141 procedure DatabaseQueryAfterOpen(DataSet: TDataSet);
142 procedure DatabaseQueryBeforeClose(DataSet: TDataSet);
143 procedure DBCharSetAfterClose(DataSet: TDataSet);
144 procedure DBCharSetBeforeOpen(DataSet: TDataSet);
145 procedure IBDatabase1AfterConnect(Sender: TObject);
146 procedure IBDatabase1AfterDisconnect(Sender: TObject);
147 procedure IBDatabase1BeforeDisconnect(Sender: TObject);
148 procedure IBDatabase1Login(Database: TIBDatabase; LoginParams: TStrings);
149 procedure AttUpdateApplyUpdates(Sender: TObject; UpdateKind: TUpdateKind;
150 Params: ISQLParams);
151 procedure DBTablesUpdateApplyUpdates(Sender: TObject; UpdateKind: TUpdateKind;
152 Params: ISQLParams);
153 procedure IBValidationService1GetNextLine(Sender: TObject; var Line: string
154 );
155 procedure IBXServicesConnection1AfterConnect(Sender: TObject);
156 procedure IBXServicesConnection1Login(Service: TIBXServicesConnection;
157 var aServerName: string; LoginParams: TStrings);
158 procedure LegacyUserListAfterOpen(DataSet: TDataSet);
159 procedure LegacyUserListAfterPost(DataSet: TDataSet);
160 procedure LegacyUserListBeforeClose(DataSet: TDataSet);
161 procedure ShadowFilesCalcFields(DataSet: TDataSet);
162 procedure SubjectAccessRightsBeforeOpen(DataSet: TDataSet);
163 procedure TagsUpdateApplyUpdates(Sender: TObject; UpdateKind: TUpdateKind;
164 Params: ISQLParams);
165 procedure UpdateCharSetApplyUpdates(Sender: TObject;
166 UpdateKind: TUpdateKind; Params: ISQLParams);
167 procedure UpdateUserRolesApplyUpdates(Sender: TObject;
168 UpdateKind: TUpdateKind; Params: ISQLParams);
169 procedure UpdateUsersApplyUpdates(Sender: TObject; UpdateKind: TUpdateKind;
170 Params: ISQLParams);
171 procedure UserListAfterInsert(DataSet: TDataSet);
172 procedure UserListAfterOpen(DataSet: TDataSet);
173 procedure UserListAfterPost(DataSet: TDataSet);
174 procedure UserListAfterScroll(DataSet: TDataSet);
175 procedure UserListBeforeClose(DataSet: TDataSet);
176 procedure UserTagsAfterInsert(DataSet: TDataSet);
177 private
178 FAfterDataReload: TNotifyEvent;
179 FAfterDBConnect: TNotifyEvent;
180 FDBHeaderScanned: boolean;
181 FDisconnecting: boolean;
182 FISShadowDatabase: boolean;
183 FDBUserName: string;
184 FDBPassword: string;
185 FLocalConnect: boolean;
186 FSubjectAccessRightsID: string;
187 {Parsed results of connectstring;}
188 FServerName: string;
189 FPortNo: string;
190 FProtocol: TProtocolAll;
191 FDatabasePathName: string;
192 FHasUserAdminPrivilege: boolean;
193 function GetAuthMethod: string;
194 function GetAutoAdmin: boolean;
195 function GetDatabaseName: string;
196 function GetDBDateCreated: string;
197 procedure GetDBFlags;
198 function GetDBOwner: string;
199 function GetDBReadOnly: boolean;
200 function GetDBSQLDialect: integer;
201 function GetDBUserName: string;
202 function GetDescription: string;
203 function GetForcedWrites: boolean;
204 function GetLingerDelay: string;
205 function GetNoReserve: boolean;
206 function GetPageBuffers: integer;
207 function GetRoleName: string;
208 function GetSecurityDatabase: string;
209 function GetServerName: string;
210 function GetSweepInterval: integer;
211 function GetUserAdminPrivilege: boolean;
212 procedure SetAutoAdmin(AValue: boolean);
213 procedure SetDBReadOnly(AValue: boolean);
214 procedure SetDBSQLDialect(AValue: integer);
215 procedure SetDescription(AValue: string);
216 procedure SetForcedWrites(AValue: boolean);
217 procedure SetLingerDelay(AValue: string);
218 procedure SetNoReserve(AValue: boolean);
219 procedure SetPageBuffers(AValue: integer);
220 procedure SetSweepInterval(AValue: integer);
221 procedure ReloadData(Data: PtrInt=0);
222 protected
223 FServiceUserName: string;
224 function GetEmbeddedMode: boolean; virtual;
225 procedure ConnectServicesAPI; virtual;
226 function CallLoginDlg(var aDatabaseName, aUserName, aPassword: string;
227 var aCreateIfNotExist: boolean): TModalResult; virtual;
228 public
229 destructor Destroy; override;
230 function Connect: boolean; virtual;
231 procedure Disconnect; virtual;
232 procedure DropDatabase;
233 procedure BackupDatabase;
234 procedure RestoreDatabase;
235 procedure BringDatabaseOnline;
236 procedure ShutDown(aShutDownmode: TDBShutdownMode; aDelay: integer);
237 procedure DatabaseRepair(Options: TValidateOptions; ReportLines: TStrings);
238 procedure OnlineValidation(ReportLines: TStrings; SelectedTablesOnly: boolean);
239 procedure LimboResolution(ActionID: TTransactionGlobalAction; Report: TStrings);
240 function IsDatabaseOnline: boolean;
241 function IsShadowDatabase: boolean;
242 procedure ActivateShadow;
243 procedure AddSecondaryFile(aFileName: string; StartAt,FileLength: integer);
244 procedure AddShadowSet;
245 procedure RemoveShadowSet(ShadowSet: integer);
246 procedure LoadPerformanceStatistics(Lines: TStrings);
247 procedure LoadDatabaseStatistics(OptionID: integer; Lines: TStrings);
248 function LoadConfigData(ConfigFileData: TConfigFileData): boolean;
249 procedure LoadServerProperties(Lines: TStrings);
250 procedure LoadServerLog(Lines: TStrings);
251 procedure RevokeAll;
252 procedure SyncSubjectAccessRights(ID: string);
253 property AutoAdmin: boolean read GetAutoAdmin write SetAutoAdmin;
254 property Description: string read GetDescription write SetDescription;
255 property Disconnecting: boolean read FDisconnecting;
256 property ForcedWrites: boolean read GetForcedWrites write SetForcedWrites;
257 property LingerDelay: string read GetLingerDelay write SetLingerDelay;
258 property DBReadOnly: boolean read GetDBReadOnly write SetDBReadOnly;
259 property NoReserve: boolean read GetNoReserve write SetNoReserve;
260 property PageBuffers: integer read GetPageBuffers write SetPageBuffers;
261 property SweepInterval: integer read GetSweepInterval write SetSweepInterval;
262 property DatabaseName: string read GetDatabaseName;
263 property SecurityDatabase: string read GetSecurityDatabase;
264 property AuthMethod: string read GetAuthMethod;
265 property EmbeddedMode: boolean read GetEmbeddedMode;
266 property DBUserName: string read GetDBUserName;
267 property RoleName: string read GetRoleName;
268 property DBOwner: string read GetDBOwner;
269 property DBSQLDialect: integer read GetDBSQLDialect write SetDBSQLDialect;
270 property DBDateCreated: string read GetDBDateCreated;
271 property ServerName: string read GetServerName;
272 property ServiceUserName: string read FServiceUserName;
273 property HasUserAdminPrivilege: boolean read FHasUserAdminPrivilege;
274 property AfterDBConnect: TNotifyEvent read FAfterDBConnect write FAfterDBConnect;
275 property AfterDataReload: TNotifyEvent read FAfterDataReload write FAfterDataReload;
276 end;
277
278 var
279 DBDataModule: TDBDataModule;
280
281 implementation
282
283 {$R *.lfm}
284
285 uses DBLoginDlgUnit, IBUtils, IBMessages, ShutdownDatabaseDlgUnit,
286 BackupDlgUnit, RestoreDlgUnit, AddShadowSetDlgUnit, IBErrorCodes;
287
288 const
289 sAddSecondarySQL = 'Alter Database Add File ''%s'' Starting at %d';
290 sAddSecondarySQL2 = 'Alter Database Add File ''%s'' Starting at %d Length %d';
291 sRemoveShadow = 'Drop Shadow %d';
292 sRemoveShadow12 = 'Drop Shadow %d DELETE FILE';
293 sPreserveShadow = 'Drop Shadow %d PRESERVE FILE';
294
295 resourcestring
296 sPreserveShadowFiles = 'Preserve Shadow Set Files after drop?';
297
298 { TDBDataModule }
299
300 procedure TDBDataModule.UpdateCharSetApplyUpdates(Sender: TObject;
301 UpdateKind: TUpdateKind; Params: ISQLParams);
302 begin
303 if UpdateKind = ukModify then
304 begin
305 ExecDDL.SQL.Text := 'ALTER DATABASE SET DEFAULT CHARACTER SET ' +
306 Params.ByName('RDB$CHARACTER_SET_NAME').AsString;
307 ExecDDL.ExecQuery;
308 end;
309 end;
310
311 procedure TDBDataModule.UpdateUserRolesApplyUpdates(Sender: TObject;
312 UpdateKind: TUpdateKind; Params: ISQLParams);
313
314 procedure Grant(Params: ISQLParams);
315 begin
316 ExecDDL.SQL.Text := 'Grant ' + trim(Params.ByName('RDB$ROLE_NAME').AsString) + ' to ' + Params.ByName('SEC$USER_NAME').AsString;
317 ExecDDL.ExecQuery;
318 end;
319
320 procedure Revoke(Params: ISQLParams);
321 begin
322 ExecDDL.SQL.Text := 'Revoke ' + trim(Params.ByName('RDB$ROLE_NAME').AsString) + ' from ' + Params.ByName('SEC$USER_NAME').AsString;
323 ExecDDL.ExecQuery;
324 end;
325
326 begin
327 if UpdateKind = ukModify then
328 begin
329 if Params.ByName('GRANTED').AsInteger = 0 then
330 Revoke(Params)
331 else
332 Grant(Params);
333 end;
334 end;
335
336 procedure TDBDataModule.UpdateUsersApplyUpdates(Sender: TObject;
337 UpdateKind: TUpdateKind; Params: ISQLParams);
338
339 var UserName: string;
340
341 function FormatStmtOptions: string;
342 var Param: ISQLParam;
343 begin
344 Result := UserName;
345 Param := Params.ByName('SEC$PASSWORD');
346 if (Param <> nil) and not Param.IsNull then
347 Result += ' PASSWORD ''' + SQLSafeString(Param.AsString) + '''';
348 Param := Params.ByName('SEC$FIRST_NAME');
349 if Param <> nil then
350 Result += ' FIRSTNAME ''' + SQLSafeString(Param.AsString) + '''';
351 Param := Params.ByName('SEC$MIDDLE_NAME');
352 if Param <> nil then
353 Result += ' MIDDLENAME ''' + SQLSafeString(Param.AsString) + '''';
354 Param := Params.ByName('SEC$LAST_NAME');
355 if Param <> nil then
356 Result += ' LASTNAME ''' + SQLSafeString(Param.AsString) + '''';
357 Param := Params.ByName('SEC$ACTIVE');
358 if Param <> nil then
359 begin
360 if Param.AsBoolean then
361 Result += ' ACTIVE'
362 else
363 Result += ' INACTIVE';
364 end;
365 Param := Params.ByName('SEC$PLUGIN');
366 if Param <> nil then
367 Result += ' USING PLUGIN ' + QuoteIdentifierIfNeeded((Sender as TIBUpdate).DataSet.Database.SQLDialect,Param.AsString);
368 end;
369
370 function GetAlterPasswordStmt: string;
371 var Param: ISQLParam;
372 begin
373 Result := '';
374 Param := Params.ByName('SEC$PASSWORD');
375 if (UpdateKind = ukModify) and not Param.IsNull then
376 begin
377 Result := 'ALTER USER ' + UserName +
378 ' PASSWORD ''' + SQLSafeString(Param.AsString) + '''';
379 Param := Params.ByName('SEC$PLUGIN');
380 if Param <> nil then
381 Result += ' USING PLUGIN ' + QuoteIdentifierIfNeeded((Sender as TIBUpdate).DataSet.Database.SQLDialect,Param.AsString);
382 end;
383 end;
384
385 begin
386 UserName := Trim(Params.ByName('SEC$USER_NAME').AsString);
387 {non SYSDBA user not an RDB$ADMIN can only change their password}
388 if (DBUserName <> 'SYSDBA') and (RoleName <> 'RDB$ADMIN') then
389 begin
390 ExecDDL.SQL.Text := GetAlterPasswordStmt;
391 if ExecDDL.SQL.Text <> '' then
392 ExecDDL.ExecQuery;
393 Exit;
394 end;
395
396 case UpdateKind of
397 ukInsert:
398 ExecDDL.SQL.Text := 'CREATE USER ' + FormatStmtOptions;
399 ukModify:
400 ExecDDL.SQL.Text := 'ALTER USER ' + FormatStmtOptions;
401 ukDelete:
402 ExecDDL.SQL.Text := 'DROP USER ' + UserName;
403 end;
404 ExecDDL.ExecQuery;
405
406 if UpdateKind = ukInsert then
407 begin
408 {if new user is also given the admin role then we need to add this}
409 if Params.ByName('SEC$ADMIN').AsBoolean then
410 begin
411 ExecDDL.SQL.Text := 'ALTER USER ' + UserName + ' GRANT ADMIN ROLE';
412 ExecDDL.ExecQuery;
413 end;
414 if Params.ByName('DBCreator').AsBoolean then
415 begin
416 ExecDDL.SQL.Text := 'GRANT CREATE DATABASE TO USER ' + UserName;
417 ExecDDL.ExecQuery;
418 end
419 else
420 begin
421 ExecDDL.SQL.Text := 'REVOKE CREATE DATABASE FROM USER ' + UserName;
422 ExecDDL.ExecQuery;
423 end
424 end
425 else
426 if UpdateKind = ukModify then
427 {Update Admin Role if allowed}
428 begin
429 if Params.ByName('SEC$ADMIN').AsBoolean and not Params.ByName('OLD_SEC$ADMIN').AsBoolean then
430 begin
431 ExecDDL.SQL.Text := 'ALTER USER ' + UserName + ' GRANT ADMIN ROLE';
432 ExecDDL.ExecQuery;
433 end
434 else
435 if not Params.ByName('SEC$ADMIN').AsBoolean and Params.ByName('OLD_SEC$ADMIN').AsBoolean then
436 begin
437 ExecDDL.SQL.Text := 'ALTER USER ' + UserName + ' REVOKE ADMIN ROLE';
438 ExecDDL.ExecQuery;
439 end
440 end;
441
442 {Update DB Creator Role}
443 if Params.ByName('DBCreator').AsBoolean and not Params.ByName('OLD_DBCreator').AsBoolean then
444 begin
445 ExecDDL.SQL.Text := 'GRANT CREATE DATABASE TO USER ' + UserName;
446 ExecDDL.ExecQuery;
447 end
448 else
449 if not Params.ByName('DBCreator').AsBoolean and Params.ByName('OLD_DBCreator').AsBoolean then
450 begin
451 ExecDDL.SQL.Text := 'REVOKE CREATE DATABASE FROM USER ' + UserName;
452 ExecDDL.ExecQuery;
453 end
454 end;
455
456 procedure TDBDataModule.UserListAfterInsert(DataSet: TDataSet);
457 begin
458 DataSet.FieldByName('SEC$ADMIN').AsBoolean := false;
459 DataSet.FieldByName('SEC$ACTIVE').AsBoolean := false;
460 DataSet.FieldByName('DBCreator').AsBoolean := false;
461 DataSet.FieldByName('SEC$PLUGIN').AsString := 'Srp';
462 // DataSet.FieldByName('UserID').AsInteger := 0;
463 // DataSet.FieldByName('GroupID').AsInteger := 0;
464 DataSet.FieldByName('SEC$PASSWORD').Clear;
465 RoleNameList.Active := false; {Prevent role assignments until saved}
466 UserTags.Active := false; {ditto}
467 end;
468
469 procedure TDBDataModule.UserListAfterOpen(DataSet: TDataSet);
470 begin
471 if UserListSource.DataSet <> DataSet then
472 UserListSource.DataSet := DataSet;
473 RoleNameList.Active := true;
474 UserTags.Active := true;
475 end;
476
477 procedure TDBDataModule.UserListAfterPost(DataSet: TDataSet);
478 begin
479 CurrentTransaction.Commit;
480 end;
481
482 procedure TDBDataModule.UserListAfterScroll(DataSet: TDataSet);
483 begin
484 UserList.FieldByName('SEC$PLUGIN').ReadOnly := UserList.State <> dsInsert;
485 end;
486
487 procedure TDBDataModule.UserListBeforeClose(DataSet: TDataSet);
488 begin
489 RoleNameList.Active := false;
490 UserTags.Active := false;
491 end;
492
493 procedure TDBDataModule.UserTagsAfterInsert(DataSet: TDataSet);
494 begin
495 DataSet.FieldByName('SEC$USER_NAME').AsString := DataSet.DataSource.DataSet.FieldByName('SEC$USER_NAME').AsString;
496 end;
497
498 procedure TDBDataModule.ConnectServicesAPI;
499 begin
500 if IBXServicesConnection1.Connected then Exit;
501 try
502 IBXServicesConnection1.ConnectUsing(IBDatabase1);
503 except on E: Exception do
504 begin
505 Application.ShowException(E);
506 IBDatabase1.Connected := false;
507 FDBPassword := '';
508 Exit;
509 end;
510 end;
511 end;
512
513 function TDBDataModule.CallLoginDlg(var aDatabaseName, aUserName,
514 aPassword: string; var aCreateIfNotExist: boolean): TModalResult;
515 begin
516 Result := DBLoginDlg.ShowModal(aDatabaseName, aUserName, aPassword, aCreateIfNotExist);
517 end;
518
519 procedure TDBDataModule.GetDBFlags;
520 var Lines: TStringList;
521 i: integer;
522 line: string;
523 begin
524 if FDBHeaderScanned or not DatabaseQuery.Active or not AttmtQuery.Active then Exit;
525 FIsShadowDatabase := false;
526
527 try
528 with IBStatisticalService1 do
529 begin
530 Options := [HeaderPages];
531 Lines := TStringList.Create;
532 try
533 Execute(Lines);
534 for i := 0 to Lines.Count - 1 do
535 begin
536 line := Lines[i];
537 if (Pos('Attributes',Line) <> 0) and (Pos('shadow',Line) <> 0) then
538 begin
539 FIsShadowDatabase := true;
540 break;
541 end;
542 end;
543 finally
544 Lines.Free;
545 end;
546 FDBHeaderScanned := true;
547 end;
548 except on E: Exception do
549 MessageDlg('Error getting DB Header Page: ' + E.Message,mtError,[mbOK],0);
550 end;
551 end;
552
553 function TDBDataModule.GetDBOwner: string;
554 var DBOField: TField;
555 begin
556 DBOField := DatabaseQuery.FindField('MON$OWNER');
557 if DBOField <> nil then
558 Result := Trim(DBOField.AsString)
559 else
560 Result := 'n/a';
561 end;
562
563 function TDBDataModule.GetAutoAdmin: boolean;
564 begin
565 Result := false;
566 if not CurrentTransaction.Active then Exit;
567 SecGlobalAuth.Active := true; {sets AutoAdmin}
568 try
569 Result := SecGlobalAuth.FieldByName('Mappings').AsInteger > 0;
570 finally
571 SecGlobalAuth.Active := false;
572 end;
573 end;
574
575 function TDBDataModule.GetDatabaseName: string;
576 begin
577 if DatabaseQuery.Active and not DatabaseQuery.FieldByName('MON$DATABASE_NAME').IsNull then
578 Result := DatabaseQuery.FieldByName('MON$DATABASE_NAME').AsString
579 else
580 Result := FDatabasePathName;
581 end;
582
583 function TDBDataModule.GetDBDateCreated: string;
584 begin
585 with DefaultFormatSettings do
586 try
587 Result := FormatDateTime(LongDateFormat + ' ' + LongTimeFormat,DatabaseQuery.FieldByName('MON$CREATION_DATE').AsDateTime);
588 except
589 Result := 'unknown';
590 end;
591 end;
592
593 function TDBDataModule.GetDBReadOnly: boolean;
594 begin
595 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$READ_ONLY').AsInteger <> 0);
596 end;
597
598 function TDBDataModule.GetDBSQLDialect: integer;
599 begin
600 Result := IBDatabaseInfo.DBSQLDialect;
601 end;
602
603 function TDBDataModule.GetDBUserName: string;
604 var DPB: IDPB;
605 info: IDPBItem;
606 begin
607 Result := '';
608 if AttmtQuery.Active then
609 Result := Trim(AttmtQuery.FieldByName('MON$USER').AsString)
610 else
611 if IBDatabase1.Connected then
612 begin
613 DPB := IBDatabase1.Attachment.getDPB;
614 info := DPB.Find(isc_dpb_user_name);
615 if info <> nil then
616 Result := info.AsString;
617 end
618 end;
619
620 function TDBDataModule.GetDescription: string;
621 begin
622 if DatabaseQuery.Active then
623 Result := DatabaseQuery.FieldByName('RDB$DESCRIPTION').AsString
624 else
625 Result := '';
626 end;
627
628 function TDBDataModule.GetEmbeddedMode: boolean;
629 begin
630 Result := AttmtQuery.Active and AttmtQuery.FieldByName('MON$REMOTE_PROTOCOL').IsNull;
631 end;
632
633 function TDBDataModule.GetForcedWrites: boolean;
634 begin
635 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$FORCED_WRITES').AsInteger <> 0);
636 end;
637
638 procedure TDBDataModule.SetLingerDelay(AValue: string);
639 begin
640 if (StrToInt(AValue) = DatabaseQuery.FieldByName('RDB$LINGER').AsInteger) then Exit;
641
642 if (AValue = '') or (StrToInt(AValue) = 0) then
643 begin
644 if MessageDlg('Turn off Linger Permanently?',mtConfirmation,[mbYes,mbNo],0) = mrNo then
645 begin
646 IBConfigService1.SetNoLinger;
647 CurrentTransaction.Commit; {Refresh}
648 Exit;
649 end;
650 ExecDDL.SQL.Text := 'ALTER DATABASE DROP LINGER'
651 end
652 else
653 ExecDDL.SQL.Text := 'ALTER DATABASE SET LINGER TO ' + AValue;
654 with ExecDDL do
655 begin
656 Transaction.Active := true;
657 ExecQuery;
658 Transaction.Commit;
659 end;
660 end;
661
662
663 function TDBDataModule.GetAuthMethod: string;
664 var AuthMeth: TField;
665 begin
666 AuthMeth := AttmtQuery.FindField('MON$AUTH_METHOD');
667 if AuthMeth = nil then
668 Result := 'Legacy_auth'
669 else
670 Result := AuthMeth.AsString;
671 end;
672
673 procedure TDBDataModule.SetNoReserve(AValue: boolean);
674 begin
675 IBConfigService1.SetReserveSpace(AValue);
676 end;
677
678 procedure TDBDataModule.SetPageBuffers(AValue: integer);
679 begin
680 IBDatabase1.Connected := false;
681 try
682 IBConfigService1.SetPageBuffers(AValue);
683 finally
684 IBDatabase1.Connected := true;
685 end;
686 end;
687
688 procedure TDBDataModule.SetSweepInterval(AValue: integer);
689 begin
690 IBDatabase1.Connected := false;
691 try
692 IBConfigService1.SetSweepInterval(AValue);
693 finally
694 IBDatabase1.Connected := true;
695 end;
696 end;
697
698 procedure TDBDataModule.ReloadData(Data: PtrInt);
699 begin
700 if csDestroying in ComponentState then Exit;
701 CurrentTransaction.Active := true;
702 DataBaseQuery.Active := true;
703 AttmtQuery.Active := true;
704 if LegacyUserList.Active then
705 RoleNameList.Active := true;
706 if assigned(FAfterDataReload) then
707 AfterDataReload(self);
708 end;
709
710 destructor TDBDataModule.Destroy;
711 begin
712 Application.RemoveAsyncCalls(self);
713 inherited Destroy;
714 end;
715
716 function TDBDataModule.Connect: boolean;
717
718 procedure ReportException(E: Exception);
719 begin
720 MessageDlg(E.Message,mtError,[mbOK],0);
721 FDBPassword := '';
722 end;
723
724 procedure KillShadows;
725 begin
726 with IBXServicesConnection1 do
727 begin
728 ServerName := FServerName;
729 Protocol := FProtocol;
730 PortNo := FPortNo;
731 Connected := true;
732 end;
733 try
734 with IBValidationService1 do
735 begin
736 DatabaseName := FDatabasePathName;
737 Options := [IBXServices.KillShadows];
738 Execute(nil);
739 MessageDlg('All Unavailable Shadows killed',mtInformation,[mbOK],0);
740 end;
741 finally
742 IBXServicesConnection1.Connected := false;
743 end;
744 end;
745
746 var KillDone: boolean;
747 begin
748 KillDone := false;
749 Result := false;
750 Disconnect;
751 repeat
752 try
753 IBDatabase1.Connected := true;
754 except
755 on E:EIBClientError do
756 begin
757 Exit
758 end;
759 On E: EIBInterBaseError do
760 begin
761 FDBPassword := '';
762 if (E.IBErrorCode = isc_io_error) and not KillDone then
763 begin
764 if MessageDlg('I/O Error reported on database file. If this is a shadow file, do you want '+
765 'to kill all unavailable shadow sets?. The original message is ' + E.Message,
766 mtInformation,[mbYes,mbNo],0) = mrNo then
767 continue;
768 try KillShadows except end;
769 KillDone := true;
770 end
771 else
772 ReportException(E);
773 end;
774 On E:Exception do
775 ReportException(E);
776 end;
777 until IBDatabase1.Connected;
778
779 if assigned(FAfterDBConnect) then
780 AfterDBConnect(self);
781 Result := IBDatabase1.Connected;
782 end;
783
784 procedure TDBDataModule.Disconnect;
785 begin
786 FDBUserName := '';
787 FDBPassword := '';
788 FServiceUserName := '';
789 FLocalConnect := false;
790 IBDatabase1.Connected := false;
791 IBXServicesConnection1.Connected := false;
792 FDBHeaderScanned := false;
793 end;
794
795 procedure TDBDataModule.DropDatabase;
796 begin
797 IBDatabase1.DropDatabase;
798 Disconnect;
799 end;
800
801 procedure TDBDataModule.BackupDatabase;
802 begin
803 BackupDlg.ShowModal;
804 end;
805
806 procedure TDBDataModule.RestoreDatabase;
807 var DefaultPageSize: integer;
808 DefaultNumBuffers: integer;
809 begin
810 DefaultPageSize := DatabaseQuery.FieldByName('MON$PAGE_SIZE').AsInteger;
811 DefaultNumBuffers := DatabaseQuery.FieldByName('MON$PAGE_BUFFERS').AsInteger;
812 IBDatabase1.Connected := false;
813 try
814 RestoreDlg.ShowModal(DefaultPageSize,DefaultNumBuffers);
815 finally
816 IBDatabase1.Connected := true;
817 end;
818 end;
819
820 procedure TDBDataModule.BringDatabaseOnline;
821 begin
822 if IsDatabaseOnline then
823 MessageDlg('Database is already online!',mtInformation,[mbOK],0)
824 else
825 begin
826 IBDatabase1.Connected := false;
827 try
828 IBConfigService1.BringDatabaseOnline;
829 finally
830 IBDatabase1.Connected := true;
831 end;
832 if IsDatabaseOnline then
833 MessageDlg('Database is back online',mtInformation,[mbOK],0)
834 else
835 MessageDlg('Database is still shutdown!',mtError,[mbOK],0);
836 end;
837 end;
838
839 procedure TDBDataModule.ShutDown(aShutDownmode: TDBShutdownMode; aDelay: integer
840 );
841 begin
842 IBDatabase1.Connected := false;
843 try
844 ShutdownDatabaseDlg.Shutdown(aShutDownmode, aDelay);
845 finally
846 IBDatabase1.Connected := true;
847 end;
848 end;
849
850 procedure TDBDataModule.DatabaseRepair(Options: TValidateOptions; ReportLines: TStrings);
851
852 procedure ReportOptions;
853 var Line: string;
854 begin
855 Line := 'With Options: [';
856 if (ValidateDB in Options) then Line += 'ValidateDB ';
857 if (SweepDB in Options) then Line += 'SweepDB ';
858 if (KillShadows in Options) then Line += 'KillShadows ';
859 if (ValidateFull in Options) then Line += 'ValidateFull ';
860 if (CheckDB in Options) then Line += 'CheckDB ';
861 if (IgnoreChecksum in Options) then Line +='IgnoreChecksum ';
862 if (MendDB in Options) then Line +='MendDB ';
863 Line +=']';
864 ReportLines.Add(Line);
865 end;
866
867 begin
868 ReportLines.Add(Format('Validation of %s started',[IBValidationService1.DatabaseName]));
869 ReportOptions;
870 IBDatabase1.Connected := false;
871 with IBValidationService1 do
872 try
873 Execute(ReportLines);
874 ReportLines.Add('Operation Completed');
875 MessageDlg('Operation Completed',mtInformation,[mbOK],0);
876 finally
877 IBDatabase1.Connected := true;
878 end;
879 end;
880
881 procedure TDBDataModule.OnlineValidation(ReportLines: TStrings;
882 SelectedTablesOnly: boolean);
883 var TableNames: string;
884 Separator: string;
885 begin
886 if IBDatabaseInfo.ODSMajorVersion < 12 then
887 raise Exception.Create('Online Validation is not supported');
888 with IBOnlineValidationService1 do
889 begin
890 if SelectedTablesOnly then
891 begin
892 TableNames := '';
893 with DBTables do
894 if Active then
895 begin
896 DisableControls;
897 try
898 Separator := '';
899 First;
900 while not EOF do
901 begin
902 if FieldByName('Selected').AsInteger <> 0 then
903 begin
904 TableNames += Separator + FieldByName('RDB$RELATION_NAME').AsString;
905 Separator := '|';
906 end;
907 Next;
908 end;
909 finally
910 EnableControls;
911 end;
912 end;
913 IncludeTables := TableNames;
914 end
915 else
916 IncludeTables := '';
917 ReportLines.Add(Format('Online Validation of %s started',[IBOnlineValidationService1.DatabaseName]));
918 Execute(ReportLines);
919 ReportLines.Add('Online Validation Completed');
920 MessageDlg('Online Validation Completed',mtInformation,[mbOK],0);
921 end;
922 end;
923
924 procedure TDBDataModule.LimboResolution(ActionID: TTransactionGlobalAction;
925 Report: TStrings);
926 begin
927 if not InLimboList.Active then
928 raise Exception.Create('Limbo Transactions List not available');
929
930 with InLimboList do
931 if State = dsEdit then Post;
932 Report.Clear;
933 Report.Add('Starting Limbo transaction resolution');
934 InLimboList.FixErrors(ActionID,Report);
935 Report.Add('Limbo Transaction resolution complete');
936 CurrentTransaction.Commit;
937 end;
938
939 function TDBDataModule.GetLingerDelay: string;
940 var Linger: TField;
941 begin
942 Result := 'n/a';
943 if not DatabaseQuery.Active then exit;
944 Linger := DatabaseQuery.FindField('RDB$LINGER');
945 if Linger <> nil then
946 begin
947 if Linger.IsNull then
948 Result := '0'
949 else
950 Result := Linger.AsString;
951 end;
952 end;
953
954 function TDBDataModule.GetNoReserve: boolean;
955 begin
956 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$RESERVE_SPACE').AsInteger <> 0);
957 end;
958
959 function TDBDataModule.GetPageBuffers: integer;
960 begin
961 Result := IBDatabaseInfo.NumBuffers;
962 end;
963
964 function TDBDataModule.GetRoleName: string;
965 begin
966 Result := Trim(AttmtQuery.FieldByName('MON$ROLE').AsString);
967 end;
968
969 function TDBDataModule.GetSecurityDatabase: string;
970 var SecPlugin: TField;
971 begin
972 SecPlugin := DatabaseQuery.FindField('MON$SEC_DATABASE');
973 if SecPlugin = nil then
974 Result := 'Legacy'
975 else
976 Result := Trim(SecPlugin.AsString);
977 end;
978
979 function TDBDataModule.GetServerName: string;
980 begin
981 Result := IBXServicesConnection1.ServerName;
982 end;
983
984 function TDBDataModule.GetSweepInterval: integer;
985 begin
986 if DatabaseQuery.Active then
987 Result := DatabaseQuery.FieldByName('MON$SWEEP_INTERVAL').AsInteger
988 else
989 Result := 0;
990 end;
991
992 function TDBDataModule.GetUserAdminPrivilege: boolean;
993 begin
994 Result := false;
995 {For ODS 12 use SEC$USERS table}
996 if IBDatabase1.Connected and (IBDatabaseInfo.ODSMajorVersion >= 12) then
997 with AdminUserQuery do
998 begin
999 ExecQuery;
1000 try
1001 Result := not EOF and FieldByName('SEC$ADMIN').AsBoolean;
1002 finally
1003 Close;
1004 end;
1005 end
1006 {if need to know for ODS 11.2 then will have to use Service API}
1007 else
1008 begin
1009 with IBSecurityService1 do
1010 begin
1011 DisplayUser(ServiceUserName);
1012 Result := (UserInfoCount > 0) and UserInfo[0].AdminRole;
1013 end;
1014 end;
1015 end;
1016
1017 procedure TDBDataModule.SetAutoAdmin(AValue: boolean);
1018 begin
1019 IBSecurityService1.SetAutoAdmin(AValue);
1020 CurrentTransaction.Commit;
1021 end;
1022
1023 procedure TDBDataModule.SetDBReadOnly(AValue: boolean);
1024 begin
1025 IBDatabase1.Connected := false;
1026 try
1027 IBConfigService1.SetReadOnly(AValue);
1028 finally
1029 IBDatabase1.Connected := true;
1030 end;
1031 end;
1032
1033 procedure TDBDataModule.SetDBSQLDialect(AValue: integer);
1034 begin
1035 IBDatabase1.Connected := false;
1036 try
1037 IBConfigService1.SetDBSqlDialect(AValue);
1038 finally
1039 IBDatabase1.Connected := true;
1040 end;
1041 end;
1042
1043 procedure TDBDataModule.SetDescription(AValue: string);
1044 begin
1045 with TIBSQL.Create(IBDatabase1) do
1046 try
1047 SQL.Text := 'Comment on Database is ''' + SQLSafeString(AValue) + '''';
1048 Transaction.Active := true;
1049 ExecQuery;
1050 finally
1051 Free;
1052 end;
1053 CurrentTransaction.Commit;
1054 end;
1055
1056 procedure TDBDataModule.SetForcedWrites(AValue: boolean);
1057 begin
1058 IBConfigService1.SetAsyncMode(not AValue);
1059 end;
1060
1061 function TDBDataModule.IsDatabaseOnline: boolean;
1062 begin
1063 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$SHUTDOWN_MODE').AsInteger = 0);
1064 end;
1065
1066 function TDBDataModule.IsShadowDatabase: boolean;
1067 begin
1068 GetDBFlags;
1069 Result := FIsShadowDatabase;
1070 end;
1071
1072 procedure TDBDataModule.ActivateShadow;
1073 var DBConnected: boolean;
1074 begin
1075 DBConnected := IBDatabase1.Connected;
1076 IBDatabase1.Connected := false;
1077 try
1078 IBConfigService1.ActivateShadow;
1079 finally
1080 IBDatabase1.Connected := DBConnected;
1081 end;
1082 MessageDlg('Shadow Database activated. You should now rename the file or change the database alias name to point to the shadow',
1083 mtInformation,[mbOK],0);
1084 end;
1085
1086 procedure TDBDataModule.AddSecondaryFile(aFileName: string; StartAt,
1087 FileLength: integer);
1088 var SQLText: string;
1089 begin
1090 if FileLength <> -1 then
1091 SQLText := Format(sAddSecondarySQL2,[aFileName,StartAt,FileLength])
1092 else
1093 SQLText := Format(sAddSecondarySQL,[aFileName,StartAt]);
1094 ExecDDL.SQL.Text := SQLText;
1095 ExecDDL.ExecQuery;
1096 CurrentTransaction.Commit;
1097 end;
1098
1099 procedure TDBDataModule.AddShadowSet;
1100 var CurrentLocation: TBookmark;
1101 ShadowSet: integer;
1102 begin
1103 if ShadowFiles.RecordCount = 0 then
1104 ShadowSet := 1
1105 else
1106 with ShadowFiles do
1107 begin
1108 CurrentLocation := Bookmark;
1109 DisableControls;
1110 try
1111 Last;
1112 ShadowSet := FieldByName('RDB$Shadow_Number').AsInteger + 1;
1113 finally
1114 Bookmark := CurrentLocation;
1115 EnableControls
1116 end
1117 end;
1118 AddShadowSetDlg.ShowModal(ShadowSet);
1119 CurrentTransaction.Active := true;
1120 end;
1121
1122 procedure TDBDataModule.RemoveShadowSet(ShadowSet: integer);
1123 begin
1124 if IBDatabaseInfo.ODSMajorVersion < 12 then
1125 begin
1126 if MessageDlg(Format(sRemoveShadow,[ShadowSet]),mtConfirmation,[mbYes,mbNo],0) = mrYes then
1127 ExecDDL.SQL.Text := Format(sRemoveShadow,[ShadowSet]);
1128 end
1129 else
1130 case MessageDlg(Format(sPreserveShadowFiles,[ShadowSet]),mtConfirmation,[mbYes,mbNo,mbCancel],0) of
1131 mrNo:
1132 ExecDDL.SQL.Text :=Format(sRemoveShadow12,[ShadowSet]);
1133 mrYes:
1134 ExecDDL.SQL.Text := Format(sPreserveShadow,[ShadowSet]);
1135 mrCancel:
1136 Exit;
1137 end;
1138 ExecDDL.ExecQuery;
1139 CurrentTransaction.Commit;
1140 end;
1141
1142 procedure TDBDataModule.LoadPerformanceStatistics(Lines: TStrings);
1143
1144 procedure AddPerfStats(Heading: string; stats: TStrings);
1145 var i: integer;
1146 begin
1147 with Lines do
1148 begin
1149 if stats.count = 0 then exit;
1150 Add('');
1151 Add(Heading);
1152 for i := 0 to stats.Count - 1 do
1153 begin
1154 if TableNameLookup.Locate('RDB$RELATION_ID',stats.Names[i],[]) then
1155 Add(' ' + TableNameLookup.FieldByName('RDB$RELATION_NAME').AsString + ' = ' + stats.ValueFromIndex[i]);
1156 end;
1157 end;
1158 end;
1159
1160 begin
1161 TableNameLookup.Active := true;
1162 with IBDatabaseInfo, Lines do
1163 begin
1164 Add(Format('Number of reads from the memory buffer cache = %d',[Fetches]));
1165 Add(Format('Number of writes to the memory buffer cache = %d',[Marks]));
1166 Add(Format('Number of page reads = %d',[Reads]));
1167 Add(Format('Number of page writes = %d',[Writes]));
1168 Add('');
1169 Add('Since Database last attached:');
1170 AddPerfStats('Number of removals of a version of a record',BackoutCount);
1171 AddPerfStats('Number of database deletes',DeleteCount);
1172 AddPerfStats('Number of removals of a committed record',ExpungeCount);
1173 AddPerfStats('Number of inserts',InsertCount);
1174 AddPerfStats('Number of removals of old versions of fully mature records',PurgeCount);
1175 AddPerfStats('Number of reads done via an index',ReadIdxCount);
1176 AddPerfStats('Number of sequential table scans',ReadSeqCount);
1177 AddPerfStats('Number of database updates',UpdateCount);
1178 end;
1179 end;
1180
1181 procedure TDBDataModule.LoadDatabaseStatistics(OptionID: integer; Lines: TStrings);
1182 begin
1183 if OptionID = 1 then
1184 LoadPerformanceStatistics(Lines)
1185 else
1186 with IBStatisticalService1 do
1187 begin
1188 case OptionID of
1189 0: Options := [HeaderPages];
1190 2: options := [DataPages];
1191 3: Options := [IndexPages];
1192 4: Options := [SystemRelations]
1193 end;
1194 Execute(Lines);
1195 end;
1196 end;
1197
1198 function TDBDataModule.LoadConfigData(ConfigFileData: TConfigFileData): boolean;
1199 var i: integer;
1200 aValue: integer;
1201 begin
1202 ConfigDataset.Active := true;
1203 ConfigDataset.Clear(false);
1204 for i := 0 to Length(ConfigFileData.ConfigFileKey) - 1 do
1205 begin
1206 aValue := ConfigFileData.ConfigFileValue[i] ;
1207 with ConfigDataset do
1208 case ConfigFileData.ConfigFileKey[i] of
1209 ISCCFG_LOCKMEM_KEY:
1210 AppendRecord(['Lock mem', aValue]);
1211 ISCCFG_LOCKSEM_KEY:
1212 AppendRecord(['Lock Semaphores', aValue]);
1213 ISCCFG_LOCKSIG_KEY:
1214 AppendRecord(['Lock sig', aValue]);
1215 ISCCFG_EVNTMEM_KEY:
1216 AppendRecord(['Event mem', aValue]);
1217 ISCCFG_PRIORITY_KEY:
1218 AppendRecord(['Priority', aValue]);
1219 ISCCFG_MEMMIN_KEY:
1220 AppendRecord(['Min memory', aValue]);
1221 ISCCFG_MEMMAX_KEY:
1222 AppendRecord(['Max Memory', aValue]);
1223 ISCCFG_LOCKORDER_KEY:
1224 AppendRecord(['Lock order', aValue]);
1225 ISCCFG_ANYLOCKMEM_KEY:
1226 AppendRecord(['Any lock mem', aValue]);
1227 ISCCFG_ANYLOCKSEM_KEY:
1228 AppendRecord(['Any lock semaphore',aValue]);
1229 ISCCFG_ANYLOCKSIG_KEY:
1230 AppendRecord(['any lock sig', aValue]);
1231 ISCCFG_ANYEVNTMEM_KEY:
1232 AppendRecord(['any event mem', aValue]);
1233 ISCCFG_LOCKHASH_KEY:
1234 AppendRecord(['Lock hash', aValue]);
1235 ISCCFG_DEADLOCK_KEY:
1236 AppendRecord(['Deadlock', aValue]);
1237 ISCCFG_LOCKSPIN_KEY:
1238 AppendRecord(['Lock spin', aValue]);
1239 ISCCFG_CONN_TIMEOUT_KEY:
1240 AppendRecord(['Conn timeout', aValue]);
1241 ISCCFG_DUMMY_INTRVL_KEY:
1242 AppendRecord(['Dummy interval', aValue]);
1243 ISCCFG_IPCMAP_KEY:
1244 AppendRecord(['Map size', aValue]);
1245 ISCCFG_DBCACHE_KEY:
1246 AppendRecord(['Cache size', aValue]);
1247 end;
1248 end;
1249 Result := ConfigDataset.Active and (ConfigDataset.RecordCount > 0);
1250 end;
1251
1252 procedure TDBDataModule.LoadServerProperties(Lines: TStrings);
1253 var i: integer;
1254 begin
1255 Lines.Clear;
1256 with IBServerProperties1 do
1257 begin
1258 Lines.Add('Server Version = ' + VersionInfo.ServerVersion);
1259 Lines.Add('Server Implementation = ' + VersionInfo.ServerImplementation);
1260 Lines.Add('Service Version = ' + IntToStr(VersionInfo.ServiceVersion));
1261 with ServicesConnection do
1262 Lines.Add(Format('Firebird Release = %d.%d.%d (Build no. %d)',[ServerVersionNo[1],
1263 ServerVersionNo[2],
1264 ServerVersionNo[3],
1265 ServerVersionNo[4]]));
1266 Lines.Add('No. of attachments = ' + IntToStr(DatabaseInfo.NoOfAttachments));
1267 Lines.Add('No. of databases = ' + IntToStr(DatabaseInfo.NoOfDatabases));
1268 for i := 0 to length(DatabaseInfo.DbName) - 1 do
1269 Lines.Add(Format('DB Name (%d) = %s',[i+1, DatabaseInfo.DbName[i]]));
1270 Lines.Add('Base Location = ' + ConfigParams.BaseLocation);
1271 Lines.Add('Lock File Location = ' + ConfigParams.LockFileLocation);
1272 Lines.Add('Security Database Location = ' + ConfigParams.SecurityDatabaseLocation);
1273 Lines.Add('Message File Location = ' + ConfigParams.MessageFileLocation);
1274 end;
1275 end;
1276
1277 procedure TDBDataModule.LoadServerLog(Lines: TStrings);
1278 begin
1279 Lines.Clear;
1280 if IBLogService1.ServicesConnection.ServiceIntf.getProtocol = Local then
1281 Lines.Add('Server Log not available with embedded server')
1282 else
1283 IBLogService1.Execute(Lines);
1284 end;
1285
1286 procedure TDBDataModule.RevokeAll;
1287 begin
1288 with SubjectAccessRights do
1289 if Active then
1290 begin
1291 DisableControls;
1292 try
1293 First;
1294 while not EOF do
1295 begin
1296 if FieldByName('OBJECT_TYPE').AsInteger = 0 {relation} then
1297 ExecDDL.SQL.Text := Format('Revoke All on %s from %s',[
1298 Trim(FieldByName('OBJECT_NAME').AsString),
1299 Trim(FieldByName('SUBJECT_NAME').AsString)])
1300 else
1301 if FieldByName('OBJECT_TYPE').AsInteger = 13 {role} then
1302 ExecDDL.SQL.Text := Format('Revoke %s from %s',[
1303 Trim(FieldByName('OBJECT_NAME').AsString),
1304 Trim(FieldByName('SUBJECT_NAME').AsString)])
1305 else
1306 ExecDDL.SQL.Text := Format('Revoke All on %s %s from %s',[
1307 Trim(FieldByName('OBJECT_TYPE_NAME').AsString),
1308 Trim(FieldByName('OBJECT_NAME').AsString),
1309 Trim(FieldByName('SUBJECT_NAME').AsString)]);
1310 ExecDDL.ExecQuery;
1311 Next;
1312 end;
1313 finally
1314 EnableControls;
1315 end;
1316 CurrentTransaction.Commit;
1317 end;
1318 end;
1319
1320 procedure TDBDataModule.SyncSubjectAccessRights(ID: string);
1321 begin
1322 if (FSubjectAccessRightsID = ID) and SubjectAccessRights.Active then Exit;
1323 SubjectAccessRights.Active := false;
1324 FSubjectAccessRightsID := ID;
1325 SubjectAccessRights.Active := true;
1326 end;
1327
1328 procedure TDBDataModule.IBDatabase1Login(Database: TIBDatabase;
1329 LoginParams: TStrings);
1330 var aDatabaseName: string;
1331 aUserName: string;
1332 aPassword: string;
1333 aCreateIfNotExist: boolean;
1334 begin
1335 if FLocalConnect or (FDBPassword <> '') {reconnect} then
1336 begin
1337 LoginParams.Values['user_name'] := FDBUserName;
1338 LoginParams.Values['password'] := FDBPassword;
1339 exit;
1340 end;
1341
1342 aDatabaseName := Database.DatabaseName;
1343 aUserName := LoginParams.Values['user_name'];
1344 aPassword := '';
1345 aCreateIfNotExist := false;
1346 if CallLoginDlg(aDatabaseName, aUserName, aPassword, aCreateIfNotExist) = mrOK then
1347 begin
1348 FDBPassword := aPassword; {remember for reconnect}
1349 Database.DatabaseName := aDatabaseName;
1350 LoginParams.Values['user_name'] := aUserName;
1351 LoginParams.Values['password'] := aPassword;
1352 FDBUserName := aUserName;
1353 FDBPassword := aPassword;
1354 Database.CreateIfNotExists := aCreateIfNotExist;
1355 ParseConnectString(aDatabaseName,FServerName,FDatabasePathName,FProtocol,FPortNo);
1356 end
1357 else
1358 IBError(ibxeOperationCancelled, [nil]);
1359 end;
1360
1361 procedure TDBDataModule.AttUpdateApplyUpdates(Sender: TObject;
1362 UpdateKind: TUpdateKind; Params: ISQLParams);
1363 begin
1364 if UpdateKind = ukDelete then
1365 begin
1366 ExecDDL.SQL.Text := 'Delete from MON$ATTACHMENTS Where MON$ATTACHMENT_ID =' +
1367 Params.ByName('MON$ATTACHMENT_ID').Asstring;
1368 ExecDDL.ExecQuery;
1369 end;
1370 end;
1371
1372 procedure TDBDataModule.DBTablesUpdateApplyUpdates(Sender: TObject;
1373 UpdateKind: TUpdateKind; Params: ISQLParams);
1374 begin
1375 // Do nothing
1376 end;
1377
1378 procedure TDBDataModule.IBValidationService1GetNextLine(Sender: TObject;
1379 var Line: string);
1380 begin
1381 Application.ProcessMessages;
1382 end;
1383
1384 procedure TDBDataModule.IBXServicesConnection1AfterConnect(Sender: TObject);
1385 var UN: ISPBItem;
1386 begin
1387 UN := IBXServicesConnection1.ServiceIntf.getSPB.Find(isc_spb_user_name);
1388 if UN <> nil then
1389 FServiceUserName := UN.AsString;
1390 end;
1391
1392 procedure TDBDataModule.IBXServicesConnection1Login(
1393 Service: TIBXServicesConnection; var aServerName: string; LoginParams: TStrings);
1394 begin
1395 LoginParams.Values['user_name'] := FDBUserName;
1396 LoginParams.Values['password'] := FDBPassword;
1397 end;
1398
1399 procedure TDBDataModule.LegacyUserListAfterOpen(DataSet: TDataSet);
1400 begin
1401 if UserListSource.DataSet <> LegacyUserList then
1402 UserListSource.DataSet := LegacyUserList;
1403 if IBDatabase1.Connected then
1404 begin
1405 CurrentTransaction.Active := true;
1406 RoleNameList.Active := true;
1407 end;
1408 end;
1409
1410 procedure TDBDataModule.LegacyUserListAfterPost(DataSet: TDataSet);
1411 begin
1412 if IBDatabase1.Connected then
1413 RoleNameList.Active := true;
1414 end;
1415
1416 procedure TDBDataModule.LegacyUserListBeforeClose(DataSet: TDataSet);
1417 begin
1418 RoleNameList.Active := false;
1419 end;
1420
1421 procedure TDBDataModule.ShadowFilesCalcFields(DataSet: TDataSet);
1422 var Flags: integer;
1423 begin
1424 Flags := DataSet.FieldByName('RDB$FILE_FLAGS').AsInteger;
1425 if Flags and $10 <> 0 then
1426 DataSet.FieldByName('FileMode').AsString := 'C'
1427 else
1428 if Flags and $04 <> 0 then
1429 DataSet.FieldByName('FileMode').AsString := 'M'
1430 else
1431 if Flags and $01 <> 0 then
1432 if DataSet.FieldByName('RDB$FILE_SEQUENCE').AsInteger = 0 then
1433 DataSet.FieldByName('FileMode').AsString := 'A'
1434 else
1435 DataSet.FieldByName('FileMode').AsString := '+'
1436 else
1437 DataSet.FieldByName('FileMode').AsString := ''
1438 end;
1439
1440 procedure TDBDataModule.SubjectAccessRightsBeforeOpen(DataSet: TDataSet);
1441 begin
1442 SubjectAccessRights.ParamByName('ID').AsString := FSubjectAccessRightsID;
1443 end;
1444
1445 procedure TDBDataModule.TagsUpdateApplyUpdates(Sender: TObject;
1446 UpdateKind: TUpdateKind; Params: ISQLParams);
1447 var sql: string;
1448 begin
1449 sql := '';
1450 case UpdateKind of
1451 ukInsert,
1452 ukModify:
1453 begin
1454 sql := 'ALTER USER ' + Trim(Params.ByName('SEC$USER_NAME').AsString)
1455 + ' TAGS (' + QuoteIdentifierIfNeeded(IBDatabase1.SQLDialect,Params.ByName('SEC$KEY').AsString)
1456 + '=''' + SQLSafeString(Params.ByName('SEC$VALUE').AsString) + '''';
1457 if Params.ByName('SEC$KEY').AsString <> Params.ByName('OLD_SEC$KEY').AsString then
1458 sql += ', DROP ' + QuoteIdentifierIfNeeded(IBDatabase1.SQLDialect,Params.ByName('OLD_SEC$KEY').AsString);
1459 sql +=')'
1460 end;
1461
1462 ukDelete:
1463 sql := 'ALTER USER ' + Trim(Params.ByName('SEC$USER_NAME').AsString)
1464 + ' TAGS (DROP ' + QuoteIdentifierIfNeeded(IBDatabase1.SQLDialect,Params.ByName('SEC$KEY').AsString) + ')';
1465 end;
1466 ExecDDL.SQL.Text := sql;
1467 ExecDDL.ExecQuery;
1468 end;
1469
1470 procedure TDBDataModule.IBDatabase1AfterConnect(Sender: TObject);
1471 begin
1472 {Virtual tables did not exist prior to Firebird 2.1 - so don't bother with old version}
1473 with IBDatabaseInfo do
1474 if (ODSMajorVersion < 11) or ((ODSMajorVersion = 11) and (ODSMinorVersion < 1)) then
1475 begin
1476 IBDatabase1.Connected := false;
1477 raise Exception.Create('This application requires Firebird 2.1 or later');
1478 end
1479 else
1480 if ODSMajorVersion < 12 then
1481 {Don't expect to be able to find these fields}
1482 begin
1483 AttachmentsMONCLIENT_VERSION.FieldKind := fkCalculated;
1484 AttachmentsMONREMOTE_VERSION.FieldKind := fkCalculated;
1485 AttachmentsMONREMOTE_HOST.FieldKind := fkCalculated;
1486 AttachmentsMONREMOTE_OS_USER.FieldKind := fkCalculated;
1487 AttachmentsMONAUTH_METHOD.FieldKind := fkCalculated;
1488 AttachmentsMONSYSTEM_FLAG.FieldKind := fkCalculated;
1489 AttachmentsRDBSECURITY_CLASS.FieldKind := fkCalculated;
1490 AttachmentsRDBOWNER_NAME.FieldKind := fkCalculated;
1491 end
1492 else
1493 begin
1494 AttachmentsMONCLIENT_VERSION.FieldKind := fkData;
1495 AttachmentsMONREMOTE_VERSION.FieldKind := fkData;
1496 AttachmentsMONREMOTE_HOST.FieldKind := fkData;
1497 AttachmentsMONREMOTE_OS_USER.FieldKind := fkData;
1498 AttachmentsMONAUTH_METHOD.FieldKind := fkData;
1499 AttachmentsMONSYSTEM_FLAG.FieldKind := fkData;
1500 AttachmentsRDBSECURITY_CLASS.FieldKind := fkData;
1501 AttachmentsRDBOWNER_NAME.FieldKind := fkData;
1502 end;
1503
1504 FLocalConnect := FProtocol = Local;
1505 ConnectServicesAPI;
1506 CurrentTransaction.Active := true;
1507 FHasUserAdminPrivilege := GetUserAdminPrivilege;
1508 ReloadData;
1509 end;
1510
1511 procedure TDBDataModule.IBDatabase1AfterDisconnect(Sender: TObject);
1512 begin
1513 FDisconnecting := false;
1514 end;
1515
1516 procedure TDBDataModule.IBDatabase1BeforeDisconnect(Sender: TObject);
1517 begin
1518 FDBHeaderScanned := false;
1519 FDisconnecting := true;
1520 end;
1521
1522 procedure TDBDataModule.DatabaseQueryAfterOpen(DataSet: TDataSet);
1523 begin
1524 DBCharSet.Active := true;
1525 end;
1526
1527 procedure TDBDataModule.CurrentTransactionAfterTransactionEnd(Sender: TObject);
1528 begin
1529 if not Disconnecting and not (csDestroying in ComponentState) then
1530 begin
1531 CurrentTransaction.Active := true;
1532 Application.QueueAsyncCall(@ReloadData,0);
1533 end;
1534 end;
1535
1536 procedure TDBDataModule.ApplicationProperties1Exception(Sender: TObject;
1537 E: Exception);
1538 begin
1539 if E is EIBInterBaseError then
1540 begin
1541 if RoleNameList.State in [dsInsert,dsEdit] then
1542 RoleNameList.Cancel;
1543 if UserList.State in [dsInsert,dsEdit] then
1544 UserList.Cancel;
1545 end;
1546 MessageDlg(E.Message,mtError,[mbOK],0);
1547 if CurrentTransaction.Active then
1548 CurrentTransaction.Rollback;
1549 end;
1550
1551 procedure TDBDataModule.AccessRightsCalcFields(DataSet: TDataSet);
1552 begin
1553 AccessRightsDisplayName.AsString := AccessRightsSUBJECT_NAME.AsString;
1554 if AccessRightsSUBJECT_TYPE.AsInteger = 8 then
1555 begin
1556 if (AccessRightsSUBJECT_NAME.AsString <> 'PUBLIC') and UserListSource.DataSet.Active and
1557 not UserListSource.DataSet.Locate('SEC$USER_NAME',AccessRightsSUBJECT_NAME.AsString,[]) then
1558 begin
1559 AccessRightsImageIndex.AsInteger := 4;
1560 AccessRightsDisplayName.AsString := AccessRightsSUBJECT_NAME.AsString + ' (stale)';
1561 end
1562 else
1563 AccessRightsImageIndex.AsInteger := -1
1564 end
1565 else
1566 AccessRightsImageIndex.AsInteger := -1;
1567 end;
1568
1569 procedure TDBDataModule.AttachmentsAfterDelete(DataSet: TDataSet);
1570 begin
1571 CurrentTransaction.Commit;
1572 end;
1573
1574 procedure TDBDataModule.AttachmentsAfterOpen(DataSet: TDataSet);
1575 begin
1576 Attachments.Locate('MON$ATTACHMENT_ID',AttmtQuery.FieldByName('MON$ATTACHMENT_ID').AsInteger,[]);
1577 end;
1578
1579 procedure TDBDataModule.AttachmentsBeforeOpen(DataSet: TDataSet);
1580 begin
1581 if IBDatabaseInfo.ODSMajorVersion >= 12 then
1582 (DataSet as TIBQuery).Parser.Add2WhereClause('r.MON$SYSTEM_FLAG = 0');
1583 end;
1584
1585 procedure TDBDataModule.ConfigDatasetAfterClose(DataSet: TDataSet);
1586 begin
1587 ConfigDataset.Clear(false);
1588 end;
1589
1590 procedure TDBDataModule.DatabaseQueryBeforeClose(DataSet: TDataSet);
1591 begin
1592 DBCharSet.Active := false;
1593 end;
1594
1595 procedure TDBDataModule.DBCharSetAfterClose(DataSet: TDataSet);
1596 begin
1597 CharSetLookup.Active := false;
1598 end;
1599
1600 procedure TDBDataModule.DBCharSetBeforeOpen(DataSet: TDataSet);
1601 begin
1602 CharSetLookup.Active := true;
1603 end;
1604
1605 end.
1606

Properties

Name Value
svn:eol-style native