fbadmin.pp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. unit FBAdmin;
  2. { Interbase/Firebird Administration using the service manager
  3. Copyright (C) 2012 Ludo Brands
  4. This library is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU Library General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or (at your
  7. option) any later version with the following modification:
  8. As a special exception, the copyright holders of this library give you
  9. permission to link this library with independent modules to produce an
  10. executable, regardless of the license terms of these independent modules,and
  11. to copy and distribute the resulting executable under terms of your choice,
  12. provided that you also meet, for each linked independent module, the terms
  13. and conditions of the license of that module. An independent module is a
  14. module which is not derived from or based on this library. If you modify
  15. this library, you may extend this exception to your version of the library,
  16. but you are not obligated to do so. If you do not wish to do so, delete this
  17. exception statement from your version.
  18. This program is distributed in the hope that it will be useful, but WITHOUT
  19. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  20. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
  21. for more details.
  22. You should have received a copy of the GNU Library General Public License
  23. along with this library; if not, write to the Free Software Foundation,
  24. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25. }
  26. {$mode objfpc}{$H+}
  27. {$Define LinkDynamically}
  28. interface
  29. uses
  30. Classes, SysUtils,
  31. {$IfDef LinkDynamically}
  32. ibase60dyn,
  33. {$Else}
  34. ibase60,
  35. {$EndIf}
  36. IBConnection;
  37. type
  38. TIBBackupOption=(IBBkpVerbose,IBBkpIgnoreChecksums,IBBkpIgnoreLimbo,IBBkpMetadataOnly,
  39. IBBkpNoGarbageCollect,IBBkpOldDescriptions,IBBkpNonTransportable,IBBkpConvert);
  40. TIBBackupOptions= set of TIBBackupOption;
  41. TIBRestoreOption=(IBResVerbose,IBResDeactivateIdx,IBResNoShadow,IBResNoValidity,
  42. IBResOneAtaTime,IBResReplace,IBResCreate,IBResUseAllSpace,IBResAMReadOnly,IBResAMReadWrite);
  43. TIBRestoreOptions= set of TIBRestoreOption;
  44. TServiceProtocol=(IBSPLOCAL,IBSPTCPIP,IBSPNETBEUI,IBSPNAMEDPIPE);
  45. TIBOnOutput= procedure(Sender: TObject; msg: string; IBAdminAction: string) of object;
  46. TIBStatOption = (IBDataPages, IBDbLog, IBHeaderPages, IBIndexPages, IBSystemRelations,
  47. IBRecordVersions, IBStatTables);
  48. TIBStatOptions = set of TIBStatOption;
  49. { TFBAdmin }
  50. TFBAdmin=class(TComponent)
  51. private
  52. FErrorCode: longint;
  53. FErrorMsg: string;
  54. FHost: string;
  55. FOnOutput: TIBOnOutput;
  56. FOutput: TStringList;
  57. FPassword: string;
  58. FPort: word;
  59. FProtocol: TServiceProtocol;
  60. FServerImplementation: string;
  61. FServerLockDir: string;
  62. FServerMsgDir: string;
  63. FServerRootDir: string;
  64. FServerSecDBDir: string;
  65. FServerVersion: string;
  66. FStatus: array [0..19] of ISC_STATUS;
  67. FSvcHandle: isc_svc_handle;
  68. FUseExceptions: boolean;
  69. FUser: string;
  70. function CheckConnected(ProcName: string):boolean;
  71. procedure CheckError(ProcName : string; Status : PISC_STATUS);
  72. function GetDBInfo:boolean;
  73. function GetIBLongint(buffer:string; var bufptr:integer):longint;overload;
  74. function GetIBString(buffer:string; var bufptr:integer):string;overload;
  75. function GetOutput(IBAdminAction:string):boolean;
  76. function IBParamSerialize(isccode:byte;value:string):string;
  77. procedure IBRaiseError(GDSErrorCode:Longint; const msg : string; const args : array of const);
  78. function IBSPBParamSerialize(isccode:byte;value:string):string;
  79. function IBSPBParamSerialize(isccode:byte;value:longint):string;
  80. function MakeBackupOptions(options:TIBBackupOptions):longint;
  81. function MakeRestoreOptions(options:TIBRestoreOptions):longint;
  82. public
  83. constructor Create(AOwner: TComponent); override;
  84. destructor Destroy; override;
  85. //Connect to service manager. Specify User,Password and, for remote databases,
  86. //Host and, if not standard, Port
  87. function Connect:boolean;
  88. //Disconnect from service manager. Done automatically when destroying component
  89. function DisConnect:boolean;
  90. //Backup database to a single file on the server.
  91. //Include IBBkpVerbose in Options to get progress feedback through the OnOutput Handler
  92. function Backup(Database,Filename:string;Options:TIBBackupOptions;RoleName:string=''):boolean;
  93. //Backup database to multiple files with length FileSize on the server.
  94. //Filenames is the list of filenames to use. The last file specified has no size limit.
  95. //Include IBBkpVerbose in Options to get progress feedback through the OnOutput Handler
  96. function BackupMultiFile(Database:string;Filenames:TStrings;FileSize:longint;
  97. Options:TIBBackupOptions;RoleName:string=''):boolean;
  98. //Restore database from a single file on the server.
  99. //Include IBResReplace to restore in and existing database or IBResCreate
  100. //to create a a new one.
  101. //Include IBResVerbose in Options to get progress feedback through the OnOutput Handler
  102. function Restore(Database,Filename:string;Options:TIBRestoreOptions;RoleName:string=''):boolean;
  103. //Restore database from multiple files on the server.
  104. //Filenames is the list of files to use.
  105. //Include IBResReplace to restore in and existing database or IBResCreate
  106. //to create a a new one.
  107. //Include IBResVerbose in Options to get progress feedback through the OnOutput Handler
  108. function RestoreMultiFile(Database:string;Filenames:TStrings;
  109. Options:TIBRestoreOptions;RoleName:string=''):boolean;
  110. //Add a new user.
  111. function AddUser(UserName,Password:string;RoleName:string='';
  112. GroupName:string='';FirstName:string='';MiddleName:string='';
  113. LastName:string='';UserID: longint = 0; GroupID: longint = 0):boolean;
  114. //Modify an existing user.
  115. function ModifyUser(UserName,Password:string;RoleName:string='';
  116. GroupName:string='';FirstName:string='';MiddleName:string='';
  117. LastName:string='';UserID: longint = 0; GroupID: longint = 0):boolean;
  118. //Delete an existing user.
  119. function DeleteUser(UserName:string;RoleName:string=''):boolean;
  120. //Get the details of an existing user.
  121. function GetUser(UserName:string;var GroupName,FirstName,MiddleName,
  122. LastName:string;var UserID, GroupID: longint):boolean;
  123. //Get the list of all users
  124. function GetUsers(Users:TStrings):boolean;
  125. //Get database server log file
  126. function GetDatabaseLog:boolean;
  127. //Get database statistics
  128. function GetDatabaseStats(Database:string;Options:TIBStatOptions;TableNames:String = ''): boolean;
  129. //Database server version
  130. property ServerVersion:string read FServerVersion;
  131. //Implementation string of the database server
  132. property ServerImplementation:string read FServerImplementation;
  133. //Setting of $FIREBIRD or $INTERBASE
  134. property ServerRootDir:string read FServerRootDir;
  135. //Setting of $FIREBIRD_LCK or $INTERBASE_LCK
  136. property ServerLockDir:string read FServerLockDir;
  137. //Setting of $FIREBIRD_MSG or $INTERBASE_MSG
  138. property ServerMsgDir:string read FServerMsgDir;
  139. //Path to the security database in use by the server
  140. property ServerSecDBDir:string read FServerSecDBDir;
  141. published
  142. //User name to connect to service manager
  143. property User: string read FUser write FUser;
  144. //User name to connect to service manager
  145. property Password: string read FPassword write FPassword;
  146. //Database Host
  147. property Host: string read FHost write FHost;
  148. //Database Port, Default:3050
  149. property Port: word read FPort write FPort default 3050;
  150. //Protocol used to connect to service manager. One of:
  151. //IBSPLOCAL: Host and port ignored
  152. //IBSPTCPIP: Connect to Host:Port
  153. //IBSPNETBEUI: Connect to \\Host\
  154. //IBSPNAMEDPIPE: Connect to //Host/
  155. property Protocol: TServiceProtocol read FProtocol write FProtocol;
  156. //Errorcode returned in status vector or 0 for TFBAdmin errors
  157. property ErrorCode:longint read FErrorCode;
  158. //Errormsg returned in status vector or by TFBAdmin
  159. property ErrorMsg:string read FErrorMsg;
  160. //Raise exceptions when error encounterd. Default: false
  161. property UseExceptions:boolean read FUseExceptions write FUseExceptions;
  162. //Service output messages
  163. //Result from Backup and Restore operations and GetLog
  164. property Output:TStringList read FOutput;
  165. //Event handler for Service output messages
  166. //Used in Backup and Restore operations and GetLog
  167. property OnOutput: TIBOnOutput read FOnOutput write FOnOutput;
  168. end;
  169. implementation
  170. resourcestring
  171. SErrNotConnected = '%s : %s : Not connected.';
  172. SErrError = '%s : %s : %s';
  173. SErrConnected = '%s : Connect : Already connected.';
  174. SErrRestoreOptionsError = '%s : Restore : Nothing to do. Specify IBResReplace or IBResCreate in Options.';
  175. SErrRestoreMultiOptionsError = '%s : RestoreMultiFile : Nothing to do. Specify IBResReplace or IBResCreate in Options.';
  176. SErrUserDoesNotExist = '%s : GetUser : User does not exist.';
  177. SErrUserInvalidReply = '%s : GetUser : Invalid reply (%d).';
  178. SErrUsersInvalidReply = '%s : GetUsers : Invalid reply (%d).';
  179. { TFBAdmin }
  180. function TFBAdmin.IBParamSerialize(isccode: byte; value: string): string;
  181. begin
  182. result:=chr(isccode)+chr(Length(value))+value;
  183. end;
  184. procedure TFBAdmin.IBRaiseError(GDSErrorCode: Longint; const msg: string;
  185. const args: array of const);
  186. var
  187. E:EIBDatabaseError;
  188. begin
  189. FErrorMsg:=format(msg,args);
  190. FErrorCode:=GDSErrorCode;
  191. if FUseExceptions then
  192. begin
  193. E := EIBDatabaseError.Create(FErrorMsg);
  194. E.GDSErrorCode := GDSErrorCode;
  195. Raise E;
  196. end;
  197. end;
  198. function TFBAdmin.IBSPBParamSerialize(isccode: byte; value: string): string;
  199. begin
  200. result:=chr(isccode)+chr(Length(value) and $ff)+chr((Length(value)shr 8) and $ff)+value;
  201. end;
  202. function TFBAdmin.IBSPBParamSerialize(isccode: byte; value: longint): string;
  203. begin
  204. result:=chr(isccode)+chr(value and $ff)+chr((value shr 8) and $ff)
  205. +chr((value shr 16) and $ff)+chr((value shr 24) and $ff);
  206. end;
  207. function TFBAdmin.MakeBackupOptions(options: TIBBackupOptions): longint;
  208. begin
  209. result:=0;
  210. if IBBkpConvert in Options then
  211. result:=result or isc_spb_bkp_convert;
  212. if IBBkpIgnoreChecksums in Options then
  213. result:=result or isc_spb_bkp_ignore_checksums;
  214. if IBBkpIgnoreLimbo in Options then
  215. result:=result or isc_spb_bkp_ignore_limbo;
  216. if IBBkpMetadataOnly in Options then
  217. result:=result or isc_spb_bkp_metadata_only;
  218. if IBBkpNoGarbageCollect in Options then
  219. result:=result or isc_spb_bkp_no_garbage_collect;
  220. if IBBkpNonTransportable in Options then
  221. result:=result or isc_spb_bkp_non_transportable;
  222. if IBBkpOldDescriptions in Options then
  223. result:=result or isc_spb_bkp_old_descriptions;
  224. end;
  225. function TFBAdmin.MakeRestoreOptions(options: TIBRestoreOptions): longint;
  226. begin
  227. result:=0;
  228. if IBResCreate in Options then
  229. result:=result or isc_spb_res_create;
  230. if IBResDeactivateIdx in Options then
  231. result:=result or isc_spb_res_deactivate_idx;
  232. if IBResNoShadow in Options then
  233. result:=result or isc_spb_res_no_shadow;
  234. if IBResNoValidity in Options then
  235. result:=result or isc_spb_res_no_validity;
  236. if IBResOneAtaTime in Options then
  237. result:=result or isc_spb_res_one_at_a_time;
  238. if IBResReplace in Options then
  239. result:=result or isc_spb_res_replace;
  240. if IBResUseAllSpace in Options then
  241. result:=result or isc_spb_res_use_all_space;
  242. end;
  243. function TFBAdmin.CheckConnected(ProcName: string): boolean;
  244. begin
  245. result:=false;
  246. if FSvcHandle=FB_API_NULLHANDLE then
  247. begin
  248. IBRaiseError(0,SErrNotConnected,[self.Name,ProcName]);
  249. exit;
  250. end;
  251. result:=true;
  252. end;
  253. procedure TFBAdmin.CheckError(ProcName: string; Status: PISC_STATUS);
  254. var
  255. buf : array [0..1023] of char;
  256. Msg : string;
  257. Err : longint;
  258. begin
  259. if ((Status[0] = 1) and (Status[1] <> 0)) then
  260. begin
  261. Err := Status[1];
  262. msg := '';
  263. while isc_interprete(Buf, @Status) > 0 do
  264. Msg := Msg + LineEnding +' -' + StrPas(Buf);
  265. IBRaiseError(Err,SErrError,[self.Name,ProcName,Msg]);
  266. end;
  267. end;
  268. function TFBAdmin.GetDBInfo: boolean;
  269. function QueryInfo(isc:byte):string;
  270. var
  271. spb:string;
  272. len:integer;
  273. begin
  274. result:='';
  275. spb:=chr(isc);
  276. setlength(result,255);
  277. if (isc_service_query(@FStatus[0], @FSvcHandle, nil, 0, nil, length(spb),
  278. @spb[1],255,@result[1])=0) and (result[1]=chr(isc)) then
  279. begin
  280. len:=isc_vax_integer(@result[2],2);
  281. delete(result,1,3); // remove cmd and len
  282. setlength(result,len);
  283. end;
  284. end;
  285. begin
  286. FServerImplementation:= QueryInfo(isc_info_svc_implementation);
  287. FServerLockDir:= QueryInfo(isc_info_svc_get_env_lock);
  288. FServerMsgDir:= QueryInfo(isc_info_svc_get_env_msg);
  289. FServerRootDir:= QueryInfo(isc_info_svc_get_env);
  290. FServerSecDBDir:= QueryInfo(isc_info_svc_user_dbpath);
  291. FServerVersion:= QueryInfo(isc_info_svc_server_version);
  292. end;
  293. function TFBAdmin.GetIBLongint(buffer: string; var bufptr: integer): longint;
  294. begin
  295. bufptr:=bufptr+1;
  296. result:=isc_vax_integer(@Buffer[bufptr], 4);
  297. bufptr:=bufptr+4;
  298. end;
  299. function TFBAdmin.GetIBString(buffer: string; var bufptr: integer): string;
  300. var
  301. len:integer;
  302. begin
  303. bufptr:=bufptr+1;
  304. len:=isc_vax_integer(@buffer[bufptr], 2);
  305. bufptr:=bufptr+2;
  306. result:=copy(buffer,bufptr,len);
  307. bufptr:=bufptr+len;
  308. end;
  309. function TFBAdmin.GetOutput(IBAdminAction: string): boolean;
  310. var
  311. len:integer;
  312. buffer:string;
  313. spb:string;
  314. const
  315. BUFFERSIZE=1000;
  316. begin
  317. len:=0;
  318. FOutput.Clear;
  319. spb:=chr(isc_info_svc_line);
  320. repeat
  321. setlength(buffer,BUFFERSIZE);
  322. result:=isc_service_query(@FStatus[0], @FSvcHandle, nil, 0, nil, length(spb),
  323. @spb[1],BUFFERSIZE,@buffer[1])=0;
  324. if not result then
  325. begin
  326. CheckError('GetOutput',FStatus);
  327. exit;
  328. end;
  329. if buffer[1]=chr(isc_info_svc_line) then
  330. begin
  331. len:=isc_vax_integer(@buffer[2],2);
  332. delete(buffer,1,3); // remove cmd and len
  333. setlength(buffer,len);
  334. FOutput.Add(buffer);
  335. if assigned(FOnOutput) then
  336. begin
  337. FOnOutput(Self,buffer,IBAdminAction);
  338. end;
  339. end;
  340. until len=0;
  341. end;
  342. constructor TFBAdmin.Create(AOwner: TComponent);
  343. begin
  344. inherited Create(AOwner);
  345. FPort:= 3050;
  346. FOutput:=TStringList.Create;
  347. end;
  348. destructor TFBAdmin.Destroy;
  349. begin
  350. if FSvcHandle<>FB_API_NULLHANDLE then
  351. DisConnect;
  352. FOutput.Destroy;
  353. inherited Destroy;
  354. end;
  355. function TFBAdmin.Connect: boolean;
  356. var
  357. E:EIBDatabaseError;
  358. Service:string;
  359. spb:string;
  360. begin
  361. result:=false;
  362. {$IfDef LinkDynamically}
  363. result:=InitialiseIBase60<>0;
  364. {$EndIf}
  365. if FSvcHandle<>FB_API_NULLHANDLE then
  366. begin
  367. E := EIBDatabaseError.CreateFmt(SErrConnected,[self.Name]);
  368. E.GDSErrorCode := 0;
  369. Raise E;
  370. end;
  371. Service:='service_mgr';
  372. case FProtocol of
  373. IBSPTCPIP:if FPort=3050 then
  374. service:=FHost+':'+service
  375. else
  376. service:=FHost+'/'+IntTostr(FPort)+':'+service;
  377. IBSPNETBEUI:service:='\\'+FHost+'\'+service;
  378. IBSPNAMEDPIPE:service:='//'+FHost+'/'+service;
  379. end;
  380. spb:=chr(isc_spb_version)+chr(isc_spb_current_version)+
  381. IBParamSerialize(isc_spb_user_name,FUser)+
  382. IBParamSerialize(isc_spb_password,FPassword);
  383. result:=isc_service_attach(@FStatus[0], 0,PChar(Service), @FSvcHandle,
  384. length(spb), @spb[1]) = 0;
  385. if not result then
  386. CheckError('Connect',FStatus)
  387. else
  388. GetDBInfo;
  389. end;
  390. function TFBAdmin.DisConnect: boolean;
  391. begin
  392. result:=CheckConnected('DisConnect');
  393. result:= isc_service_detach(@FStatus[0], @FSvcHandle) = 0;
  394. if not result then
  395. CheckError('DisConnect',FStatus);
  396. FSvcHandle:=FB_API_NULLHANDLE;
  397. {$IfDef LinkDynamically}
  398. ReleaseIBase60;
  399. {$EndIf}
  400. result:=true;
  401. end;
  402. function TFBAdmin.Backup(Database, Filename: string; Options: TIBBackupOptions;
  403. RoleName: string): boolean;
  404. var
  405. spb:string;
  406. begin
  407. result:=CheckConnected('Backup');
  408. spb:=chr(isc_action_svc_backup)+IBSPBParamSerialize(isc_spb_dbname,Database)
  409. +IBSPBParamSerialize(isc_spb_bkp_file,Filename);
  410. if RoleName<>'' then
  411. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  412. if IBBkpVerbose in Options then
  413. spb:=spb+chr(isc_spb_verbose);
  414. spb:=spb+IBSPBParamSerialize(isc_spb_options,MakeBackupOptions(Options));
  415. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  416. @spb[1])=0;
  417. if not result then
  418. begin
  419. CheckError('Backup',FStatus);
  420. exit;
  421. end;
  422. if IBBkpVerbose in Options then
  423. result:=GetOutput('Backup');
  424. end;
  425. function TFBAdmin.BackupMultiFile(Database: string; Filenames: TStrings;
  426. FileSize: longint; Options: TIBBackupOptions; RoleName: string): boolean;
  427. var
  428. spb:string;
  429. i:integer;
  430. begin
  431. result:=CheckConnected('BackupMultiFile');
  432. spb:=chr(isc_action_svc_backup)+IBSPBParamSerialize(isc_spb_dbname,Database);
  433. for i:=0 to Filenames.Count-1 do
  434. begin
  435. spb:=spb+IBSPBParamSerialize(isc_spb_bkp_file,Filenames[i]);
  436. spb:=spb+IBSPBParamSerialize(isc_spb_bkp_length,FileSize);
  437. end;
  438. if RoleName<>'' then
  439. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  440. if IBBkpVerbose in Options then
  441. spb:=spb+chr(isc_spb_verbose);
  442. spb:=spb+IBSPBParamSerialize(isc_spb_options,MakeBackupOptions(Options));
  443. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  444. @spb[1])=0;
  445. if not result then
  446. begin
  447. CheckError('BackupMultiFile',FStatus);
  448. exit;
  449. end;
  450. if IBBkpVerbose in Options then
  451. result:=GetOutput('BackupMultiFile');
  452. end;
  453. function TFBAdmin.Restore(Database, Filename: string;
  454. Options: TIBRestoreOptions; RoleName: string): boolean;
  455. var
  456. spb:string;
  457. begin
  458. result:=CheckConnected('Restore');
  459. if not ((IBResReplace in Options) or (IBResCreate in Options)) then
  460. begin
  461. result:=false;
  462. IBRaiseError(0,SErrRestoreOptionsError,[self.Name]);
  463. exit;
  464. end;
  465. spb:=chr(isc_action_svc_restore)+IBSPBParamSerialize(isc_spb_dbname,Database)
  466. +IBSPBParamSerialize(isc_spb_bkp_file,Filename);
  467. if RoleName<>'' then
  468. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  469. if IBResVerbose in Options then
  470. spb:=spb+chr(isc_spb_verbose);
  471. if (IBResAMReadOnly in Options) or (IBResAMReadWrite in Options) then
  472. begin
  473. if (IBResAMReadOnly in Options) then //ReadOnly overrides ReadWrite
  474. spb:=spb+chr(isc_spb_res_access_mode)+chr(isc_spb_res_am_readonly)
  475. else
  476. spb:=spb+chr(isc_spb_res_access_mode)+chr(isc_spb_res_am_readwrite);
  477. end;
  478. spb:=spb+IBSPBParamSerialize(isc_spb_options,MakeRestoreOptions(Options));
  479. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  480. @spb[1])=0;
  481. if not result then
  482. begin
  483. CheckError('Restore',FStatus);
  484. exit;
  485. end;
  486. if IBResVerbose in Options then
  487. result:=GetOutput('Restore');
  488. end;
  489. function TFBAdmin.RestoreMultiFile(Database: string; Filenames: TStrings;
  490. Options: TIBRestoreOptions; RoleName: string): boolean;
  491. var
  492. spb:string;
  493. i:integer;
  494. begin
  495. result:=CheckConnected('RestoreMultiFile');
  496. if not ((IBResReplace in Options) or (IBResCreate in Options)) then
  497. begin
  498. result:=false;
  499. IBRaiseError(0,SErrRestoreMultiOptionsError,[self.Name]);
  500. exit;
  501. end;
  502. spb:=chr(isc_action_svc_restore)+IBSPBParamSerialize(isc_spb_dbname,Database);
  503. for i:=0 to Filenames.Count-1 do
  504. spb:=spb+IBSPBParamSerialize(isc_spb_bkp_file,Filenames[i]);
  505. if RoleName<>'' then
  506. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  507. if IBResVerbose in Options then
  508. spb:=spb+chr(isc_spb_verbose);
  509. if (IBResAMReadOnly in Options) or (IBResAMReadWrite in Options) then
  510. begin
  511. if (IBResAMReadOnly in Options) then //ReadOnly overrides ReadWrite
  512. spb:=spb+chr(isc_spb_res_access_mode)+chr(isc_spb_res_am_readonly)
  513. else
  514. spb:=spb+chr(isc_spb_res_access_mode)+chr(isc_spb_res_am_readwrite);
  515. end;
  516. spb:=spb+IBSPBParamSerialize(isc_spb_options,MakeRestoreOptions(Options));
  517. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  518. @spb[1])=0;
  519. if not result then
  520. begin
  521. CheckError('RestoreMultiFile',FStatus);
  522. exit;
  523. end;
  524. if IBResVerbose in Options then
  525. result:=GetOutput('RestoreMultiFile');
  526. end;
  527. function TFBAdmin.AddUser(UserName, Password: string; RoleName: string;
  528. GroupName: string; FirstName: string; MiddleName: string; LastName: string;
  529. UserID: longint; GroupID: longint): boolean;
  530. var
  531. spb:string;
  532. begin
  533. result:=CheckConnected('AddUser');
  534. spb:=chr(isc_action_svc_add_user)+IBSPBParamSerialize(isc_spb_sec_username,copy(UserName,1,31))+
  535. IBSPBParamSerialize(isc_spb_sec_password,copy(Password,1,8));
  536. if RoleName<>'' then
  537. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  538. if GroupName<>'' then
  539. spb:=spb+IBSPBParamSerialize(isc_spb_sec_groupname,copy(GroupName,1,31));
  540. if FirstName<>'' then
  541. spb:=spb+IBSPBParamSerialize(isc_spb_sec_firstname,copy(FirstName,1,255));
  542. if MiddleName<>'' then
  543. spb:=spb+IBSPBParamSerialize(isc_spb_sec_middlename,copy(MiddleName,1,255));
  544. if LastName<>'' then
  545. spb:=spb+IBSPBParamSerialize(isc_spb_sec_lastname,copy(LastName,1,255));
  546. if UserID<>0 then
  547. spb:=spb+IBSPBParamSerialize(isc_spb_sec_userid,UserID);
  548. if GroupID<>0 then
  549. spb:=spb+IBSPBParamSerialize(isc_spb_sec_groupid,GroupID);
  550. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  551. @spb[1])=0;
  552. if not result then
  553. CheckError('AddUser',FStatus);
  554. end;
  555. function TFBAdmin.ModifyUser(UserName, Password: string; RoleName: string;
  556. GroupName: string; FirstName: string; MiddleName: string; LastName: string;
  557. UserID: longint; GroupID: longint): boolean;
  558. var
  559. spb:string;
  560. begin
  561. result:=CheckConnected('ModifyUser');
  562. spb:=chr(isc_action_svc_modify_user)+IBSPBParamSerialize(isc_spb_sec_username,copy(UserName,1,31))+
  563. IBSPBParamSerialize(isc_spb_sec_password,copy(Password,1,8));
  564. if RoleName<>'' then
  565. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  566. if GroupName<>'' then
  567. spb:=spb+IBSPBParamSerialize(isc_spb_sec_groupname,copy(GroupName,1,31));
  568. if FirstName<>'' then
  569. spb:=spb+IBSPBParamSerialize(isc_spb_sec_firstname,copy(FirstName,1,255));
  570. if MiddleName<>'' then
  571. spb:=spb+IBSPBParamSerialize(isc_spb_sec_middlename,copy(MiddleName,1,255));
  572. if LastName<>'' then
  573. spb:=spb+IBSPBParamSerialize(isc_spb_sec_lastname,copy(LastName,1,255));
  574. if UserID<>0 then
  575. spb:=spb+IBSPBParamSerialize(isc_spb_sec_userid,UserID);
  576. if GroupID<>0 then
  577. spb:=spb+IBSPBParamSerialize(isc_spb_sec_groupid,GroupID);
  578. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  579. @spb[1])=0;
  580. if not result then
  581. CheckError('ModifyUser',FStatus);
  582. end;
  583. function TFBAdmin.DeleteUser(UserName: string; RoleName: string): boolean;
  584. var
  585. spb:string;
  586. begin
  587. result:=CheckConnected('DeleteUser');
  588. spb:=chr(isc_action_svc_delete_user)+IBSPBParamSerialize(isc_spb_sec_username,copy(UserName,1,31));
  589. if RoleName<>'' then
  590. spb:=spb+IBSPBParamSerialize(isc_spb_sql_role_name,copy(RoleName,1,31));
  591. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  592. @spb[1])=0;
  593. if not result then
  594. CheckError('DeleteUser',FStatus);
  595. end;
  596. function TFBAdmin.GetUser(UserName: string; var GroupName, FirstName,
  597. MiddleName, LastName: string; var UserID, GroupID: longint): boolean;
  598. var
  599. spb:string;
  600. buffer:string;
  601. bufptr:integer;
  602. const
  603. BUFFERSIZE=1000;
  604. begin
  605. result:=CheckConnected('GetUser');
  606. spb:=chr(isc_action_svc_display_user)+IBSPBParamSerialize(isc_spb_sec_username,copy(UserName,1,31));
  607. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  608. @spb[1])=0;
  609. if not result then
  610. begin
  611. CheckError('GetUser',FStatus);
  612. exit;
  613. end;
  614. //retrieve result
  615. spb:=chr(isc_info_svc_get_users);
  616. setlength(buffer,BUFFERSIZE);
  617. result:=isc_service_query(@FStatus[0], @FSvcHandle, nil, 0, nil, length(spb),
  618. @spb[1],BUFFERSIZE,@buffer[1])=0;
  619. if not result then
  620. begin
  621. CheckError('GetUser',FStatus);
  622. exit;
  623. end;
  624. bufptr:=4;
  625. if buffer[1]=chr(isc_info_svc_get_users) then
  626. begin
  627. if buffer[bufptr]=chr(isc_info_end) then
  628. begin
  629. result:=false;
  630. IBRaiseError(0,SErrUserDoesNotExist,[self.Name]);
  631. exit;
  632. end;
  633. while buffer[bufptr]<>chr(isc_info_end) do
  634. begin
  635. case buffer[bufptr] of
  636. chr(isc_spb_sec_username):GetIBString(buffer,bufptr); //trash result
  637. chr(isc_spb_sec_groupname):GroupName:=GetIBString(buffer,bufptr);
  638. chr(isc_spb_sec_firstname):FirstName:=GetIBString(buffer,bufptr);
  639. chr(isc_spb_sec_middlename):MiddleName:=GetIBString(buffer,bufptr);
  640. chr(isc_spb_sec_lastname):LastName:=GetIBString(buffer,bufptr);
  641. chr(isc_spb_sec_userid):UserID:=GetIBLongint(buffer,bufptr);
  642. chr(isc_spb_sec_groupid):GroupID:=GetIBLongint(buffer,bufptr);
  643. else
  644. begin
  645. result:=false;
  646. IBRaiseError(0,SErrUserInvalidReply,[self.Name,ord(buffer[bufptr])]);
  647. exit;
  648. end;
  649. end;
  650. end;
  651. end;
  652. end;
  653. function TFBAdmin.GetUsers(Users: TStrings): boolean;
  654. var
  655. spb:string;
  656. buffer:string;
  657. bufptr:integer;
  658. const
  659. BUFFERSIZE=1000;
  660. begin
  661. result:=CheckConnected('GetUsers');
  662. spb:=chr(isc_action_svc_display_user);
  663. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  664. @spb[1])=0;
  665. if not result then
  666. begin
  667. CheckError('GetUsers',FStatus);
  668. exit;
  669. end;
  670. //retrieve result
  671. spb:=chr(isc_info_svc_get_users);
  672. setlength(buffer,BUFFERSIZE);
  673. result:=isc_service_query(@FStatus[0], @FSvcHandle, nil, 0, nil, length(spb),
  674. @spb[1],BUFFERSIZE,@buffer[1])=0;
  675. if not result then
  676. begin
  677. CheckError('GetUsers',FStatus);
  678. exit;
  679. end;
  680. bufptr:=4;
  681. Users.Clear;
  682. if buffer[1]=chr(isc_info_svc_get_users) then
  683. begin
  684. while buffer[bufptr]<>chr(isc_info_end) do
  685. begin
  686. case buffer[bufptr] of
  687. chr(isc_spb_sec_username):Users.Add(GetIBString(buffer,bufptr));
  688. chr(isc_spb_sec_groupname),
  689. chr(isc_spb_sec_firstname),
  690. chr(isc_spb_sec_middlename),
  691. chr(isc_spb_sec_lastname):GetIBString(buffer,bufptr); //trash result
  692. chr(isc_spb_sec_userid),
  693. chr(isc_spb_sec_groupid):GetIBLongint(buffer,bufptr); //trash result
  694. else
  695. begin
  696. result:=false;
  697. IBRaiseError(0,SErrUsersInvalidReply,[self.Name,ord(buffer[bufptr])]);
  698. exit;
  699. end;
  700. end;
  701. end;
  702. end;
  703. end;
  704. function TFBAdmin.GetDatabaseLog: boolean;
  705. var
  706. spb:string;
  707. begin
  708. result:=CheckConnected('GetLogFile');
  709. spb:=chr(isc_action_svc_get_ib_log);
  710. result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  711. @spb[1])=0;
  712. if not result then
  713. begin
  714. CheckError('GetLogFile',FStatus);
  715. exit;
  716. end;
  717. result:=GetOutput('GetLogFile');
  718. end;
  719. function TFBAdmin.GetDatabaseStats(Database:string;Options: TIBStatOptions; TableNames: String
  720. ): boolean;
  721. var
  722. spb:string;
  723. param: Integer;
  724. begin
  725. Result:=CheckConnected('GetDatabaseStats');
  726. param := 0;
  727. if (IBDataPages in Options) then
  728. param := param or isc_spb_sts_data_pages;
  729. if (IBDbLog in Options) then
  730. param := param or isc_spb_sts_db_log;
  731. if (IBHeaderPages in Options) then
  732. param := param or isc_spb_sts_hdr_pages;
  733. if (IBIndexPages in Options) then
  734. param := param or isc_spb_sts_idx_pages;
  735. if (IBSystemRelations in Options) then
  736. param := param or isc_spb_sts_sys_relations;
  737. if (IBRecordVersions in Options) then
  738. param := param or isc_spb_sts_record_versions;
  739. if (IBStatTables in Options) then
  740. param := param or isc_spb_sts_table;
  741. spb := Char(isc_action_svc_db_stats)+IBSPBParamSerialize(isc_spb_dbname,Database)+
  742. IBSPBParamSerialize(isc_spb_options, param);
  743. if (IBStatTables in Options) and (TableNames <> '') then
  744. spb := spb+IBSPBParamSerialize(isc_spb_command_line, TableNames);
  745. Result:=isc_service_start(@FStatus[0], @FSvcHandle, nil, length(spb),
  746. @spb[1])=0;
  747. if not Result then
  748. begin
  749. CheckError('GetDatabaseStats',FStatus);
  750. exit;
  751. end;
  752. Result:=GetOutput('GetDatabaseStats');
  753. end;
  754. end.