ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/examples/DBAdmin/DataModule.pas
Revision: 291
Committed: Fri Apr 17 10:26:08 2020 UTC (4 years ago) by tony
Content type: text/x-pascal
File size: 50218 byte(s)
Log Message:
Changed for 2.3.4 merged into public release

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: TIBLargeIntField;
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 end
415 else
416 if UpdateKind = ukModify then
417 {Update Admin Role if allowed}
418 begin
419 if Params.ByName('SEC$ADMIN').AsBoolean and not Params.ByName('OLD_SEC$ADMIN').AsBoolean then
420 begin
421 ExecDDL.SQL.Text := 'ALTER USER ' + UserName + ' GRANT ADMIN ROLE';
422 ExecDDL.ExecQuery;
423 end
424 else
425 if not Params.ByName('SEC$ADMIN').AsBoolean and Params.ByName('OLD_SEC$ADMIN').AsBoolean then
426 begin
427 ExecDDL.SQL.Text := 'ALTER USER ' + UserName + ' REVOKE ADMIN ROLE';
428 ExecDDL.ExecQuery;
429 end
430 end;
431
432 {Update DB Creator Role}
433 if Params.ByName('DBCreator').AsBoolean and not Params.ByName('OLD_DBCreator').AsBoolean then
434 begin
435 ExecDDL.SQL.Text := 'GRANT CREATE DATABASE TO USER ' + UserName;
436 ExecDDL.ExecQuery;
437 end
438 else
439 if not Params.ByName('DBCreator').AsBoolean and Params.ByName('OLD_DBCreator').AsBoolean then
440 begin
441 ExecDDL.SQL.Text := 'REVOKE CREATE DATABASE FROM USER ' + UserName;
442 ExecDDL.ExecQuery;
443 end
444 end;
445
446 procedure TDBDataModule.UserListAfterInsert(DataSet: TDataSet);
447 begin
448 DataSet.FieldByName('SEC$ADMIN').AsBoolean := false;
449 DataSet.FieldByName('SEC$ACTIVE').AsBoolean := false;
450 DataSet.FieldByName('DBCreator').AsBoolean := false;
451 DataSet.FieldByName('SEC$PLUGIN').AsString := 'Srp';
452 DataSet.FieldByName('UserID').AsInteger := 0;
453 DataSet.FieldByName('GroupID').AsInteger := 0;
454 DataSet.FieldByName('SEC$PASSWORD').Clear;
455 RoleNameList.Active := false; {Prevent role assignments until saved}
456 UserTags.Active := false; {ditto}
457 end;
458
459 procedure TDBDataModule.UserListAfterOpen(DataSet: TDataSet);
460 begin
461 UserListSource.DataSet := UserList;
462 RoleNameList.Active := true;
463 UserTags.Active := true;
464 end;
465
466 procedure TDBDataModule.UserListAfterPost(DataSet: TDataSet);
467 begin
468 CurrentTransaction.Commit;
469 end;
470
471 procedure TDBDataModule.UserListAfterScroll(DataSet: TDataSet);
472 begin
473 UserList.FieldByName('SEC$PLUGIN').ReadOnly := UserList.State <> dsInsert;
474 end;
475
476 procedure TDBDataModule.UserListBeforeClose(DataSet: TDataSet);
477 begin
478 RoleNameList.Active := false;
479 UserTags.Active := false;
480 end;
481
482 procedure TDBDataModule.UserTagsAfterInsert(DataSet: TDataSet);
483 begin
484 DataSet.FieldByName('SEC$USER_NAME').AsString := DataSet.DataSource.DataSet.FieldByName('SEC$USER_NAME').AsString;
485 end;
486
487 procedure TDBDataModule.ConnectServicesAPI;
488 begin
489 if IBXServicesConnection1.Connected then Exit;
490 try
491 IBXServicesConnection1.ConnectUsing(IBDatabase1);
492 except on E: Exception do
493 begin
494 Application.ShowException(E);
495 IBDatabase1.Connected := false;
496 FDBPassword := '';
497 Exit;
498 end;
499 end;
500 end;
501
502 function TDBDataModule.CallLoginDlg(var aDatabaseName, aUserName,
503 aPassword: string; var aCreateIfNotExist: boolean): TModalResult;
504 begin
505 Result := DBLoginDlg.ShowModal(aDatabaseName, aUserName, aPassword, aCreateIfNotExist);
506 end;
507
508 procedure TDBDataModule.GetDBFlags;
509 var Lines: TStringList;
510 i: integer;
511 line: string;
512 begin
513 if FDBHeaderScanned or not DatabaseQuery.Active or not AttmtQuery.Active then Exit;
514 FIsShadowDatabase := false;
515
516 try
517 with IBStatisticalService1 do
518 begin
519 Options := [HeaderPages];
520 Lines := TStringList.Create;
521 try
522 Execute(Lines);
523 for i := 0 to Lines.Count - 1 do
524 begin
525 line := Lines[i];
526 if (Pos('Attributes',Line) <> 0) and (Pos('shadow',Line) <> 0) then
527 begin
528 FIsShadowDatabase := true;
529 break;
530 end;
531 end;
532 finally
533 Lines.Free;
534 end;
535 FDBHeaderScanned := true;
536 end;
537 except on E: Exception do
538 MessageDlg('Error getting DB Header Page: ' + E.Message,mtError,[mbOK],0);
539 end;
540 end;
541
542 function TDBDataModule.GetDBOwner: string;
543 var DBOField: TField;
544 begin
545 DBOField := DatabaseQuery.FindField('MON$OWNER');
546 if DBOField <> nil then
547 Result := Trim(DBOField.AsString)
548 else
549 Result := 'n/a';
550 end;
551
552 function TDBDataModule.GetAutoAdmin: boolean;
553 begin
554 Result := false;
555 if not CurrentTransaction.Active then Exit;
556 SecGlobalAuth.Active := true; {sets AutoAdmin}
557 try
558 Result := SecGlobalAuth.FieldByName('Mappings').AsInteger > 0;
559 finally
560 SecGlobalAuth.Active := false;
561 end;
562 end;
563
564 function TDBDataModule.GetDatabaseName: string;
565 begin
566 if DatabaseQuery.Active and not DatabaseQuery.FieldByName('MON$DATABASE_NAME').IsNull then
567 Result := DatabaseQuery.FieldByName('MON$DATABASE_NAME').AsString
568 else
569 Result := FDatabasePathName;
570 end;
571
572 function TDBDataModule.GetDBDateCreated: string;
573 begin
574 with DefaultFormatSettings do
575 try
576 Result := FormatDateTime(LongDateFormat + ' ' + LongTimeFormat,DatabaseQuery.FieldByName('MON$CREATION_DATE').AsDateTime);
577 except
578 Result := 'unknown';
579 end;
580 end;
581
582 function TDBDataModule.GetDBReadOnly: boolean;
583 begin
584 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$READ_ONLY').AsInteger <> 0);
585 end;
586
587 function TDBDataModule.GetDBSQLDialect: integer;
588 begin
589 Result := IBDatabaseInfo.DBSQLDialect;
590 end;
591
592 function TDBDataModule.GetDBUserName: string;
593 var DPB: IDPB;
594 info: IDPBItem;
595 begin
596 Result := '';
597 if AttmtQuery.Active then
598 Result := Trim(AttmtQuery.FieldByName('MON$USER').AsString)
599 else
600 if IBDatabase1.Connected then
601 begin
602 DPB := IBDatabase1.Attachment.getDPB;
603 info := DPB.Find(isc_dpb_user_name);
604 if info <> nil then
605 Result := info.AsString;
606 end
607 end;
608
609 function TDBDataModule.GetDescription: string;
610 begin
611 if DatabaseQuery.Active then
612 Result := DatabaseQuery.FieldByName('RDB$DESCRIPTION').AsString
613 else
614 Result := '';
615 end;
616
617 function TDBDataModule.GetEmbeddedMode: boolean;
618 begin
619 Result := AttmtQuery.Active and AttmtQuery.FieldByName('MON$REMOTE_PROTOCOL').IsNull;
620 end;
621
622 function TDBDataModule.GetForcedWrites: boolean;
623 begin
624 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$FORCED_WRITES').AsInteger <> 0);
625 end;
626
627 procedure TDBDataModule.SetLingerDelay(AValue: string);
628 begin
629 if (StrToInt(AValue) = DatabaseQuery.FieldByName('RDB$LINGER').AsInteger) then Exit;
630
631 if (AValue = '') or (StrToInt(AValue) = 0) then
632 begin
633 if MessageDlg('Turn off Linger Permanently?',mtConfirmation,[mbYes,mbNo],0) = mrNo then
634 begin
635 IBConfigService1.SetNoLinger;
636 CurrentTransaction.Commit; {Refresh}
637 Exit;
638 end;
639 ExecDDL.SQL.Text := 'ALTER DATABASE DROP LINGER'
640 end
641 else
642 ExecDDL.SQL.Text := 'ALTER DATABASE SET LINGER TO ' + AValue;
643 with ExecDDL do
644 begin
645 Transaction.Active := true;
646 ExecQuery;
647 Transaction.Commit;
648 end;
649 end;
650
651
652 function TDBDataModule.GetAuthMethod: string;
653 var AuthMeth: TField;
654 begin
655 AuthMeth := AttmtQuery.FindField('MON$AUTH_METHOD');
656 if AuthMeth = nil then
657 Result := 'Legacy_auth'
658 else
659 Result := AuthMeth.AsString;
660 end;
661
662 procedure TDBDataModule.SetNoReserve(AValue: boolean);
663 begin
664 IBConfigService1.SetReserveSpace(AValue);
665 end;
666
667 procedure TDBDataModule.SetPageBuffers(AValue: integer);
668 begin
669 IBDatabase1.Connected := false;
670 try
671 IBConfigService1.SetPageBuffers(AValue);
672 finally
673 IBDatabase1.Connected := true;
674 end;
675 end;
676
677 procedure TDBDataModule.SetSweepInterval(AValue: integer);
678 begin
679 IBDatabase1.Connected := false;
680 try
681 IBConfigService1.SetSweepInterval(AValue);
682 finally
683 IBDatabase1.Connected := true;
684 end;
685 end;
686
687 procedure TDBDataModule.ReloadData(Data: PtrInt);
688 begin
689 if csDestroying in ComponentState then Exit;
690 CurrentTransaction.Active := true;
691 DataBaseQuery.Active := true;
692 AttmtQuery.Active := true;
693 if LegacyUserList.Active then
694 RoleNameList.Active := true;
695 if assigned(FAfterDataReload) then
696 AfterDataReload(self);
697 end;
698
699 destructor TDBDataModule.Destroy;
700 begin
701 Application.RemoveAsyncCalls(self);
702 inherited Destroy;
703 end;
704
705 function TDBDataModule.Connect: boolean;
706
707 procedure ReportException(E: Exception);
708 begin
709 MessageDlg(E.Message,mtError,[mbOK],0);
710 FDBPassword := '';
711 end;
712
713 procedure KillShadows;
714 begin
715 with IBXServicesConnection1 do
716 begin
717 ServerName := FServerName;
718 Protocol := FProtocol;
719 PortNo := FPortNo;
720 Connected := true;
721 end;
722 try
723 with IBValidationService1 do
724 begin
725 DatabaseName := FDatabasePathName;
726 Options := [IBXServices.KillShadows];
727 Execute(nil);
728 MessageDlg('All Unavailable Shadows killed',mtInformation,[mbOK],0);
729 end;
730 finally
731 IBXServicesConnection1.Connected := false;
732 end;
733 end;
734
735 var KillDone: boolean;
736 begin
737 KillDone := false;
738 Result := false;
739 Disconnect;
740 repeat
741 try
742 IBDatabase1.Connected := true;
743 except
744 on E:EIBClientError do
745 begin
746 Exit
747 end;
748 On E: EIBInterBaseError do
749 begin
750 FDBPassword := '';
751 if (E.IBErrorCode = isc_io_error) and not KillDone then
752 begin
753 if MessageDlg('I/O Error reported on database file. If this is a shadow file, do you want '+
754 'to kill all unavailable shadow sets?. The original message is ' + E.Message,
755 mtInformation,[mbYes,mbNo],0) = mrNo then
756 continue;
757 try KillShadows except end;
758 KillDone := true;
759 end
760 else
761 ReportException(E);
762 end;
763 On E:Exception do
764 ReportException(E);
765 end;
766 until IBDatabase1.Connected;
767
768 if assigned(FAfterDBConnect) then
769 AfterDBConnect(self);
770 Result := IBDatabase1.Connected;
771 end;
772
773 procedure TDBDataModule.Disconnect;
774 begin
775 FDBUserName := '';
776 FDBPassword := '';
777 FServiceUserName := '';
778 FLocalConnect := false;
779 IBDatabase1.Connected := false;
780 IBXServicesConnection1.Connected := false;
781 FDBHeaderScanned := false;
782 end;
783
784 procedure TDBDataModule.DropDatabase;
785 begin
786 IBDatabase1.DropDatabase;
787 Disconnect;
788 end;
789
790 procedure TDBDataModule.BackupDatabase;
791 begin
792 BackupDlg.ShowModal;
793 end;
794
795 procedure TDBDataModule.RestoreDatabase;
796 var DefaultPageSize: integer;
797 DefaultNumBuffers: integer;
798 begin
799 DefaultPageSize := DatabaseQuery.FieldByName('MON$PAGE_SIZE').AsInteger;
800 DefaultNumBuffers := DatabaseQuery.FieldByName('MON$PAGE_BUFFERS').AsInteger;
801 IBDatabase1.Connected := false;
802 try
803 RestoreDlg.ShowModal(DefaultPageSize,DefaultNumBuffers);
804 finally
805 IBDatabase1.Connected := true;
806 end;
807 end;
808
809 procedure TDBDataModule.BringDatabaseOnline;
810 begin
811 if IsDatabaseOnline then
812 MessageDlg('Database is already online!',mtInformation,[mbOK],0)
813 else
814 begin
815 IBDatabase1.Connected := false;
816 try
817 IBConfigService1.BringDatabaseOnline;
818 finally
819 IBDatabase1.Connected := true;
820 end;
821 if IsDatabaseOnline then
822 MessageDlg('Database is back online',mtInformation,[mbOK],0)
823 else
824 MessageDlg('Database is still shutdown!',mtError,[mbOK],0);
825 end;
826 end;
827
828 procedure TDBDataModule.ShutDown(aShutDownmode: TDBShutdownMode; aDelay: integer
829 );
830 begin
831 IBDatabase1.Connected := false;
832 try
833 ShutdownDatabaseDlg.Shutdown(aShutDownmode, aDelay);
834 finally
835 IBDatabase1.Connected := true;
836 end;
837 end;
838
839 procedure TDBDataModule.DatabaseRepair(Options: TValidateOptions; ReportLines: TStrings);
840
841 procedure ReportOptions;
842 var Line: string;
843 begin
844 Line := 'With Options: [';
845 if (ValidateDB in Options) then Line += 'ValidateDB ';
846 if (SweepDB in Options) then Line += 'SweepDB ';
847 if (KillShadows in Options) then Line += 'KillShadows ';
848 if (ValidateFull in Options) then Line += 'ValidateFull ';
849 if (CheckDB in Options) then Line += 'CheckDB ';
850 if (IgnoreChecksum in Options) then Line +='IgnoreChecksum ';
851 if (MendDB in Options) then Line +='MendDB ';
852 Line +=']';
853 ReportLines.Add(Line);
854 end;
855
856 begin
857 ReportLines.Add(Format('Validation of %s started',[IBValidationService1.DatabaseName]));
858 ReportOptions;
859 IBDatabase1.Connected := false;
860 with IBValidationService1 do
861 try
862 Execute(ReportLines);
863 ReportLines.Add('Operation Completed');
864 MessageDlg('Operation Completed',mtInformation,[mbOK],0);
865 finally
866 IBDatabase1.Connected := true;
867 end;
868 end;
869
870 procedure TDBDataModule.OnlineValidation(ReportLines: TStrings;
871 SelectedTablesOnly: boolean);
872 var TableNames: string;
873 Separator: string;
874 begin
875 if IBDatabaseInfo.ODSMajorVersion < 12 then
876 raise Exception.Create('Online Validation is not supported');
877 with IBOnlineValidationService1 do
878 begin
879 if SelectedTablesOnly then
880 begin
881 TableNames := '';
882 with DBTables do
883 if Active then
884 begin
885 DisableControls;
886 try
887 Separator := '';
888 First;
889 while not EOF do
890 begin
891 if FieldByName('Selected').AsInteger <> 0 then
892 begin
893 TableNames += Separator + FieldByName('RDB$RELATION_NAME').AsString;
894 Separator := '|';
895 end;
896 Next;
897 end;
898 finally
899 EnableControls;
900 end;
901 end;
902 IncludeTables := TableNames;
903 end
904 else
905 IncludeTables := '';
906 ReportLines.Add(Format('Online Validation of %s started',[IBOnlineValidationService1.DatabaseName]));
907 Execute(ReportLines);
908 ReportLines.Add('Online Validation Completed');
909 MessageDlg('Online Validation Completed',mtInformation,[mbOK],0);
910 end;
911 end;
912
913 procedure TDBDataModule.LimboResolution(ActionID: TTransactionGlobalAction;
914 Report: TStrings);
915 begin
916 if not InLimboList.Active then
917 raise Exception.Create('Limbo Transactions List not available');
918
919 with InLimboList do
920 if State = dsEdit then Post;
921 Report.Clear;
922 Report.Add('Starting Limbo transaction resolution');
923 InLimboList.FixErrors(ActionID,Report);
924 Report.Add('Limbo Transaction resolution complete');
925 CurrentTransaction.Commit;
926 end;
927
928 function TDBDataModule.GetLingerDelay: string;
929 var Linger: TField;
930 begin
931 Result := 'n/a';
932 if not DatabaseQuery.Active then exit;
933 Linger := DatabaseQuery.FindField('RDB$LINGER');
934 if Linger <> nil then
935 begin
936 if Linger.IsNull then
937 Result := '0'
938 else
939 Result := Linger.AsString;
940 end;
941 end;
942
943 function TDBDataModule.GetNoReserve: boolean;
944 begin
945 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$RESERVE_SPACE').AsInteger <> 0);
946 end;
947
948 function TDBDataModule.GetPageBuffers: integer;
949 begin
950 Result := IBDatabaseInfo.NumBuffers;
951 end;
952
953 function TDBDataModule.GetRoleName: string;
954 begin
955 Result := Trim(AttmtQuery.FieldByName('MON$ROLE').AsString);
956 end;
957
958 function TDBDataModule.GetSecurityDatabase: string;
959 var SecPlugin: TField;
960 begin
961 SecPlugin := DatabaseQuery.FindField('MON$SEC_DATABASE');
962 if SecPlugin = nil then
963 Result := 'Legacy'
964 else
965 Result := Trim(SecPlugin.AsString);
966 end;
967
968 function TDBDataModule.GetServerName: string;
969 begin
970 Result := IBXServicesConnection1.ServerName;
971 end;
972
973 function TDBDataModule.GetSweepInterval: integer;
974 begin
975 if DatabaseQuery.Active then
976 Result := DatabaseQuery.FieldByName('MON$SWEEP_INTERVAL').AsInteger
977 else
978 Result := 0;
979 end;
980
981 function TDBDataModule.GetUserAdminPrivilege: boolean;
982 begin
983 Result := false;
984 {For ODS 12 use SEC$USERS table}
985 if IBDatabase1.Connected and (IBDatabaseInfo.ODSMajorVersion >= 12) then
986 with AdminUserQuery do
987 begin
988 ExecQuery;
989 try
990 Result := not EOF and FieldByName('SEC$ADMIN').AsBoolean;
991 finally
992 Close;
993 end;
994 end
995 {if need to know for ODS 11.2 then will have to use Service API}
996 else
997 begin
998 with IBSecurityService1 do
999 begin
1000 DisplayUser(ServiceUserName);
1001 Result := (UserInfoCount > 0) and UserInfo[0].AdminRole;
1002 end;
1003 end;
1004 end;
1005
1006 procedure TDBDataModule.SetAutoAdmin(AValue: boolean);
1007 begin
1008 IBSecurityService1.SetAutoAdmin(AValue);
1009 CurrentTransaction.Commit;
1010 end;
1011
1012 procedure TDBDataModule.SetDBReadOnly(AValue: boolean);
1013 begin
1014 IBDatabase1.Connected := false;
1015 try
1016 IBConfigService1.SetReadOnly(AValue);
1017 finally
1018 IBDatabase1.Connected := true;
1019 end;
1020 end;
1021
1022 procedure TDBDataModule.SetDBSQLDialect(AValue: integer);
1023 begin
1024 IBDatabase1.Connected := false;
1025 try
1026 IBConfigService1.SetDBSqlDialect(AValue);
1027 finally
1028 IBDatabase1.Connected := true;
1029 end;
1030 end;
1031
1032 procedure TDBDataModule.SetDescription(AValue: string);
1033 begin
1034 with TIBSQL.Create(IBDatabase1) do
1035 try
1036 SQL.Text := 'Comment on Database is ''' + SQLSafeString(AValue) + '''';
1037 Transaction.Active := true;
1038 ExecQuery;
1039 finally
1040 Free;
1041 end;
1042 CurrentTransaction.Commit;
1043 end;
1044
1045 procedure TDBDataModule.SetForcedWrites(AValue: boolean);
1046 begin
1047 IBConfigService1.SetAsyncMode(not AValue);
1048 end;
1049
1050 function TDBDataModule.IsDatabaseOnline: boolean;
1051 begin
1052 Result := DatabaseQuery.Active and (DatabaseQuery.FieldByName('MON$SHUTDOWN_MODE').AsInteger = 0);
1053 end;
1054
1055 function TDBDataModule.IsShadowDatabase: boolean;
1056 begin
1057 GetDBFlags;
1058 Result := FIsShadowDatabase;
1059 end;
1060
1061 procedure TDBDataModule.ActivateShadow;
1062 begin
1063 IBConfigService1.ActivateShadow;
1064 MessageDlg('Shadow Database activated. You should now rename the file or change the database alias name to point to the shadow',
1065 mtInformation,[mbOK],0);
1066 end;
1067
1068 procedure TDBDataModule.AddSecondaryFile(aFileName: string; StartAt,
1069 FileLength: integer);
1070 var SQLText: string;
1071 begin
1072 if FileLength <> -1 then
1073 SQLText := Format(sAddSecondarySQL2,[aFileName,StartAt,FileLength])
1074 else
1075 SQLText := Format(sAddSecondarySQL,[aFileName,StartAt]);
1076 ExecDDL.SQL.Text := SQLText;
1077 ExecDDL.ExecQuery;
1078 CurrentTransaction.Commit;
1079 end;
1080
1081 procedure TDBDataModule.AddShadowSet;
1082 var CurrentLocation: TBookmark;
1083 ShadowSet: integer;
1084 begin
1085 if ShadowFiles.RecordCount = 0 then
1086 ShadowSet := 1
1087 else
1088 with ShadowFiles do
1089 begin
1090 CurrentLocation := Bookmark;
1091 DisableControls;
1092 try
1093 Last;
1094 ShadowSet := FieldByName('RDB$Shadow_Number').AsInteger + 1;
1095 finally
1096 Bookmark := CurrentLocation;
1097 EnableControls
1098 end
1099 end;
1100 AddShadowSetDlg.ShowModal(ShadowSet);
1101 CurrentTransaction.Active := true;
1102 end;
1103
1104 procedure TDBDataModule.RemoveShadowSet(ShadowSet: integer);
1105 begin
1106 if IBDatabaseInfo.ODSMajorVersion < 12 then
1107 begin
1108 if MessageDlg(Format(sRemoveShadow,[ShadowSet]),mtConfirmation,[mbYes,mbNo],0) = mrYes then
1109 ExecDDL.SQL.Text := Format(sRemoveShadow,[ShadowSet]);
1110 end
1111 else
1112 case MessageDlg(Format(sPreserveShadowFiles,[ShadowSet]),mtConfirmation,[mbYes,mbNo,mbCancel],0) of
1113 mrNo:
1114 ExecDDL.SQL.Text :=Format(sRemoveShadow12,[ShadowSet]);
1115 mrYes:
1116 ExecDDL.SQL.Text := Format(sPreserveShadow,[ShadowSet]);
1117 mrCancel:
1118 Exit;
1119 end;
1120 ExecDDL.ExecQuery;
1121 CurrentTransaction.Commit;
1122 end;
1123
1124 procedure TDBDataModule.LoadPerformanceStatistics(Lines: TStrings);
1125
1126 procedure AddPerfStats(Heading: string; stats: TStrings);
1127 var i: integer;
1128 begin
1129 with Lines do
1130 begin
1131 if stats.count = 0 then exit;
1132 Add('');
1133 Add(Heading);
1134 for i := 0 to stats.Count - 1 do
1135 begin
1136 if TableNameLookup.Locate('RDB$RELATION_ID',stats.Names[i],[]) then
1137 Add(' ' + TableNameLookup.FieldByName('RDB$RELATION_NAME').AsString + ' = ' + stats.ValueFromIndex[i]);
1138 end;
1139 end;
1140 end;
1141
1142 begin
1143 TableNameLookup.Active := true;
1144 with IBDatabaseInfo, Lines do
1145 begin
1146 Add(Format('Number of reads from the memory buffer cache = %d',[Fetches]));
1147 Add(Format('Number of writes to the memory buffer cache = %d',[Marks]));
1148 Add(Format('Number of page reads = %d',[Reads]));
1149 Add(Format('Number of page writes = %d',[Writes]));
1150 Add('');
1151 Add('Since Database last attached:');
1152 AddPerfStats('Number of removals of a version of a record',BackoutCount);
1153 AddPerfStats('Number of database deletes',DeleteCount);
1154 AddPerfStats('Number of removals of a committed record',ExpungeCount);
1155 AddPerfStats('Number of inserts',InsertCount);
1156 AddPerfStats('Number of removals of old versions of fully mature records',PurgeCount);
1157 AddPerfStats('Number of reads done via an index',ReadIdxCount);
1158 AddPerfStats('Number of sequential table scans',ReadSeqCount);
1159 AddPerfStats('Number of database updates',UpdateCount);
1160 end;
1161 end;
1162
1163 procedure TDBDataModule.LoadDatabaseStatistics(OptionID: integer; Lines: TStrings);
1164 begin
1165 if OptionID = 1 then
1166 LoadPerformanceStatistics(Lines)
1167 else
1168 with IBStatisticalService1 do
1169 begin
1170 case OptionID of
1171 0: Options := [HeaderPages];
1172 2: options := [DataPages];
1173 3: Options := [IndexPages];
1174 4: Options := [SystemRelations]
1175 end;
1176 Execute(Lines);
1177 end;
1178 end;
1179
1180 function TDBDataModule.LoadConfigData(ConfigFileData: TConfigFileData): boolean;
1181 var i: integer;
1182 aValue: integer;
1183 begin
1184 ConfigDataset.Active := true;
1185 ConfigDataset.Clear(false);
1186 for i := 0 to Length(ConfigFileData.ConfigFileKey) - 1 do
1187 begin
1188 aValue := ConfigFileData.ConfigFileValue[i] ;
1189 with ConfigDataset do
1190 case ConfigFileData.ConfigFileKey[i] of
1191 ISCCFG_LOCKMEM_KEY:
1192 AppendRecord(['Lock mem', aValue]);
1193 ISCCFG_LOCKSEM_KEY:
1194 AppendRecord(['Lock Semaphores', aValue]);
1195 ISCCFG_LOCKSIG_KEY:
1196 AppendRecord(['Lock sig', aValue]);
1197 ISCCFG_EVNTMEM_KEY:
1198 AppendRecord(['Event mem', aValue]);
1199 ISCCFG_PRIORITY_KEY:
1200 AppendRecord(['Priority', aValue]);
1201 ISCCFG_MEMMIN_KEY:
1202 AppendRecord(['Min memory', aValue]);
1203 ISCCFG_MEMMAX_KEY:
1204 AppendRecord(['Max Memory', aValue]);
1205 ISCCFG_LOCKORDER_KEY:
1206 AppendRecord(['Lock order', aValue]);
1207 ISCCFG_ANYLOCKMEM_KEY:
1208 AppendRecord(['Any lock mem', aValue]);
1209 ISCCFG_ANYLOCKSEM_KEY:
1210 AppendRecord(['Any lock semaphore',aValue]);
1211 ISCCFG_ANYLOCKSIG_KEY:
1212 AppendRecord(['any lock sig', aValue]);
1213 ISCCFG_ANYEVNTMEM_KEY:
1214 AppendRecord(['any event mem', aValue]);
1215 ISCCFG_LOCKHASH_KEY:
1216 AppendRecord(['Lock hash', aValue]);
1217 ISCCFG_DEADLOCK_KEY:
1218 AppendRecord(['Deadlock', aValue]);
1219 ISCCFG_LOCKSPIN_KEY:
1220 AppendRecord(['Lock spin', aValue]);
1221 ISCCFG_CONN_TIMEOUT_KEY:
1222 AppendRecord(['Conn timeout', aValue]);
1223 ISCCFG_DUMMY_INTRVL_KEY:
1224 AppendRecord(['Dummy interval', aValue]);
1225 ISCCFG_IPCMAP_KEY:
1226 AppendRecord(['Map size', aValue]);
1227 ISCCFG_DBCACHE_KEY:
1228 AppendRecord(['Cache size', aValue]);
1229 end;
1230 end;
1231 Result := ConfigDataset.Active and (ConfigDataset.RecordCount > 0);
1232 end;
1233
1234 procedure TDBDataModule.LoadServerProperties(Lines: TStrings);
1235 var i: integer;
1236 begin
1237 Lines.Clear;
1238 with IBServerProperties1 do
1239 begin
1240 Lines.Add('Server Version = ' + VersionInfo.ServerVersion);
1241 Lines.Add('Server Implementation = ' + VersionInfo.ServerImplementation);
1242 Lines.Add('Service Version = ' + IntToStr(VersionInfo.ServiceVersion));
1243 with ServicesConnection do
1244 Lines.Add(Format('Firebird Release = %d.%d.%d (Build no. %d)',[ServerVersionNo[1],
1245 ServerVersionNo[2],
1246 ServerVersionNo[3],
1247 ServerVersionNo[4]]));
1248 Lines.Add('No. of attachments = ' + IntToStr(DatabaseInfo.NoOfAttachments));
1249 Lines.Add('No. of databases = ' + IntToStr(DatabaseInfo.NoOfDatabases));
1250 for i := 0 to length(DatabaseInfo.DbName) - 1 do
1251 Lines.Add(Format('DB Name (%d) = %s',[i+1, DatabaseInfo.DbName[i]]));
1252 Lines.Add('Base Location = ' + ConfigParams.BaseLocation);
1253 Lines.Add('Lock File Location = ' + ConfigParams.LockFileLocation);
1254 Lines.Add('Security Database Location = ' + ConfigParams.SecurityDatabaseLocation);
1255 Lines.Add('Message File Location = ' + ConfigParams.MessageFileLocation);
1256 end;
1257 end;
1258
1259 procedure TDBDataModule.LoadServerLog(Lines: TStrings);
1260 begin
1261 Lines.Clear;
1262 if IBLogService1.ServicesConnection.ServiceIntf.getProtocol = Local then
1263 Lines.Add('Server Log not available with embedded server')
1264 else
1265 IBLogService1.Execute(Lines);
1266 end;
1267
1268 procedure TDBDataModule.RevokeAll;
1269 begin
1270 with SubjectAccessRights do
1271 if Active then
1272 begin
1273 DisableControls;
1274 try
1275 First;
1276 while not EOF do
1277 begin
1278 if FieldByName('OBJECT_TYPE').AsInteger = 0 {relation} then
1279 ExecDDL.SQL.Text := Format('Revoke All on %s from %s',[
1280 Trim(FieldByName('OBJECT_NAME').AsString),
1281 Trim(FieldByName('SUBJECT_NAME').AsString)])
1282 else
1283 if FieldByName('OBJECT_TYPE').AsInteger = 13 {role} then
1284 ExecDDL.SQL.Text := Format('Revoke %s from %s',[
1285 Trim(FieldByName('OBJECT_NAME').AsString),
1286 Trim(FieldByName('SUBJECT_NAME').AsString)])
1287 else
1288 ExecDDL.SQL.Text := Format('Revoke All on %s %s from %s',[
1289 Trim(FieldByName('OBJECT_TYPE_NAME').AsString),
1290 Trim(FieldByName('OBJECT_NAME').AsString),
1291 Trim(FieldByName('SUBJECT_NAME').AsString)]);
1292 ExecDDL.ExecQuery;
1293 Next;
1294 end;
1295 finally
1296 EnableControls;
1297 end;
1298 CurrentTransaction.Commit;
1299 end;
1300 end;
1301
1302 procedure TDBDataModule.SyncSubjectAccessRights(ID: string);
1303 begin
1304 if (FSubjectAccessRightsID = ID) and SubjectAccessRights.Active then Exit;
1305 SubjectAccessRights.Active := false;
1306 FSubjectAccessRightsID := ID;
1307 SubjectAccessRights.Active := true;
1308 end;
1309
1310 procedure TDBDataModule.IBDatabase1Login(Database: TIBDatabase;
1311 LoginParams: TStrings);
1312 var aDatabaseName: string;
1313 aUserName: string;
1314 aPassword: string;
1315 aCreateIfNotExist: boolean;
1316 begin
1317 if FLocalConnect or (FDBPassword <> '') {reconnect} then
1318 begin
1319 LoginParams.Values['user_name'] := FDBUserName;
1320 LoginParams.Values['password'] := FDBPassword;
1321 exit;
1322 end;
1323
1324 aDatabaseName := Database.DatabaseName;
1325 aUserName := LoginParams.Values['user_name'];
1326 aPassword := '';
1327 aCreateIfNotExist := false;
1328 if CallLoginDlg(aDatabaseName, aUserName, aPassword, aCreateIfNotExist) = mrOK then
1329 begin
1330 FDBPassword := aPassword; {remember for reconnect}
1331 Database.DatabaseName := aDatabaseName;
1332 LoginParams.Values['user_name'] := aUserName;
1333 LoginParams.Values['password'] := aPassword;
1334 FDBUserName := aUserName;
1335 FDBPassword := aPassword;
1336 Database.CreateIfNotExists := aCreateIfNotExist;
1337 ParseConnectString(aDatabaseName,FServerName,FDatabasePathName,FProtocol,FPortNo);
1338 end
1339 else
1340 IBError(ibxeOperationCancelled, [nil]);
1341 end;
1342
1343 procedure TDBDataModule.AttUpdateApplyUpdates(Sender: TObject;
1344 UpdateKind: TUpdateKind; Params: ISQLParams);
1345 begin
1346 if UpdateKind = ukDelete then
1347 begin
1348 ExecDDL.SQL.Text := 'Delete from MON$ATTACHMENTS Where MON$ATTACHMENT_ID =' +
1349 Params.ByName('MON$ATTACHMENT_ID').Asstring;
1350 ExecDDL.ExecQuery;
1351 end;
1352 end;
1353
1354 procedure TDBDataModule.DBTablesUpdateApplyUpdates(Sender: TObject;
1355 UpdateKind: TUpdateKind; Params: ISQLParams);
1356 begin
1357 // Do nothing
1358 end;
1359
1360 procedure TDBDataModule.IBValidationService1GetNextLine(Sender: TObject;
1361 var Line: string);
1362 begin
1363 Application.ProcessMessages;
1364 end;
1365
1366 procedure TDBDataModule.IBXServicesConnection1AfterConnect(Sender: TObject);
1367 var UN: ISPBItem;
1368 begin
1369 UN := IBXServicesConnection1.ServiceIntf.getSPB.Find(isc_spb_user_name);
1370 if UN <> nil then
1371 FServiceUserName := UN.AsString;
1372 end;
1373
1374 procedure TDBDataModule.IBXServicesConnection1Login(
1375 Service: TIBXServicesConnection; var aServerName: string; LoginParams: TStrings);
1376 begin
1377 LoginParams.Values['user_name'] := FDBUserName;
1378 LoginParams.Values['password'] := FDBPassword;
1379 end;
1380
1381 procedure TDBDataModule.LegacyUserListAfterOpen(DataSet: TDataSet);
1382 begin
1383 UserListSource.DataSet := LegacyUserList;
1384 if IBDatabase1.Connected then
1385 begin
1386 CurrentTransaction.Active := true;
1387 RoleNameList.Active := true;
1388 end;
1389 end;
1390
1391 procedure TDBDataModule.LegacyUserListAfterPost(DataSet: TDataSet);
1392 begin
1393 if IBDatabase1.Connected then
1394 RoleNameList.Active := true;
1395 end;
1396
1397 procedure TDBDataModule.LegacyUserListBeforeClose(DataSet: TDataSet);
1398 begin
1399 RoleNameList.Active := false;
1400 end;
1401
1402 procedure TDBDataModule.ShadowFilesCalcFields(DataSet: TDataSet);
1403 var Flags: integer;
1404 begin
1405 Flags := DataSet.FieldByName('RDB$FILE_FLAGS').AsInteger;
1406 if Flags and $10 <> 0 then
1407 DataSet.FieldByName('FileMode').AsString := 'C'
1408 else
1409 if Flags and $04 <> 0 then
1410 DataSet.FieldByName('FileMode').AsString := 'M'
1411 else
1412 if Flags and $01 <> 0 then
1413 if DataSet.FieldByName('RDB$FILE_SEQUENCE').AsInteger = 0 then
1414 DataSet.FieldByName('FileMode').AsString := 'A'
1415 else
1416 DataSet.FieldByName('FileMode').AsString := '+'
1417 else
1418 DataSet.FieldByName('FileMode').AsString := ''
1419 end;
1420
1421 procedure TDBDataModule.SubjectAccessRightsBeforeOpen(DataSet: TDataSet);
1422 begin
1423 SubjectAccessRights.ParamByName('ID').AsString := FSubjectAccessRightsID;
1424 end;
1425
1426 procedure TDBDataModule.TagsUpdateApplyUpdates(Sender: TObject;
1427 UpdateKind: TUpdateKind; Params: ISQLParams);
1428 var sql: string;
1429 begin
1430 sql := '';
1431 case UpdateKind of
1432 ukInsert,
1433 ukModify:
1434 begin
1435 sql := 'ALTER USER ' + Trim(Params.ByName('SEC$USER_NAME').AsString)
1436 + ' TAGS (' + QuoteIdentifierIfNeeded(IBDatabase1.SQLDialect,Params.ByName('SEC$KEY').AsString)
1437 + '=''' + SQLSafeString(Params.ByName('SEC$VALUE').AsString) + '''';
1438 if Params.ByName('SEC$KEY').AsString <> Params.ByName('OLD_SEC$KEY').AsString then
1439 sql += ', DROP ' + QuoteIdentifierIfNeeded(IBDatabase1.SQLDialect,Params.ByName('OLD_SEC$KEY').AsString);
1440 sql +=')'
1441 end;
1442
1443 ukDelete:
1444 sql := 'ALTER USER ' + Trim(Params.ByName('SEC$USER_NAME').AsString)
1445 + ' TAGS (DROP ' + QuoteIdentifierIfNeeded(IBDatabase1.SQLDialect,Params.ByName('SEC$KEY').AsString) + ')';
1446 end;
1447 ExecDDL.SQL.Text := sql;
1448 ExecDDL.ExecQuery;
1449 end;
1450
1451 procedure TDBDataModule.IBDatabase1AfterConnect(Sender: TObject);
1452 begin
1453 {Virtual tables did not exist prior to Firebird 2.1 - so don't bother with old version}
1454 with IBDatabaseInfo do
1455 if (ODSMajorVersion < 11) or ((ODSMajorVersion = 11) and (ODSMinorVersion < 1)) then
1456 begin
1457 IBDatabase1.Connected := false;
1458 raise Exception.Create('This application requires Firebird 2.1 or later');
1459 end
1460 else
1461 if ODSMajorVersion < 12 then
1462 {Don't expect to be able to find these fields}
1463 begin
1464 AttachmentsMONCLIENT_VERSION.FieldKind := fkCalculated;
1465 AttachmentsMONREMOTE_VERSION.FieldKind := fkCalculated;
1466 AttachmentsMONREMOTE_HOST.FieldKind := fkCalculated;
1467 AttachmentsMONREMOTE_OS_USER.FieldKind := fkCalculated;
1468 AttachmentsMONAUTH_METHOD.FieldKind := fkCalculated;
1469 AttachmentsMONSYSTEM_FLAG.FieldKind := fkCalculated;
1470 AttachmentsRDBSECURITY_CLASS.FieldKind := fkCalculated;
1471 AttachmentsRDBOWNER_NAME.FieldKind := fkCalculated;
1472 end
1473 else
1474 begin
1475 AttachmentsMONCLIENT_VERSION.FieldKind := fkData;
1476 AttachmentsMONREMOTE_VERSION.FieldKind := fkData;
1477 AttachmentsMONREMOTE_HOST.FieldKind := fkData;
1478 AttachmentsMONREMOTE_OS_USER.FieldKind := fkData;
1479 AttachmentsMONAUTH_METHOD.FieldKind := fkData;
1480 AttachmentsMONSYSTEM_FLAG.FieldKind := fkData;
1481 AttachmentsRDBSECURITY_CLASS.FieldKind := fkData;
1482 AttachmentsRDBOWNER_NAME.FieldKind := fkData;
1483 end;
1484
1485 FLocalConnect := FProtocol = Local;
1486 ConnectServicesAPI;
1487 CurrentTransaction.Active := true;
1488 FHasUserAdminPrivilege := GetUserAdminPrivilege;
1489 ReloadData;
1490 end;
1491
1492 procedure TDBDataModule.IBDatabase1AfterDisconnect(Sender: TObject);
1493 begin
1494 FDisconnecting := false;
1495 end;
1496
1497 procedure TDBDataModule.IBDatabase1BeforeDisconnect(Sender: TObject);
1498 begin
1499 FDisconnecting := true;
1500 end;
1501
1502 procedure TDBDataModule.DatabaseQueryAfterOpen(DataSet: TDataSet);
1503 begin
1504 DBCharSet.Active := true;
1505 end;
1506
1507 procedure TDBDataModule.CurrentTransactionAfterTransactionEnd(Sender: TObject);
1508 begin
1509 if not Disconnecting and not (csDestroying in ComponentState) then
1510 begin
1511 CurrentTransaction.Active := true;
1512 Application.QueueAsyncCall(@ReloadData,0);
1513 end;
1514 end;
1515
1516 procedure TDBDataModule.ApplicationProperties1Exception(Sender: TObject;
1517 E: Exception);
1518 begin
1519 if E is EIBInterBaseError then
1520 begin
1521 if RoleNameList.State in [dsInsert,dsEdit] then
1522 RoleNameList.Cancel;
1523 if UserList.State in [dsInsert,dsEdit] then
1524 UserList.Cancel;
1525 end;
1526 MessageDlg(E.Message,mtError,[mbOK],0);
1527 if CurrentTransaction.Active then
1528 CurrentTransaction.Rollback;
1529 end;
1530
1531 procedure TDBDataModule.AccessRightsCalcFields(DataSet: TDataSet);
1532 begin
1533 AccessRightsDisplayName.AsString := AccessRightsSUBJECT_NAME.AsString;
1534 if AccessRightsSUBJECT_TYPE.AsInteger = 8 then
1535 begin
1536 if (AccessRightsSUBJECT_NAME.AsString <> 'PUBLIC') and UserListSource.DataSet.Active and
1537 not UserListSource.DataSet.Locate('SEC$USER_NAME',AccessRightsSUBJECT_NAME.AsString,[]) then
1538 begin
1539 AccessRightsImageIndex.AsInteger := 4;
1540 AccessRightsDisplayName.AsString := AccessRightsSUBJECT_NAME.AsString + ' (stale)';
1541 end
1542 else
1543 AccessRightsImageIndex.AsInteger := -1
1544 end
1545 else
1546 AccessRightsImageIndex.AsInteger := -1;
1547 end;
1548
1549 procedure TDBDataModule.AttachmentsAfterDelete(DataSet: TDataSet);
1550 begin
1551 CurrentTransaction.Commit;
1552 end;
1553
1554 procedure TDBDataModule.AttachmentsAfterOpen(DataSet: TDataSet);
1555 begin
1556 Attachments.Locate('MON$ATTACHMENT_ID',AttmtQuery.FieldByName('MON$ATTACHMENT_ID').AsInteger,[]);
1557 end;
1558
1559 procedure TDBDataModule.AttachmentsBeforeOpen(DataSet: TDataSet);
1560 begin
1561 if IBDatabaseInfo.ODSMajorVersion >= 12 then
1562 (DataSet as TIBQuery).Parser.Add2WhereClause('r.MON$SYSTEM_FLAG = 0');
1563 end;
1564
1565 procedure TDBDataModule.ConfigDatasetAfterClose(DataSet: TDataSet);
1566 begin
1567 ConfigDataset.Clear(false);
1568 end;
1569
1570 procedure TDBDataModule.DatabaseQueryBeforeClose(DataSet: TDataSet);
1571 begin
1572 DBCharSet.Active := false;
1573 end;
1574
1575 procedure TDBDataModule.DBCharSetAfterClose(DataSet: TDataSet);
1576 begin
1577 CharSetLookup.Active := false;
1578 end;
1579
1580 procedure TDBDataModule.DBCharSetBeforeOpen(DataSet: TDataSet);
1581 begin
1582 CharSetLookup.Active := true;
1583 end;
1584
1585 end.
1586