node-firebird 1.1.8 → 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1046 @@
1
+ const Events = require('events');
2
+ const stream = require('stream');
3
+ const Const = require('./const');
4
+ const {BlrReader} = require('./serialize');
5
+ const {doError} = require('../callback');
6
+
7
+ /***************************************
8
+ *
9
+ * Service Manager
10
+ *
11
+ ***************************************/
12
+
13
+ const ServiceManager = function(connection) {
14
+ this.connection = connection;
15
+ connection.svc = this;
16
+ }
17
+
18
+ ServiceManager.prototype.__proto__ = Object.create(Events.EventEmitter.prototype, {
19
+ constructor: {
20
+ value: ServiceManager,
21
+ enumberable: false
22
+ }
23
+ });
24
+
25
+ ServiceManager.prototype._createOutputStream = function (optread, buffersize, callback) {
26
+ var self = this;
27
+ optread = optread || 'byline';
28
+ var t = new stream.Readable({ objectMode: optread === 'byline' }); // chunk by line
29
+ t.__proto__._read = function () {
30
+ var selfread = this;
31
+ var fct = optread === 'byline' ? self.readline : self.readeof;
32
+ fct.call(self, { buffersize: buffersize }, function (err, data) {
33
+ if (err) {
34
+ selfread.push(err.message, Const.DEFAULT_ENCODING);
35
+ return;
36
+ }
37
+ if (data.line && data.line.length)
38
+ selfread.push(data.line, Const.DEFAULT_ENCODING);
39
+ else
40
+ selfread.push(null);
41
+ });
42
+ }
43
+
44
+ callback(null, t);
45
+ }
46
+
47
+
48
+ ServiceManager.prototype._infosmapping = {
49
+ "50"/*isc_info_svc_svr_db_info*/ : "dbinfo",
50
+ "51"/*isc_info_svc_get_license*/ : "licenses",
51
+ "52"/*isc_info_svc_get_license_mask*/ : "licenseoptions",
52
+ "53"/*isc_info_svc_get_config*/ : "fbconfig",
53
+ "54"/*isc_info_svc_version*/ : "svcversion",
54
+ "55"/*isc_info_svc_server_version*/ : "fbversion",
55
+ "56"/*isc_info_svc_implementation*/ : "fbimplementation",
56
+ "57"/*isc_info_svc_capabilities*/ : "fbcapatibilities",
57
+ "58"/*isc_info_svc_user_dbpath*/ : "pathsecuritydb",
58
+ "59"/*isc_info_svc_get_env*/ : "fbenv",
59
+ "60"/*isc_info_svc_get_env_lock*/ : "fbenvlock",
60
+ "61"/*isc_info_svc_get_env_msg*/ : "fbenvmsg",
61
+ "62"/*isc_info_svc_line*/ : "",
62
+ "63"/*isc_info_svc_to_eof*/ : "",
63
+ "64"/*isc_info_svc_timeout*/ : "",
64
+ "65"/*isc_info_svc_get_licensed_users*/ : "",
65
+ "66"/*isc_info_svc_limbo_trans*/ : "limbotrans",
66
+ "67"/*isc_info_svc_running*/ : "",
67
+ "68"/*isc_info_svc_get_users*/ : "fbusers",
68
+ "78"/*isc_info_svc_stdin*/ : ""
69
+ };
70
+
71
+ ServiceManager.prototype._processcapabilities = function (blr, res) {
72
+ var capArray = [
73
+ "WAL_SUPPORT",
74
+ "MULTI_CLIENT_SUPPORT",
75
+ "REMOTE_HOP_SUPPORT",
76
+ "NO_SVR_STATS_SUPPORT",
77
+ "NO_DB_STATS_SUPPORT",
78
+ "LOCAL_ENGINE_SUPPORT",
79
+ "NO_FORCED_WRITE_SUPPORT",
80
+ "NO_SHUTDOWN_SUPPORT",
81
+ "NO_SERVER_SHUTDOWN_SUPPORT",
82
+ "SERVER_CONFIG_SUPPORT",
83
+ "QUOTED_FILENAME_SUPPORT"
84
+ ];
85
+ var dbcapa = res[this._infosmapping[57]] = [];
86
+ var caps = blr.readInt32();
87
+
88
+ for (var i = 0; i < capArray.length; ++i)
89
+ if (caps & (1 << i))
90
+ dbcapa.push(capArray[i]);
91
+ }
92
+
93
+ ServiceManager.prototype._processdbinfo = function (blr, res) {
94
+ var tinfo = blr.readByteCode();
95
+ var dbinfo = res[this._infosmapping[50]] = {};
96
+
97
+ dbinfo.database = [];
98
+ for (; tinfo != Const.isc_info_flag_end; tinfo = blr.readByteCode()) {
99
+ switch (tinfo) {
100
+ case Const.isc_spb_dbname:
101
+ dbinfo.database.push(blr.readString());
102
+ break;
103
+ case Const.isc_spb_num_att:
104
+ dbinfo.nbattachment = blr.readInt32();
105
+ break;
106
+ case Const.isc_spb_num_db:
107
+ dbinfo.nbdatabase = blr.readInt32();
108
+ break;
109
+ }
110
+ }
111
+ }
112
+
113
+ ServiceManager.prototype._processquery = function (buffer, callback) {
114
+ //console.log(buffer);
115
+ var br = new BlrReader(buffer);
116
+ var tinfo = br.readByteCode();
117
+ var res = {};
118
+ res.result = 0;
119
+ for (; tinfo !== Const.isc_info_end; tinfo = br.readByteCode()) {
120
+ switch (tinfo) {
121
+ case Const.isc_info_svc_server_version:
122
+ case Const.isc_info_svc_implementation:
123
+ case Const.isc_info_svc_user_dbpath:
124
+ case Const.isc_info_svc_get_env:
125
+ case Const.isc_info_svc_get_env_lock:
126
+ case Const.isc_info_svc_get_env_msg:
127
+ res[this._infosmapping[tinfo]] = br.readString();
128
+ break;
129
+ case Const.isc_info_svc_version:
130
+ res[this._infosmapping[tinfo]] = br.readInt32();
131
+ break;
132
+ case Const.isc_info_svc_svr_db_info:
133
+ this._processdbinfo(br, res);
134
+ break;
135
+ case Const.isc_info_svc_limbo_trans:
136
+ // not implemented
137
+ for (; tinfo !== isc_info_flag_end; tinfo = br.readByteCode())
138
+ break;
139
+ case Const.isc_info_svc_get_users:
140
+ br.pos += 2
141
+ res[this._infosmapping[tinfo]] = [];
142
+ break;
143
+ case Const.isc_spb_sec_username:
144
+ var tuser = res[this._infosmapping[68]];
145
+ tuser.push({});
146
+ tuser[tuser.length - 1].username = br.readString();
147
+ break;
148
+ case Const.isc_spb_sec_firstname:
149
+ var tuser = res[this._infosmapping[68]];
150
+ var user = tuser[tuser.length-1];
151
+ user.firstname = br.readString();
152
+ break;
153
+ case Const.isc_spb_sec_middlename:
154
+ var tuser = res[this._infosmapping[68]];
155
+ var user = tuser[tuser.length-1];
156
+ user.middlename = br.readString();
157
+ break;
158
+ case Const.isc_spb_sec_lastname:
159
+ var tuser = res[this._infosmapping[68]];
160
+ var user = tuser[tuser.length-1];
161
+ user.lastname = br.readString();
162
+ break;
163
+ case Const.isc_spb_sec_groupid:
164
+ var tuser = res[this._infosmapping[68]];
165
+ var user = tuser[tuser.length-1];
166
+ user.groupid = br.readInt32();
167
+ break;
168
+ case Const.isc_spb_sec_userid:
169
+ var tuser = res[this._infosmapping[68]];
170
+ var user = tuser[tuser.length-1];
171
+ user.userid = br.readInt32();
172
+
173
+ break;
174
+ case Const.isc_spb_sec_admin:
175
+ var tuser = res[this._infosmapping[68]];
176
+ var user = tuser[tuser.length-1];
177
+ user.admin = br.readInt32();
178
+ break;
179
+
180
+ case Const.isc_info_svc_line:
181
+ res.line = br.readString();
182
+ break;
183
+
184
+ case Const.isc_info_svc_to_eof:
185
+ res.line = br.readString();
186
+ break;
187
+
188
+ case Const.isc_info_truncated:
189
+ res.result = 1; // too much data for the result buffer increase size of it (buffersize parameter))
190
+ break;
191
+
192
+ case Const.isc_info_data_not_ready:
193
+ res.result = 2;
194
+ break;
195
+
196
+ case Const.isc_info_svc_timeout:
197
+ res.result = 3;
198
+ break;
199
+
200
+ case Const.isc_info_svc_stdin:
201
+
202
+ break;
203
+
204
+ case Const.isc_info_svc_capabilities:
205
+ this._processcapabilities(br, res);
206
+ break;
207
+ }
208
+ }
209
+ callback(null, res);
210
+ }
211
+
212
+ ServiceManager.prototype.detach = function(callback, force) {
213
+ var self = this;
214
+
215
+ if (!force && self.connection._pending.length > 0) {
216
+ self.connection._detachAuto = true;
217
+ self.connection._detachCallback = callback;
218
+ return self;
219
+ }
220
+
221
+ self.connection.svcdetach(function (err, obj) {
222
+
223
+ self.connection.disconnect();
224
+ self.emit('detach', false);
225
+
226
+ if (callback)
227
+ callback(err, obj);
228
+
229
+ }, force);
230
+
231
+ return self;
232
+ }
233
+
234
+ ServiceManager.prototype.backup = function (options, callback) {
235
+ var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
236
+ var verbose = options.verbose || false;
237
+ // format of bckfile {filename:'name', sizefile:''} sizefile is length of part in bytes
238
+ var bckfiles = options.backupfiles || options.files || null;
239
+ // for convenience
240
+ if (bckfiles) bckfiles = bckfiles.constructor !== Array?[{ filename: bckfiles, sizefile: '0' }]:bckfiles;
241
+ var factor = options.factor || 0; //If backing up to a physical tape device, this switch lets you specify the tape's blocking factor
242
+ var ignorechecksums = options.ignorechecksums || false;
243
+ var ignorelimbo = options.ignorelimbo || false;
244
+ var metadataonly = options.metadataonly || false;
245
+ var nogarbagecollect = options.nogarbasecollect || false;
246
+ var olddescriptions = options.olddescriptions || false;
247
+ var nontransportable = options.nontransportable || false;
248
+ var convert = options.convert || false;
249
+ var expand = options.expand || false;
250
+ var notriggers = options.notriggers || false;
251
+
252
+ if (dbpath == null || dbpath.length === 0) {
253
+ doError(new Error('No database specified'), callback);
254
+ return;
255
+ }
256
+
257
+ if (bckfiles == null || bckfiles.length === 0) {
258
+ doError(new Error('No backup path specified'), callback);
259
+ return;
260
+ }
261
+
262
+ var blr = this.connection._blr;
263
+ blr.pos = 0;
264
+ blr.addByte(Const.isc_action_svc_backup);
265
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
266
+ for (var i = 0; i < bckfiles.length; i++) {
267
+ blr.addString2(Const.isc_spb_bkp_file, bckfiles[i].filename, Const.DEFAULT_ENCODING);
268
+ if (i !== bckfiles.length - 1) // not the end, so we need to write the size of this part (gsplit)
269
+ blr.addString2(Const.isc_spb_bkp_length, bckfiles[i].sizefile, Const.DEFAULT_ENCODING);
270
+ }
271
+ if (factor)
272
+ blr.addByteInt32(Const.isc_spb_bkp_factor, factor);
273
+
274
+ var opts = 0;
275
+ if (ignorechecksums) opts = opts | Const.isc_spb_bkp_ignore_checksums;
276
+ if (ignorelimbo) opts = opts | Const.isc_spb_bkp_ignore_limbo;
277
+ if (metadataonly) opts = opts | Const.isc_spb_bkp_metadata_only;
278
+ if (nogarbagecollect) opts = opts | Const.isc_spb_bkp_no_garbage_collect;
279
+ if (olddescriptions) opts = opts | Const.isc_spb_bkp_old_descriptions;
280
+ if (nontransportable) opts = opts | Const.isc_spb_bkp_non_transportable;
281
+ if (convert) opts = opts | Const.isc_spb_bkp_convert;
282
+ if (expand) opts = opts | Const.isc_spb_bkp_expand;
283
+ if (notriggers) opts = opts | Const.isc_spb_bkp_no_triggers;
284
+ if (opts)
285
+ blr.addByteInt32(Const.isc_spb_options, opts);
286
+ if (verbose)
287
+ blr.addByte(Const.isc_spb_verbose);
288
+ var self = this;
289
+ this.connection.svcstart(blr, function (err, data) {
290
+ if (err) {
291
+ doError(new Error(err), callback);
292
+ return;
293
+ }
294
+ self._createOutputStream(options.optread, options.buffersize, callback);
295
+ });
296
+ }
297
+
298
+ ServiceManager.prototype.nbackup = function (options, callback) {
299
+ var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
300
+ var bckfile = options.backupfile || options.file || null;
301
+ var level = options.level || 0; // nb day for incremental
302
+ var notriggers = options.notriggers || false;
303
+ var direct = options.direct || 'on'; // on or off direct write I/O
304
+
305
+ if (dbpath == null || dbpath.length === 0) {
306
+ doError(new Error('No database specified'), callback);
307
+ return;
308
+ }
309
+
310
+ if (bckfile == null || bckfile.length === 0) {
311
+ doError(new Error('No backup path specified'), callback);
312
+ return;
313
+ }
314
+
315
+ var blr = this.connection._blr;
316
+ blr.pos = 0;
317
+ blr.addByte(Const.isc_action_svc_nbak);
318
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
319
+ blr.addString2(Const.isc_spb_nbk_file, bckfile, Const.DEFAULT_ENCODING);
320
+ blr.addByteInt32(Const.isc_spb_nbk_level, level);
321
+ blr.addString2(Const.isc_spb_nbk_direct, direct, Const.DEFAULT_ENCODING);
322
+ var opts = 0;
323
+ if (notriggers) opts = opts | Const.isc_spb_nbk_no_triggers;
324
+ blr.addByteInt32(Const.isc_spb_options, opts);
325
+ var self = this;
326
+ this.connection.svcstart(blr, function (err, data) {
327
+ if (err) {
328
+ doError(new Error(err), callback);
329
+ return;
330
+ }
331
+ self._createOutputStream(options.optread, options.buffersize, callback);
332
+ });
333
+ }
334
+
335
+ ServiceManager.prototype.restore = function(options, callback) {
336
+ var bckfiles = options.backupfiles || options.files || null; // format bckfiles ['file1', 'file2', 'file3']
337
+ // for convenience
338
+ if (bckfiles) bckfiles = bckfiles.constructor !== Array?[bckfiles]:bckfiles;
339
+ var dbfile = options.database || this.connection.options.filename || this.connection.options.database;;
340
+ var verbose = options.verbose || false;
341
+ var cachebuffers = options.cachebuffers || 2048; // gbak -buffers
342
+ var pagesize = options.pagesize || 4096; // gbak -page_size
343
+ var readonly = options.readonly || false; // gbak -mode
344
+ var deactivateindexes = options.deactivateindexes || false;
345
+ var noshadow = options.noshadow || false;
346
+ var novalidity = options.novalidity || false;
347
+ var individualcommit = options.individualcommit || true; // otherwise no data
348
+ var replace = options.replace || false;
349
+ var create = options.create || true;
350
+ var useallspace = options.useallspace || false;
351
+ var metadataonly = options.metadataonly || false;
352
+ var fixfssdata = options.fixfssdata || null;
353
+ var fixfssmetadata = options.fixfssmetadata || null;
354
+
355
+ if (bckfiles == null || bckfiles.length === 0) {
356
+ doError(new Error('No backup file specified'), callback);
357
+ return;
358
+ }
359
+
360
+ if (dbfile == null || dbfile.length === 0) {
361
+ doError(new Error('No database path specified'), callback);
362
+ return;
363
+ }
364
+
365
+ var blr = this.connection._blr;
366
+ blr.pos = 0;
367
+ blr.addByte(Const.isc_action_svc_restore);
368
+ for (var i = 0; i < bckfiles.length; i++) {
369
+ blr.addString2(Const.isc_spb_bkp_file, bckfiles[i], Const.DEFAULT_ENCODING);
370
+ }
371
+ blr.addString2(Const.isc_spb_dbname, dbfile, Const.DEFAULT_ENCODING);
372
+ blr.addByte(Const.isc_spb_res_buffers);
373
+ blr.addInt32(cachebuffers);
374
+ blr.addByte(Const.isc_spb_res_page_size);
375
+ blr.addInt32(pagesize);
376
+ blr.addByte(Const.isc_spb_res_access_mode);
377
+ if (readonly)
378
+ blr.addByte(Const.isc_spb_prp_am_readonly);
379
+ else
380
+ blr.addByte(Const.isc_spb_prp_am_readwrite);
381
+ if (fixfssdata) blr.addString2(Const.isc_spb_res_fix_fss_data, fixfssdata, Const.DEFAULT_ENCODING);
382
+ if (fixfssmetadata) blr.addString2(Const.isc_spb_res_fix_fss_metadata, fixfssmetadata, Const.DEFAULT_ENCODING);
383
+ var opts = 0;
384
+ if (deactivateindexes) opts = opts | Const.isc_spb_res_deactivate_idx;
385
+ if (noshadow) opts = opts | Const.isc_spb_res_no_shadow;
386
+ if (novalidity) opts = opts | Const.isc_spb_res_no_validity;
387
+ if (individualcommit) opts = opts | Const.isc_spb_res_one_at_a_time;
388
+ if (replace) opts = opts | Const.isc_spb_res_replace;
389
+ if (create) opts = opts | Const.isc_spb_res_create;
390
+ if (useallspace) opts = opts | Const.isc_spb_res_use_all_space;
391
+ if (metadataonly) opts = opts | Const.isc_spb_res_fix_fss_metadata;
392
+ if (opts)
393
+ blr.addByteInt32(Const.isc_spb_options, opts);
394
+ if (verbose)
395
+ blr.addByte(Const.isc_spb_verbose);
396
+ var self = this;
397
+ this.connection.svcstart(blr, function (err, data) {
398
+ if (err) {
399
+ doError(new Error(err), callback);
400
+ return;
401
+ }
402
+ self._createOutputStream(options.optread, options.buffersize, callback);
403
+ });
404
+ }
405
+
406
+ ServiceManager.prototype.nrestore = function (options, callback) {
407
+ var bckfiles = options.backupfiles || options.files || null; // format bckfiles ['file1', 'file2', 'file3']
408
+ // for convenience
409
+ if (bckfiles) bckfiles = bckfiles.constructor !== Array?[bckfiles]:bckfiles;
410
+ var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
411
+
412
+ if (bckfiles == null || bckfiles.length === 0) {
413
+ doError(new Error('No backup file specified'), callback);
414
+ return;
415
+ }
416
+
417
+ if (dbpath == null || bckfiles.length === 0) {
418
+ doError(new Error('No database path specified'), callback);
419
+ return;
420
+ }
421
+ var blr = this.connection._blr;
422
+ blr.pos = 0;
423
+ blr.addByte(Const.isc_action_svc_nrest);
424
+ for (var i = 0; i < bckfiles.length; i++) {
425
+ blr.addString2(Const.isc_spb_nbk_file, bckfiles[i], Const.DEFAULT_ENCODING);
426
+ }
427
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
428
+ var self = this;
429
+ this.connection.svcstart(blr, function (err, data) {
430
+ if (err) {
431
+ doError(new Error(err), callback);
432
+ return;
433
+ }
434
+ self._createOutputStream(options.optread, options.buffersize, callback);
435
+ });
436
+ }
437
+
438
+ // only one at time don't use this function directly
439
+ ServiceManager.prototype._fixpropertie = function (options, callback) {
440
+ var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
441
+ var dialect = options.dialect || null;
442
+ var sweep = options.sweepinterval || null;
443
+ var pagebuffers = options.nbpagebuffers || null;
444
+ var online = options.bringonline || false;
445
+ var shutdown = options.shutdown != null ? options.shutdown : null; // 0 Forced, 1 deny transaction, 2 deny attachment
446
+ var shutdowndelay = options.shutdowndelay || 0;
447
+ var shutdownmode = options.shutdownmode; // 0 normal 1 multi 2 single 3 full
448
+ var shadow = options.activateshadow || false;
449
+ var forcewrite = options.forcewrite;
450
+ var reservespace = options.reservespace;
451
+ var accessmode = options.accessmode; // 0 readonly 1 readwrite
452
+
453
+ if (dbpath == null || dbpath.length === 0) {
454
+ doError(new Error('No database specified'), callback);
455
+ return;
456
+ }
457
+
458
+ var blr = this.connection._blr;
459
+ blr.pos = 0;
460
+ blr.addByte(Const.isc_action_svc_properties);
461
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
462
+ if (dialect) blr.addByteInt32(Const.isc_spb_prp_set_sql_dialect, dialect);
463
+ if (sweep) blr.addByteInt32(Const.isc_spb_prp_sweep_interval, sweep);
464
+ if (pagebuffers) blr.addByteInt32(Const.isc_spb_prp_page_buffers, pagebuffers);
465
+ if (shutdown != null) {
466
+ if (shutdownmode != null) {
467
+ if (SHUTDOWNEX_KIND[shutdown] === undefined) {
468
+ doError(new Error('Invalid shutdown kind'), callback);
469
+ return;
470
+ }
471
+ if (SHUTDOWNEX_MODE[shutdownmode] === undefined) {
472
+ doError(new Error('Invalid shutdown mode'), callback);
473
+ return;
474
+ }
475
+
476
+ // New shutdown with mode
477
+ blr.addBytes([Const.isc_spb_prp_shutdown_mode, SHUTDOWNEX_MODE[shutdownmode]]);
478
+ blr.addByteInt32(SHUTDOWNEX_KIND[shutdown], shutdowndelay);
479
+ } else {
480
+ // Old shutdown
481
+ blr.addByteInt32(SHUTDOWN_KIND[shutdown], shutdowndelay);
482
+ }
483
+ }
484
+ if (forcewrite) blr.addBytes([Const.isc_spb_prp_write_mode, Const.isc_spb_prp_wm_sync]);
485
+ if (forcewrite === false) blr.addBytes([Const.isc_spb_prp_write_mode, Const.isc_spb_prp_wm_async]);
486
+ if (accessmode === 1) blr.addBytes([Const.isc_spb_prp_access_mode, Const.isc_spb_prp_am_readwrite]);
487
+ if (accessmode === 0) blr.addBytes([Const.isc_spb_prp_access_mode, Const.isc_spb_prp_am_readonly]);
488
+ if (reservespace) blr.addBytes([Const.isc_spb_prp_reserve_space, Const.isc_spb_prp_res]);
489
+ if (reservespace != null && !reservespace) blr.addBytes([Const.isc_spb_prp_reserve_space, Const.isc_spb_prp_res_use_full]);
490
+ var opts = 0;
491
+ if (shadow) opts = opts | Const.isc_spb_prp_activate;
492
+ if (online) opts = opts | Const.isc_spb_prp_db_online;
493
+ if (opts)
494
+ blr.addByteInt32(Const.isc_spb_options, opts);
495
+ var self = this;
496
+ this.connection.svcstart(blr, function (err, data) {
497
+ if (err) {
498
+ doError(new Error(err), callback);
499
+ return;
500
+ }
501
+ self._createOutputStream(options.optread, options.buffersize, callback);
502
+ });
503
+ }
504
+
505
+ ServiceManager.prototype.setDialect = function (db, dialect, callback) {
506
+ this._fixpropertie({ database: db, dialect: dialect }, callback);
507
+ }
508
+
509
+ ServiceManager.prototype.setSweepinterval = function (db, sweepinterval, callback) {
510
+ this._fixpropertie({ database: db, sweepinterval: sweepinterval }, callback);
511
+ }
512
+
513
+ ServiceManager.prototype.setCachebuffer = function (db, nbpages, callback) {
514
+ this._fixpropertie({ database: db, nbpagebuffers: nbpages }, callback);
515
+ }
516
+
517
+ ServiceManager.prototype.BringOnline = function (db, callback) {
518
+ this._fixpropertie({ database: db, bringonline: true }, callback);
519
+ }
520
+
521
+ const SHUTDOWN_KIND = {
522
+ 0: Const.isc_spb_prp_shutdown_db,
523
+ 1: Const.isc_spb_prp_deny_new_transactions,
524
+ 2: Const.isc_spb_prp_deny_new_attachments
525
+ };
526
+ const SHUTDOWNEX_KIND = {
527
+ 0: Const.isc_spb_prp_force_shutdown,
528
+ 1: Const.isc_spb_prp_transactions_shutdown,
529
+ 2: Const.isc_spb_prp_attachments_shutdown
530
+ };
531
+ const SHUTDOWNEX_MODE = {
532
+ //0: isc_spb_prp_sm_normal,
533
+ 1: Const.isc_spb_prp_sm_multi,
534
+ 2: Const.isc_spb_prp_sm_single,
535
+ 3: Const.isc_spb_prp_sm_full
536
+ };
537
+ const ShutdownMode = { NORMAL: 0, MULTI: 1, SINGLE: 2, FULL: 3 };
538
+ const ShutdownKind = { FORCED: 0, DENY_TRANSACTION: 1, DENY_ATTACHMENT: 2 };
539
+ exports.ShutdownMode = ShutdownMode;
540
+ exports.ShutdownKind = ShutdownKind;
541
+
542
+ ServiceManager.prototype.Shutdown = function (db, kind, delay, mode, callback) {
543
+ // mode parameter is for server version >= 2.0
544
+ if (mode instanceof Function) {
545
+ callback = mode;
546
+ mode = undefined;
547
+ }
548
+
549
+ this._fixpropertie({ database: db, shutdown: kind, shutdowndelay: delay, shutdownmode: mode }, callback);
550
+ }
551
+
552
+ ServiceManager.prototype.setShadow = function (db, val, callback) {
553
+ this._fixpropertie({ database: db, activateshadow : val }, callback);
554
+ }
555
+
556
+ ServiceManager.prototype.setForcewrite = function (db, val, callback) {
557
+ this._fixpropertie({ database: db, forcewrite : val }, callback);
558
+ }
559
+
560
+ ServiceManager.prototype.setReservespace = function (db, val, callback) {
561
+ this._fixpropertie({ database: db, reservespace : val }, callback);
562
+ }
563
+
564
+ ServiceManager.prototype.setReadonlyMode = function (db, callback) {
565
+ this._fixpropertie({ database: db, accessmode : 0 }, callback);
566
+ }
567
+
568
+ ServiceManager.prototype.setReadwriteMode = function (db, callback) {
569
+ this._fixpropertie({ database: db, accessmode : 1 }, callback);
570
+ }
571
+
572
+ ServiceManager.prototype.validate = function (options, callback) {
573
+ var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
574
+ var checkdb = options.checkdb || false;
575
+ var ignorechecksums = options.ignorechecksums || false;
576
+ var killshadows = options.killshadows || false;
577
+ var mend = options.mend || false;
578
+ var validate = options.validate || false;
579
+ var full = options.full || false;
580
+ var sweep = options.sweep || false;
581
+ var listlimbo = options.listlimbo || false;
582
+ var icu = options.icu || false;
583
+
584
+ if (dbpath == null || dbpath.length === 0) {
585
+ doError(new Error('No database specified'), callback);
586
+ return;
587
+ }
588
+
589
+ var blr = this.connection._blr;
590
+ blr.pos = 0;
591
+ blr.addByte(Const.isc_action_svc_repair);
592
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
593
+ var opts = 0;
594
+ if (checkdb) opts = opts | Const.isc_spb_rpr_check_db;
595
+ if (ignorechecksums) opts = opts | Const.isc_spb_rpr_ignore_checksum;
596
+ if (killshadows) opts = opts | Const.isc_spb_rpr_kill_shadows;
597
+ if (mend) opts = opts | Const.isc_spb_rpr_mend_db;
598
+ if (validate) opts = opts | Const.isc_spb_rpr_validate_db;
599
+ if (full) opts = opts | Const.isc_spb_rpr_full;
600
+ if (sweep) opts = opts | Const.isc_spb_rpr_sweep_db;
601
+ if (listlimbo) opts = opts | Const.isc_spb_rpr_list_limbo_trans;
602
+ if (icu) opts = opts | Const.isc_spb_rpr_icu;
603
+ blr.addByteInt32(Const.isc_spb_options, opts);
604
+ var self = this;
605
+ this.connection.svcstart(blr, function (err, data) {
606
+ if (err) {
607
+ doError(new Error(err), callback);
608
+ return;
609
+ }
610
+ self._createOutputStream(options.optread, options.buffersize, callback);
611
+ });
612
+ }
613
+
614
+ ServiceManager.prototype.commit = function(db, transactid, callback) {
615
+ var dbpath = db || this.connection.options.filename || this.connection.options.database;
616
+ if (dbpath == null || dbpath.length === 0) {
617
+ doError(new Error('No database specified'), callback);
618
+ return;
619
+ }
620
+
621
+ var blr = this.connection._blr;
622
+ blr.pos = 0;
623
+ blr.addByte(Const.isc_action_svc_repair);
624
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
625
+ blr.addByteInt32(Const.isc_spb_rpr_commit_trans, transactid);
626
+ var self = this;
627
+ this.connection.svcstart(blr, function (err, data) {
628
+ if (err) {
629
+ doError(new Error(err), callback);
630
+ return;
631
+ }
632
+ self._createOutputStream(null, null, callback);
633
+ });
634
+ }
635
+
636
+ ServiceManager.prototype.rollback = function (db, transactid, callback) {
637
+ var dbpath = db || this.connection.options.filename || this.connection.options.database;
638
+ if (dbpath == null || dbpath.length === 0) {
639
+ doError(new Error('No database specified'), callback);
640
+ return;
641
+ }
642
+
643
+ var blr = this.connection._blr;
644
+ blr.pos = 0;
645
+ blr.addByte(Const.isc_action_svc_repair);
646
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
647
+ blr.addByteInt32(Const.isc_spb_rpr_rollback_trans, transactid);
648
+ this.connection.svcstart(blr, function (err, data) {
649
+ if (err) {
650
+ doError(new Error(err), callback);
651
+ return;
652
+ }
653
+ self._createOutputStream(null, null, callback);
654
+ });
655
+ }
656
+
657
+ ServiceManager.prototype.recover = function (db, transactid, callback) {
658
+ var dbpath = db || this.connection.options.filename || this.connection.options.database;
659
+ if (dbpath == null || dbpath.length === 0) {
660
+ doError(new Error('No database specified'), callback);
661
+ return;
662
+ }
663
+
664
+ var blr = this.connection._blr;
665
+ blr.pos = 0;
666
+ blr.addByte(Const.isc_action_svc_repair);
667
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
668
+ blr.addByteInt32(Const.isc_spb_rpr_recover_two_phase, transactid);
669
+ this.connection.svcstart(blr, function (err, data) {
670
+ if (err) {
671
+ doError(new Error(err), callback);
672
+ return;
673
+ }
674
+ self._createOutputStream(null, null, callback);
675
+ });
676
+ }
677
+
678
+ ServiceManager.prototype.getStats = function (options, callback) {
679
+ var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
680
+ var record = options.record || false;
681
+ var nocreation = options.nocreation || false;
682
+ var tables = options.tables || false;
683
+ var pages = options.pages || false;
684
+ var header = options.header || false;
685
+ var indexes = options.indexes || false;
686
+ var tablesystem = options.tablesystem || false;
687
+ var encryption = options.encryption || false;
688
+ var objects = options.objects || null; // space-separated list of object index,table,systemtable
689
+ if (dbpath == null || dbpath.length === 0) {
690
+ doError(new Error('No database specified'), callback);
691
+ return;
692
+ }
693
+
694
+ var blr = this.connection._blr;
695
+ blr.pos = 0;
696
+ blr.addByte(Const.isc_action_svc_db_stats);
697
+ blr.addString2(Const.isc_spb_dbname, dbpath, Const.DEFAULT_ENCODING);
698
+ var opts = 0;
699
+ if (record) opts = opts | Const.isc_spb_sts_record_versions;
700
+ if (nocreation) opts = opts | Const.isc_spb_sts_nocreation;
701
+ if (tables) opts = opts | Const.isc_spb_sts_table;
702
+ if (pages) opts = opts | Const.isc_spb_sts_data_pages;
703
+ if (header) opts = opts | Const.isc_spb_sts_hdr_pages;
704
+ if (indexes) opts = opts | Const.isc_spb_sts_idx_pages;
705
+ if (tablesystem) opts = opts | Const.isc_spb_sts_sys_relations;
706
+ if (encryption) opts = opts | Const.isc_spb_sts_encryption;
707
+ if (opts)
708
+ blr.addByteInt32(Const.isc_spb_options, opts);
709
+ if (objects) blr.addString2(Const.isc_spb_command_line, objects, Const.DEFAULT_ENCODING);
710
+ var self = this;
711
+ this.connection.svcstart(blr, function (err, data) {
712
+ if (err) {
713
+ doError(new Error(err), callback);
714
+ return;
715
+ }
716
+ self._createOutputStream(options.optread, options.buffersize, callback);
717
+ });
718
+
719
+ }
720
+
721
+ ServiceManager.prototype.getLog = function (options, callback) {
722
+ var self = this;
723
+ var blr = this.connection._blr;
724
+ var optread = options.optread || 'byline';
725
+ blr.pos = 0;
726
+ blr.addByte(Const.isc_action_svc_get_fb_log);
727
+ this.connection.svcstart(blr, function (err, data) {
728
+ if (err) {
729
+ doError(new Error(err), callback);
730
+ return;
731
+ }
732
+ self._createOutputStream(optread, options.buffersize, callback);
733
+ });
734
+ }
735
+
736
+ ServiceManager.prototype.getUsers = function (username, callback) {
737
+ var self = this;
738
+ var blr = this.connection._blr;
739
+ blr.pos = 0;
740
+ blr.addByte(Const.isc_action_svc_display_user);
741
+ if (username) blr.addString2(Const.isc_spb_sec_username, username, Const.DEFAULT_ENCODING);
742
+ this.connection.svcstart(blr, function (err, data) {
743
+ if (err) {
744
+ doError(new Error(err), callback);
745
+ return;
746
+ }
747
+ self.readusers({}, callback);
748
+ });
749
+ }
750
+
751
+ ServiceManager.prototype.addUser = function (username, password, options, callback) {
752
+ var rolename = options.rolename || null;
753
+ var groupname = options.groupname || null;
754
+ var firsname = options.firstname || null;
755
+ var middlename = options.middlename || null;
756
+ var lastname = options.lastname || null;
757
+ var userid = options.userid || null;
758
+ var groupid = options.groupid || null;
759
+ var admin = options.admin || null;
760
+
761
+ var blr = this.connection._blr;
762
+ blr.pos = 0;
763
+ blr.addByte(Const.isc_action_svc_add_user);
764
+ blr.addString2(Const.isc_spb_sec_username, username, Const.DEFAULT_ENCODING);
765
+ blr.addString2(Const.isc_spb_sec_password, password, Const.DEFAULT_ENCODING);
766
+ if (rolename) blr.addString2(Const.isc_dpb_sql_role_name, rolename, Const.DEFAULT_ENCODING);
767
+ if (groupname) blr.addString2(Const.isc_spb_sec_groupname, groupname, Const.DEFAULT_ENCODING);
768
+ if (firsname) blr.addString2(Const.isc_spb_sec_firstname, firsname, Const.DEFAULT_ENCODING);
769
+ if (middlename) blr.addString2(Const.isc_spb_sec_middlename, middlename, Const.DEFAULT_ENCODING);
770
+ if (lastname) blr.addString2(Const.isc_spb_sec_lastname, lastname, Const.DEFAULT_ENCODING);
771
+ if (userid != null) blr.addByteInt32(Const.isc_spb_sec_userid, userid);
772
+ if (groupid != null) blr.addByteInt32(Const.isc_spb_sec_groupid, groupid);
773
+ if (admin != null) blr.addByteInt32(Const.isc_spb_sec_admin, admin);
774
+
775
+ var self = this;
776
+ this.connection.svcstart(blr, function (err, data) {
777
+ if (err) {
778
+ doError(new Error(err), callback);
779
+ return;
780
+ }
781
+ self._createOutputStream(options.optread, options.buffersize, callback);
782
+ });
783
+ }
784
+
785
+ ServiceManager.prototype.editUser = function (username, options, callback) {
786
+ var rolename = options.rolename || null;
787
+ var groupname = options.groupname || null;
788
+ var firsname = options.firstname || null;
789
+ var middlename = options.middlename || null;
790
+ var lastname = options.lastname || null;
791
+ var userid = options.userid || null;
792
+ var groupid = options.groupid || null;
793
+ var admin = options.admin || null;
794
+ var password = options.password || null;
795
+ var blr = this.connection._blr;
796
+ blr.pos = 0;
797
+ blr.addByte(Const.isc_action_svc_modify_user);
798
+ blr.addString2(Const.isc_spb_sec_username, username, Const.DEFAULT_ENCODING);
799
+ if (password) blr.addString2(Const.isc_spb_sec_password, password, Const.DEFAULT_ENCODING);
800
+ if (rolename) blr.addString2(Const.isc_dpb_sql_role_name, rolename, Const.DEFAULT_ENCODING);
801
+ if (groupname) blr.addString2(Const.isc_spb_sec_groupname, groupname, Const.DEFAULT_ENCODING);
802
+ if (firsname) blr.addString2(Const.isc_spb_sec_firstname, firsname, Const.DEFAULT_ENCODING);
803
+ if (middlename) blr.addString2(Const.isc_spb_sec_middlename, middlename, Const.DEFAULT_ENCODING);
804
+ if (lastname) blr.addString2(Const.isc_spb_sec_lastname, lastname, Const.DEFAULT_ENCODING);
805
+ if (userid != null) blr.addByteInt32(Const.isc_spb_sec_userid, userid);
806
+ if (groupid != null) blr.addByteInt32(Const.isc_spb_sec_groupid, groupid);
807
+ if (admin != null) blr.addByteInt32(Const.isc_spb_sec_admin, admin);
808
+
809
+ var self = this;
810
+ this.connection.svcstart(blr, function (err, data) {
811
+ if (err) {
812
+ doError(new Error(err), callback);
813
+ return;
814
+ }
815
+ self._createOutputStream(options.optread, options.buffersize, callback);
816
+ });
817
+ }
818
+
819
+ ServiceManager.prototype.removeUser = function (username, rolename, callback) {
820
+ var blr = this.connection._blr;
821
+ blr.pos = 0;
822
+ blr.addByte(Const.isc_action_svc_delete_user);
823
+ blr.addString2(Const.isc_spb_sec_username, username, Const.DEFAULT_ENCODING);
824
+ if (rolename) blr.addString2(Const.isc_dpb_sql_role_name, rolename, Const.DEFAULT_ENCODING);
825
+
826
+ var self = this, options = {};
827
+ this.connection.svcstart(blr, function (err, data) {
828
+ if (err) {
829
+ doError(new Error(err), callback);
830
+ return;
831
+ }
832
+ self._createOutputStream(options.optread, options.buffersize, callback);
833
+ });
834
+ }
835
+
836
+ ServiceManager.prototype.getFbserverInfos = function (infos, options, callback) {
837
+ var buffersize = options.buffersize || 2048;
838
+ var timeout = options.timeout || 1;
839
+ var opts = {
840
+ "dbinfo" : Const.isc_info_svc_svr_db_info,
841
+ "fbconfig" : Const.isc_info_svc_get_config,
842
+ "svcversion" : Const.isc_info_svc_version,
843
+ "fbversion" : Const.isc_info_svc_server_version,
844
+ "fbimplementation" : Const.isc_info_svc_implementation,
845
+ "fbcapatibilities" : Const.isc_info_svc_capabilities,
846
+ "pathsecuritydb" : Const.isc_info_svc_user_dbpath,
847
+ "fbenv" : Const.isc_info_svc_get_env,
848
+ "fbenvlock" : Const.isc_info_svc_get_env_lock,
849
+ "fbenvmsg" : Const.isc_info_svc_get_env_msg
850
+ };
851
+ // if infos is empty all options are asked to the service
852
+
853
+ var tops = [], empty = isEmpty(infos);
854
+ for (let popts in opts)
855
+ if (empty || infos[popts])
856
+ tops.push(opts[popts]);
857
+
858
+ var self = this;
859
+ this.connection.svcquery(tops, buffersize, timeout, function (err, data) {
860
+ if (err || !data.buffer) {
861
+ doError(new Error(err||'Bad query return'), callback);
862
+ return;
863
+ }
864
+ self._processquery(data.buffer, callback);
865
+ });
866
+ }
867
+
868
+ function isEmpty(obj){
869
+ for(var p in obj) return false;
870
+ return true;
871
+ }
872
+
873
+ ServiceManager.prototype.startTrace = function (options, callback) {
874
+ var self = this;
875
+ var blr = this.connection._blr;
876
+ var configfile = options.configfile || '';
877
+ var tracename = options.tracename || '';
878
+
879
+ if (configfile.length === 0) {
880
+ doError(new Error('No config filename specified'), callback);
881
+ return;
882
+ }
883
+ if (tracename.length === 0) {
884
+ doError(new Error('No tracename specified'), callback);
885
+ return;
886
+ }
887
+
888
+ blr.pos = 0;
889
+ blr.addByte(Const.isc_action_svc_trace_start);
890
+ blr.addString2(Const.isc_spb_trc_cfg, configfile, Const.DEFAULT_ENCODING);
891
+ blr.addString2(Const.isc_spb_trc_name, tracename, Const.DEFAULT_ENCODING);
892
+ this.connection.svcstart(blr, function (err, data) {
893
+ if (err) {
894
+ doError(new Error(err), callback);
895
+ return;
896
+ }
897
+ self._createOutputStream(options.optread, options.buffersize, callback);
898
+ });
899
+ }
900
+
901
+ ServiceManager.prototype.suspendTrace = function (options, callback) {
902
+ var self = this;
903
+ var blr = this.connection._blr;
904
+ var traceid = options.traceid || null;
905
+
906
+ if (traceid == null) {
907
+ doError(new Error('No traceid specified'), callback);
908
+ return;
909
+ }
910
+
911
+ blr.pos = 0;
912
+ blr.addByte(Const.isc_action_svc_trace_suspend);
913
+ blr.addByteInt32(Const.isc_spb_trc_id, traceid);
914
+ this.connection.svcstart(blr, function (err, data) {
915
+ if (err) {
916
+ doError(new Error(err), callback);
917
+ return;
918
+ }
919
+ self._createOutputStream(options.optread, options.buffersize, callback);
920
+ });
921
+ }
922
+
923
+ ServiceManager.prototype.resumeTrace = function (options, callback) {
924
+ var self = this;
925
+ var blr = this.connection._blr;
926
+ var traceid = options.traceid || null;
927
+
928
+ if (traceid == null) {
929
+ doError(new Error('No traceid specified'), callback);
930
+ return;
931
+ }
932
+
933
+ blr.pos = 0;
934
+ blr.addByte(Const.isc_action_svc_trace_resume);
935
+ blr.addByteInt32(Const.isc_spb_trc_id, traceid);
936
+ this.connection.svcstart(blr, function (err, data) {
937
+ if (err) {
938
+ doError(new Error(err), callback);
939
+ return;
940
+ }
941
+ self._createOutputStream(options.optread, options.buffersize, callback);
942
+ });
943
+ }
944
+
945
+ ServiceManager.prototype.stopTrace = function (options, callback) {
946
+ var self = this;
947
+ var blr = this.connection._blr;
948
+ var traceid = options.traceid || null;
949
+
950
+ if (traceid == null) {
951
+ doError(new Error('No traceid specified'), callback);
952
+ return;
953
+ }
954
+
955
+ blr.pos = 0;
956
+ blr.addByte(Const.isc_action_svc_trace_stop);
957
+ blr.addByteInt32(Const.isc_spb_trc_id, traceid);
958
+ this.connection.svcstart(blr, function (err, data) {
959
+ if (err) {
960
+ doError(new Error(err), callback);
961
+ return;
962
+ }
963
+ self._createOutputStream(options.optread, options.buffersize, callback);
964
+ });
965
+ }
966
+
967
+ ServiceManager.prototype.getTraceList = function (options, callback) {
968
+ var self = this;
969
+ var blr = this.connection._blr;
970
+ blr.pos = 0;
971
+ blr.addByte(Const.isc_action_svc_trace_list);
972
+ this.connection.svcstart(blr, function (err, data) {
973
+ if (err) {
974
+ doError(new Error(err), callback);
975
+ return;
976
+ }
977
+ self._createOutputStream(options.optread, options.buffersize, callback);
978
+ });
979
+ }
980
+
981
+ ServiceManager.prototype.readline = function (options, callback) {
982
+ var buffersize = options.buffersize || 2048;
983
+ var timeout = options.timeout || 60;
984
+ var self = this;
985
+ this.connection.svcquery([Const.isc_info_svc_line], buffersize, timeout, function (err, data) {
986
+ if (err || !data.buffer) {
987
+ doError(new Error(err||'Bad query return'), callback);
988
+ return;
989
+ }
990
+ self._processquery(data.buffer, callback);
991
+ });
992
+ }
993
+
994
+ ServiceManager.prototype.readeof = function (options, callback) {
995
+ var buffersize = options.buffersize || (8 * 1024);
996
+ var timeout = options.timeout || 60;
997
+ var self = this;
998
+ this.connection.svcquery([Const.isc_info_svc_to_eof], buffersize, timeout, function (err, data) {
999
+ if (err || !data.buffer) {
1000
+ doError(new Error(err||'Bad query return'), callback);
1001
+ return;
1002
+ }
1003
+ self._processquery(data.buffer, callback);
1004
+ });
1005
+ }
1006
+
1007
+ ServiceManager.prototype.hasRunningAction = function (options, callback) {
1008
+ var buffersize = options.buffersize || 2048;
1009
+ var timeout = options.timeout || 60;
1010
+ var self = this;
1011
+ this.connection.svcquery([Const.isc_info_svc_running], buffersize, timeout, function (err, data) {
1012
+ if (err || !data.buffer) {
1013
+ doError(new Error(err||'Bad query return'), callback);
1014
+ return;
1015
+ }
1016
+ self._processquery(data.buffer, callback);
1017
+ });
1018
+ }
1019
+
1020
+ ServiceManager.prototype.readusers = function (options, callback) {
1021
+ var buffersize = options.buffersize || 2048;
1022
+ var timeout = options.timeout || 60;
1023
+ var self = this;
1024
+ this.connection.svcquery([Const.isc_info_svc_get_users], buffersize, timeout, function (err, data) {
1025
+ if (err || !data.buffer) {
1026
+ doError(new Error(err||'Bad query return'), callback);
1027
+ return;
1028
+ }
1029
+ self._processquery(data.buffer, callback);
1030
+ });
1031
+ }
1032
+
1033
+ ServiceManager.prototype.readlimbo = function (options, callback) {
1034
+ var buffersize = options.buffersize || 2048;
1035
+ var timeout = options.timeout || 60;
1036
+ var self = this;
1037
+ this.connection.svcquery([Const.isc_info_svc_limbo_trans], buffersize, timeout, function (err, data) {
1038
+ if (err || !data.buffer) {
1039
+ doError(new Error(err||'Bad query return'), callback);
1040
+ return;
1041
+ }
1042
+ self._processquery(data.buffer, callback);
1043
+ });
1044
+ }
1045
+
1046
+ module.exports = ServiceManager;