node-firebird 1.1.6 → 1.1.9

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.
package/lib/index.js CHANGED
@@ -1,19 +1,8 @@
1
- var
2
- net = require('net'),
3
- os = require('os'),
4
- Events = require('events'),
5
- stream = require('stream'),
6
- serialize = require('./serialize.js'),
7
- XdrReader = serialize.XdrReader,
8
- BlrReader = serialize.BlrReader,
9
- XdrWriter = serialize.XdrWriter,
10
- BlrWriter = serialize.BlrWriter,
11
- BitSet = serialize.BitSet,
12
- MessagesError = require('./firebird.msg.json'),
13
- crypt = require('./unix-crypt.js'),
14
- path = require('path'),
15
- srp = require('./srp'),
16
- BigInt = require('big-integer');
1
+ const Const = require('./wire/const');
2
+ const {doError, doCallback} = require('./callback');
3
+ const Connection = require('./wire/connection');
4
+ const Pool = require('./pool');
5
+ const {escape} = require('./utils');
17
6
 
18
7
  if (typeof(setImmediate) === 'undefined') {
19
8
  global.setImmediate = function(cb) {
@@ -21,4830 +10,126 @@ if (typeof(setImmediate) === 'undefined') {
21
10
  };
22
11
  }
23
12
 
24
- /**
25
- * Get Error Message per gdscode
26
- * @param {{gdscode: Number, params: Any[]}[]} status
27
- * @returns {String} - Error message
28
- */
29
- const lookupMessages = (status) => {
30
- const messages = status.map((item) => {
31
- let text = MessagesError[item.gdscode];
32
- if (text === undefined) {
33
- return 'Unknow error';
34
- }
35
- if (item.params !== undefined) {
36
- item.params.forEach((param, i) => {
37
- text = text.replace('@' + (i + 1), param);
38
- });
39
- }
40
- return text;
41
- });
42
- return messages.join(', ');
43
- }
44
-
45
- /**
46
- * Parse date from string
47
- * @param {String} str
48
- * @return {Date}
49
- */
50
- const parseDate = (str) => {
51
- const self = str.trim();
52
- const arr = self.indexOf(' ') === -1 ? self.split('T') : self.split(' ');
53
- let index = arr[0].indexOf(':');
54
- const length = arr[0].length;
55
-
56
- if (index !== -1) {
57
- const tmp = arr[1];
58
- arr[1] = arr[0];
59
- arr[0] = tmp;
60
- }
61
-
62
- if (arr[0] === undefined) {
63
- arr[0] = '';
64
- }
65
-
66
- const noTime = arr[1] === undefined || arr[1].length === 0;
67
-
68
- for (let i = 0; i < length; i++) {
69
- const c = arr[0].charCodeAt(i);
70
- if (c > 47 && c < 58) {
71
- continue;
72
- }
73
- if (c === 45 || c === 46) {
74
- continue;
75
- }
76
- if (noTime) {
77
- return new Date(self);
78
- }
79
- }
80
-
81
- if (arr[1] === undefined) {
82
- arr[1] = '00:00:00';
83
- }
84
-
85
- const firstDay = arr[0].indexOf('-') === -1;
86
-
87
- const date = (arr[0] || '').split(firstDay ? '.' : '-');
88
- const time = (arr[1] || '').split(':');
89
-
90
- if (date.length < 4 && time.length < 2) {
91
- return new Date(self);
92
- }
93
-
94
- index = (time[2] || '').indexOf('.');
95
-
96
- // milliseconds
97
- if (index !== -1) {
98
- time[3] = time[2].substring(index + 1);
99
- time[2] = time[2].substring(0, index);
100
- } else {
101
- time[3] = '0';
102
- }
103
-
104
- const parsed = [
105
- parseInt(date[firstDay ? 2 : 0], 10), // year
106
- parseInt(date[1], 10), // month
107
- parseInt(date[firstDay ? 0 : 2], 10), // day
108
- parseInt(time[0], 10), // hours
109
- parseInt(time[1], 10), // minutes
110
- parseInt(time[2], 10), // seconds
111
- parseInt(time[3], 10) // miliseconds
112
- ];
113
-
114
- const def = new Date();
115
-
116
- for (let i = 0; i < parsed.length; i++) {
117
- if (isNaN(parsed[i])) {
118
- parsed[i] = 0;
119
- }
120
-
121
- const value = parsed[i];
122
- if (value !== 0) {
123
- continue;
124
- }
125
-
126
- switch (i) {
127
- case 0:
128
- if (value <= 0) {
129
- parsed[i] = def.getFullYear();
130
- }
131
- break;
132
- case 1:
133
- if (value <= 0) {
134
- parsed[i] = def.getMonth() + 1;
135
- }
136
- break;
137
- case 2:
138
- if (value <= 0) {
139
- parsed[i] = def.getDate();
140
- }
141
- break;
142
- }
143
- }
144
-
145
- return new Date(parsed[0], parsed[1] - 1, parsed[2], parsed[3], parsed[4], parsed[5]);
146
- }
147
-
148
- function noop() {}
149
-
150
- const
151
- MAX_BUFFER_SIZE = 8192;
152
-
153
- const
154
- op_void = 0, // Packet has been voided
155
- op_connect = 1, // Connect to remote server
156
- op_exit = 2, // Remote end has exitted
157
- op_accept = 3, // Server accepts connection
158
- op_reject = 4, // Server rejects connection
159
- op_disconnect = 6, // Connect is going away
160
- op_response = 9, // Generic response block
161
-
162
- // Full context server operations
163
-
164
- op_attach = 19, // Attach database
165
- op_create = 20, // Create database
166
- op_detach = 21, // Detach database
167
- op_compile = 22, // Request based operations
168
- op_start = 23,
169
- op_start_and_send = 24,
170
- op_send = 25,
171
- op_receive = 26,
172
- op_unwind = 27, // apparently unused, see protocol.cpp's case op_unwind
173
- op_release = 28,
174
-
175
- op_transaction = 29, // Transaction operations
176
- op_commit = 30,
177
- op_rollback = 31,
178
- op_prepare = 32,
179
- op_reconnect = 33,
180
-
181
- op_create_blob = 34, // Blob operations
182
- op_open_blob = 35,
183
- op_get_segment = 36,
184
- op_put_segment = 37,
185
- op_cancel_blob = 38,
186
- op_close_blob = 39,
187
-
188
- op_info_database = 40, // Information services
189
- op_info_request = 41,
190
- op_info_transaction = 42,
191
- op_info_blob = 43,
192
-
193
- op_batch_segments = 44, // Put a bunch of blob segments
194
-
195
- op_que_events = 48, // Que event notification request
196
- op_cancel_events = 49, // Cancel event notification request
197
- op_commit_retaining = 50, // Commit retaining (what else)
198
- op_prepare2 = 51, // Message form of prepare
199
- op_event = 52, // Completed event request (asynchronous)
200
- op_connect_request = 53, // Request to establish connection
201
- op_aux_connect = 54, // Establish auxiliary connection
202
- op_ddl = 55, // DDL call
203
- op_open_blob2 = 56,
204
- op_create_blob2 = 57,
205
- op_get_slice = 58,
206
- op_put_slice = 59,
207
- op_slice = 60, // Successful response to op_get_slice
208
- op_seek_blob = 61, // Blob seek operation
209
-
210
- // DSQL operations
211
-
212
- op_allocate_statement = 62, // allocate a statment handle
213
- op_execute = 63, // execute a prepared statement
214
- op_exec_immediate = 64, // execute a statement
215
- op_fetch = 65, // fetch a record
216
- op_fetch_response = 66, // response for record fetch
217
- op_free_statement = 67, // free a statement
218
- op_prepare_statement = 68, // prepare a statement
219
- op_set_cursor = 69, // set a cursor name
220
- op_info_sql = 70,
221
-
222
- op_dummy = 71, // dummy packet to detect loss of client
223
- op_response_piggyback = 72, // response block for piggybacked messages
224
- op_start_and_receive = 73,
225
- op_start_send_and_receive = 74,
226
- op_exec_immediate2 = 75, // execute an immediate statement with msgs
227
- op_execute2 = 76, // execute a statement with msgs
228
- op_insert = 77,
229
- op_sql_response = 78, // response from execute, exec immed, insert
230
- op_transact = 79,
231
- op_transact_response = 80,
232
- op_drop_database = 81,
233
- op_service_attach = 82,
234
- op_service_detach = 83,
235
- op_service_info = 84,
236
- op_service_start = 85,
237
- op_rollback_retaining = 86,
238
- op_partial = 89, // packet is not complete - delay processing
239
- op_trusted_auth = 90,
240
- op_cancel = 91,
241
- op_cont_auth = 92,
242
- op_ping = 93,
243
- op_accept_data = 94, // Server accepts connection and returns some data to client
244
- op_abort_aux_connection = 95, // Async operation - stop waiting for async connection to arrive
245
- op_crypt = 96,
246
- op_crypt_key_callback = 97,
247
- op_cond_accept = 98; // Server accepts connection, returns some data to client
248
- // and asks client to continue authentication before attach call
249
-
250
- const
251
- CONNECT_VERSION2 = 2,
252
- CONNECT_VERSION3 = 3,
253
- ARCHITECTURE_GENERIC = 1;
254
-
255
- const
256
- // Protocol 10 includes support for warnings and removes the requirement for
257
- // encoding and decoding status codes
258
- PROTOCOL_VERSION10 = 10,
259
-
260
- // Since protocol 11 we must be separated from Borland Interbase.
261
- // Therefore always set highmost bit in protocol version to 1.
262
- // For unsigned protocol version this does not break version's compare.
263
-
264
- FB_PROTOCOL_FLAG = 0x8000,
265
- FB_PROTOCOL_MASK = ~FB_PROTOCOL_FLAG & 0xFFFF,
266
-
267
- // Protocol 11 has support for user authentication related
268
- // operations (op_update_account_info, op_authenticate_user and
269
- // op_trusted_auth). When specific operation is not supported,
270
- // we say "sorry".
271
-
272
- PROTOCOL_VERSION11 = (FB_PROTOCOL_FLAG | 11),
273
-
274
- // Protocol 12 has support for asynchronous call op_cancel.
275
- // Currently implemented asynchronously only for TCP/IP.
276
-
277
- PROTOCOL_VERSION12 = (FB_PROTOCOL_FLAG | 12),
278
-
279
- // Protocol 13 has support for authentication plugins (op_cont_auth).
280
-
281
- PROTOCOL_VERSION13 = (FB_PROTOCOL_FLAG | 13);
282
-
283
- const
284
- CNCT_user = 1, // User name
285
- CNCT_passwd = 2,
286
- // CNCT_ppo = 3, // Apollo person, project, organization. OBSOLETE.
287
- CNCT_host = 4,
288
- CNCT_group = 5, // Effective Unix group id
289
- CNCT_user_verification = 6, // Attach/create using this connection will use user verification
290
- CNCT_specific_data = 7, // Some data, needed for user verification on server
291
- CNCT_plugin_name = 8, // Name of plugin, which generated that data
292
- CNCT_login = 9, // Same data as isc_dpb_user_name
293
- CNCT_plugin_list = 10, // List of plugins, available on client
294
- CNCT_client_crypt = 11, // Client encyption level (DISABLED/ENABLED/REQUIRED)
295
- WIRE_CRYPT_DISABLED = 0,
296
- WIRE_CRYPT_ENABLED = 1,
297
- WIRE_CRYPT_REQUIRED = 2;
298
-
299
- const
300
- DSQL_close = 1,
301
- DSQL_drop = 2,
302
- DSQL_unprepare = 4; // >= 2.5
303
-
304
- // Protocols types (accept_type)
305
- const
306
- ptype_rpc = 2, // Simple remote procedure call
307
- ptype_batch_send = 3, // Batch sends, no asynchrony
308
- ptype_out_of_band = 4, // Batch sends w/ out of band notification
309
- ptype_lazy_send = 5, // Deferred packets delivery;
310
- ptype_mask = 0xFF, // Mask - up to 255 types of protocol
311
- pflag_compress = 0x100; // Turn on compression if possible
312
-
313
- const SUPPORTED_PROTOCOL = [
314
- [PROTOCOL_VERSION10, ARCHITECTURE_GENERIC, ptype_rpc, ptype_batch_send, 1],
315
- [PROTOCOL_VERSION11, ARCHITECTURE_GENERIC, ptype_lazy_send, ptype_lazy_send, 2],
316
- [PROTOCOL_VERSION12, ARCHITECTURE_GENERIC, ptype_lazy_send, ptype_lazy_send, 3],
317
- [PROTOCOL_VERSION13, ARCHITECTURE_GENERIC, ptype_lazy_send, ptype_lazy_send, 4],
318
- ];
319
-
320
- const
321
- SQL_TEXT = 452, // Array of char
322
- SQL_VARYING = 448,
323
- SQL_SHORT = 500,
324
- SQL_LONG = 496,
325
- SQL_FLOAT = 482,
326
- SQL_DOUBLE = 480,
327
- SQL_D_FLOAT = 530,
328
- SQL_TIMESTAMP = 510,
329
- SQL_BLOB = 520,
330
- SQL_ARRAY = 540,
331
- SQL_QUAD = 550,
332
- SQL_TYPE_TIME = 560,
333
- SQL_TYPE_DATE = 570,
334
- SQL_INT64 = 580,
335
- SQL_BOOLEAN = 32764, // >= 3.0
336
- SQL_NULL = 32766; // >= 2.5
337
-
338
- /***********************/
339
- /* ISC Services */
340
- /***********************/
341
- const
342
- isc_action_svc_backup = 1, /* Starts database backup process on the server */
343
- isc_action_svc_restore = 2, /* Starts database restore process on the server */
344
- isc_action_svc_repair = 3, /* Starts database repair process on the server */
345
- isc_action_svc_add_user = 4, /* Adds a new user to the security database */
346
- isc_action_svc_delete_user = 5, /* Deletes a user record from the security database */
347
- isc_action_svc_modify_user = 6, /* Modifies a user record in the security database */
348
- isc_action_svc_display_user = 7, /* Displays a user record from the security database */
349
- isc_action_svc_properties = 8, /* Sets database properties */
350
- isc_action_svc_add_license = 9, /* Adds a license to the license file */
351
- isc_action_svc_remove_license = 10, /* Removes a license from the license file */
352
- isc_action_svc_db_stats = 11, /* Retrieves database statistics */
353
- isc_action_svc_get_ib_log = 12, /* Retrieves the InterBase log file from the server */
354
- isc_action_svc_get_fb_log = isc_action_svc_get_ib_log, /* Retrieves the Firebird log file from the server */
355
- isc_action_svc_nbak = 20, /* start nbackup */
356
- isc_action_svc_nrest = 21, /* start nrestore */
357
- isc_action_svc_trace_start = 22,
358
- isc_action_svc_trace_stop = 23,
359
- isc_action_svc_trace_suspend = 24,
360
- isc_action_svc_trace_resume = 25,
361
- isc_action_svc_trace_list = 26;
362
-
363
- const
364
- isc_info_svc_svr_db_info = 50, /* Retrieves the number of attachments and databases */
365
- isc_info_svc_get_license = 51, /* Retrieves all license keys and IDs from the license file */
366
- isc_info_svc_get_license_mask = 52, /* Retrieves a bitmask representing licensed options on the server */
367
- isc_info_svc_get_config = 53, /* Retrieves the parameters and values for IB_CONFIG */
368
- isc_info_svc_version = 54, /* Retrieves the version of the services manager */
369
- isc_info_svc_server_version = 55, /* Retrieves the version of the InterBase server */
370
- isc_info_svc_implementation = 56, /* Retrieves the implementation of the InterBase server */
371
- isc_info_svc_capabilities = 57, /* Retrieves a bitmask representing the server's capabilities */
372
- isc_info_svc_user_dbpath = 58, /* Retrieves the path to the security database in use by the server */
373
- isc_info_svc_get_env = 59, /* Retrieves the setting of $INTERBASE */
374
- isc_info_svc_get_env_lock = 60, /* Retrieves the setting of $INTERBASE_LCK */
375
- isc_info_svc_get_env_msg = 61, /* Retrieves the setting of $INTERBASE_MSG */
376
- isc_info_svc_line = 62, /* Retrieves 1 line of service output per call */
377
- isc_info_svc_to_eof = 63, /* Retrieves as much of the server output as will fit in the supplied buffer */
378
- isc_info_svc_timeout = 64, /* Sets / signifies a timeout value for reading service information */
379
- isc_info_svc_get_licensed_users = 65, /* Retrieves the number of users licensed for accessing the server */
380
- isc_info_svc_limbo_trans = 66, /* Retrieve the limbo transactions */
381
- isc_info_svc_running = 67, /* Checks to see if a service is running on an attachment */
382
- isc_info_svc_get_users = 68, /* Returns the user information from isc_action_svc_display_users */
383
- isc_info_svc_stdin = 78;
384
-
385
- /* Services Properties */
386
- const
387
- isc_spb_prp_page_buffers = 5,
388
- isc_spb_prp_sweep_interval = 6,
389
- isc_spb_prp_shutdown_db = 7,
390
- isc_spb_prp_deny_new_attachments = 9,
391
- isc_spb_prp_deny_new_transactions = 10,
392
- isc_spb_prp_reserve_space = 11,
393
- isc_spb_prp_write_mode = 12,
394
- isc_spb_prp_access_mode = 13,
395
- isc_spb_prp_set_sql_dialect = 14,
396
- isc_spb_num_att = 5,
397
- isc_spb_num_db = 6,
398
- // SHUTDOWN OPTION FOR 2.0
399
- isc_spb_prp_force_shutdown = 41,
400
- isc_spb_prp_attachments_shutdown = 42,
401
- isc_spb_prp_transactions_shutdown = 43,
402
- isc_spb_prp_shutdown_mode = 44,
403
- isc_spb_prp_online_mode = 45,
404
-
405
- isc_spb_prp_sm_normal = 0,
406
- isc_spb_prp_sm_multi = 1,
407
- isc_spb_prp_sm_single = 2,
408
- isc_spb_prp_sm_full = 3,
409
-
410
-
411
- // WRITE_MODE_PARAMETERS
412
- isc_spb_prp_wm_async = 37,
413
- isc_spb_prp_wm_sync = 38,
414
-
415
- // ACCESS_MODE_PARAMETERS
416
- isc_spb_prp_am_readonly = 39,
417
- isc_spb_prp_am_readwrite = 40,
418
-
419
- // RESERVE_SPACE_PARAMETERS
420
- isc_spb_prp_res_use_full = 35,
421
- isc_spb_prp_res = 36,
422
-
423
- // Option Flags
424
- isc_spb_prp_activate = 0x0100,
425
- isc_spb_prp_db_online = 0x0200;
426
-
427
- // SHUTDOWN MODE
428
-
429
- /* · Backup Service ·*/
430
- const
431
- isc_spb_bkp_file = 5,
432
- isc_spb_bkp_factor = 6,
433
- isc_spb_bkp_length = 7,
434
- isc_spb_bkp_ignore_checksums = 0x01,
435
- isc_spb_bkp_ignore_limbo = 0x02,
436
- isc_spb_bkp_metadata_only = 0x04,
437
- isc_spb_bkp_no_garbage_collect = 0x08,
438
- isc_spb_bkp_old_descriptions = 0x10,
439
- isc_spb_bkp_non_transportable = 0x20,
440
- isc_spb_bkp_convert = 0x40,
441
- isc_spb_bkp_expand = 0x80,
442
- isc_spb_bkp_no_triggers = 0x8000,
443
- // nbackup
444
- isc_spb_nbk_level = 5,
445
- isc_spb_nbk_file = 6,
446
- isc_spb_nbk_direct = 7,
447
- isc_spb_nbk_no_triggers = 0x01;
448
-
449
- /* Restore Service ·*/
450
- const
451
- isc_spb_res_buffers = 9,
452
- isc_spb_res_page_size = 10,
453
- isc_spb_res_length = 11,
454
- isc_spb_res_access_mode = 12,
455
- isc_spb_res_fix_fss_data = 13,
456
- isc_spb_res_fix_fss_metadata = 14,
457
- isc_spb_res_am_readonly = isc_spb_prp_am_readonly,
458
- isc_spb_res_am_readwrite = isc_spb_prp_am_readwrite,
459
- isc_spb_res_deactivate_idx = 0x0100,
460
- isc_spb_res_no_shadow = 0x0200,
461
- isc_spb_res_no_validity = 0x0400,
462
- isc_spb_res_one_at_a_time = 0x0800,
463
- isc_spb_res_replace = 0x1000,
464
- isc_spb_res_create = 0x2000,
465
- isc_spb_res_use_all_space = 0x4000;
466
-
467
-
468
- /* · Repair Service ·*/
469
- const
470
- isc_spb_rpr_commit_trans = 15,
471
- isc_spb_rpr_rollback_trans = 34,
472
- isc_spb_rpr_recover_two_phase = 17,
473
- isc_spb_tra_id = 18,
474
- isc_spb_single_tra_id = 19,
475
- isc_spb_multi_tra_id = 20,
476
- isc_spb_tra_state = 21,
477
- isc_spb_tra_state_limbo = 22,
478
- isc_spb_tra_state_commit = 23,
479
- isc_spb_tra_state_rollback = 24,
480
- isc_spb_tra_state_unknown = 25,
481
- isc_spb_tra_host_site = 26,
482
- isc_spb_tra_remote_site = 27,
483
- isc_spb_tra_db_path = 28,
484
- isc_spb_tra_advise = 29,
485
- isc_spb_tra_advise_commit = 30,
486
- isc_spb_tra_advise_rollback = 31,
487
- isc_spb_tra_advise_unknown = 33,
488
- isc_spb_rpr_validate_db = 0x01,
489
- isc_spb_rpr_sweep_db = 0x02,
490
- isc_spb_rpr_mend_db = 0x04,
491
- isc_spb_rpr_list_limbo_trans = 0x08,
492
- isc_spb_rpr_check_db = 0x10,
493
- isc_spb_rpr_ignore_checksum = 0x20,
494
- isc_spb_rpr_kill_shadows = 0x40,
495
- isc_spb_rpr_full = 0x80,
496
- isc_spb_rpr_icu = 0x0800;
497
-
498
- /* · Security Service ·*/
499
- const
500
- isc_spb_sec_userid = 5,
501
- isc_spb_sec_groupid = 6,
502
- isc_spb_sec_username = 7,
503
- isc_spb_sec_password = 8,
504
- isc_spb_sec_groupname = 9,
505
- isc_spb_sec_firstname = 10,
506
- isc_spb_sec_middlename = 11,
507
- isc_spb_sec_lastname = 12,
508
- isc_spb_sec_admin = 13;
509
-
510
- /* License Service */
511
- const
512
- isc_spb_lic_key = 5,
513
- isc_spb_lic_id = 6,
514
- isc_spb_lic_desc = 7;
515
-
516
- /* Statistics Service */
517
- const
518
- isc_spb_sts_data_pages = 0x01,
519
- isc_spb_sts_db_log = 0x02,
520
- isc_spb_sts_hdr_pages = 0x04,
521
- isc_spb_sts_idx_pages = 0x08,
522
- isc_spb_sts_sys_relations = 0x10,
523
- isc_spb_sts_record_versions = 0x20,
524
- isc_spb_sts_table = 0x40,
525
- isc_spb_sts_nocreation = 0x80;
526
-
527
- /* Trace Service */
528
- const
529
- isc_spb_trc_id = 1,
530
- isc_spb_trc_name = 2,
531
- isc_spb_trc_cfg = 3;
532
-
533
-
534
- /***********************/
535
- /* ISC Error Codes */
536
- /***********************/
537
- const
538
- isc_arg_end = 0, // end of argument list
539
- isc_arg_gds = 1, // generic DSRI status value
540
- isc_arg_string = 2, // string argument
541
- isc_arg_cstring = 3, // count & string argument
542
- isc_arg_number = 4, // numeric argument (long)
543
- isc_arg_interpreted = 5, // interpreted status code (string)
544
- isc_arg_unix = 7, // UNIX error code
545
- isc_arg_next_mach = 15, // NeXT/Mach error code
546
- isc_arg_win32 = 17, // Win32 error code
547
- isc_arg_warning = 18, // warning argument
548
- isc_arg_sql_state = 19; // SQLSTATE
549
-
550
- const
551
- isc_sqlerr = 335544436;
552
-
553
- /**********************************/
554
- /* Database parameter block stuff */
555
- /**********************************/
556
- const
557
- isc_dpb_version1 = 1,
558
- isc_dpb_version2 = 2, // >= FB30
559
- isc_dpb_cdd_pathname = 1,
560
- isc_dpb_allocation = 2,
561
- isc_dpb_journal = 3,
562
- isc_dpb_page_size = 4,
563
- isc_dpb_num_buffers = 5,
564
- isc_dpb_buffer_length = 6,
565
- isc_dpb_debug = 7,
566
- isc_dpb_garbage_collect = 8,
567
- isc_dpb_verify = 9,
568
- isc_dpb_sweep = 10,
569
- isc_dpb_enable_journal = 11,
570
- isc_dpb_disable_journal = 12,
571
- isc_dpb_dbkey_scope = 13,
572
- isc_dpb_number_of_users = 14,
573
- isc_dpb_trace = 15,
574
- isc_dpb_no_garbage_collect = 16,
575
- isc_dpb_damaged = 17,
576
- isc_dpb_license = 18,
577
- isc_dpb_sys_user_name = 19,
578
- isc_dpb_encrypt_key = 20,
579
- isc_dpb_activate_shadow = 21,
580
- isc_dpb_sweep_interval = 22,
581
- isc_dpb_delete_shadow = 23,
582
- isc_dpb_force_write = 24,
583
- isc_dpb_begin_log = 25,
584
- isc_dpb_quit_log = 26,
585
- isc_dpb_no_reserve = 27,
586
- isc_dpb_user_name = 28,
587
- isc_dpb_password = 29,
588
- isc_dpb_password_enc = 30,
589
- isc_dpb_sys_user_name_enc = 31,
590
- isc_dpb_interp = 32,
591
- isc_dpb_online_dump = 33,
592
- isc_dpb_old_file_size = 34,
593
- isc_dpb_old_num_files = 35,
594
- isc_dpb_old_file = 36,
595
- isc_dpb_old_start_page = 37,
596
- isc_dpb_old_start_seqno = 38,
597
- isc_dpb_old_start_file = 39,
598
- isc_dpb_old_dump_id = 41,
599
- isc_dpb_lc_messages = 47,
600
- isc_dpb_lc_ctype = 48,
601
- isc_dpb_cache_manager = 49,
602
- isc_dpb_shutdown = 50,
603
- isc_dpb_online = 51,
604
- isc_dpb_shutdown_delay = 52,
605
- isc_dpb_reserved = 53,
606
- isc_dpb_overwrite = 54,
607
- isc_dpb_sec_attach = 55,
608
- isc_dpb_connect_timeout = 57,
609
- isc_dpb_dummy_packet_interval = 58,
610
- isc_dpb_gbak_attach = 59,
611
- isc_dpb_sql_role_name = 60,
612
- isc_dpb_set_page_buffers = 61,
613
- isc_dpb_working_directory = 62,
614
- isc_dpb_sql_dialect = 63,
615
- isc_dpb_set_db_readonly = 64,
616
- isc_dpb_set_db_sql_dialect = 65,
617
- isc_dpb_gfix_attach = 66,
618
- isc_dpb_gstat_attach = 67,
619
- isc_dpb_set_db_charset = 68,
620
- isc_dpb_gsec_attach = 69,
621
- isc_dpb_address_path = 70,
622
- isc_dpb_process_id = 71,
623
- isc_dpb_no_db_triggers = 72,
624
- isc_dpb_trusted_auth = 73,
625
- isc_dpb_process_name = 74,
626
- isc_dpb_trusted_role = 75,
627
- isc_dpb_org_filename = 76,
628
- isc_dpb_utf8_filename = 77,
629
- isc_dpb_ext_call_depth = 78,
630
- isc_dpb_auth_block = 79,
631
- isc_dpb_client_version = 80,
632
- isc_dpb_remote_protocol = 81,
633
- isc_dpb_host_name = 82,
634
- isc_dpb_os_user = 83,
635
- isc_dpb_specific_auth_data = 84,
636
- isc_dpb_auth_plugin_list = 85,
637
- isc_dpb_auth_plugin_name = 86,
638
- isc_dpb_config = 87,
639
- isc_dpb_nolinger = 88,
640
- isc_dpb_reset_icu = 89,
641
- isc_dpb_map_attach = 90,
642
- isc_dpb_session_time_zone = 91;
643
-
644
- /*************************************/
645
- /* Services parameter block stuff */
646
- /*************************************/
647
- const
648
- isc_spb_version1 = 1,
649
- isc_spb_current_version = 2,
650
- isc_spb_version = isc_spb_current_version,
651
- isc_spb_user_name = isc_dpb_user_name,
652
- isc_spb_sys_user_name = isc_dpb_sys_user_name,
653
- isc_spb_sys_user_name_enc = isc_dpb_sys_user_name_enc,
654
- isc_spb_password = isc_dpb_password,
655
- isc_spb_password_enc = isc_dpb_password_enc,
656
- isc_spb_command_line = 105,
657
- isc_spb_dbname = 106,
658
- isc_spb_verbose = 107,
659
- isc_spb_options = 108;
660
-
661
- /*************************************/
662
- /* Transaction parameter block stuff */
663
- /*************************************/
664
- const
665
- isc_tpb_version1 = 1,
666
- isc_tpb_version3 = 3,
667
- isc_tpb_consistency = 1,
668
- isc_tpb_concurrency = 2,
669
- isc_tpb_shared = 3, // < FB21
670
- isc_tpb_protected = 4, // < FB21
671
- isc_tpb_exclusive = 5, // < FB21
672
- isc_tpb_wait = 6,
673
- isc_tpb_nowait = 7,
674
- isc_tpb_read = 8,
675
- isc_tpb_write = 9,
676
- isc_tpb_lock_read = 10,
677
- isc_tpb_lock_write = 11,
678
- isc_tpb_verb_time = 12,
679
- isc_tpb_commit_time = 13,
680
- isc_tpb_ignore_limbo = 14,
681
- isc_tpb_read_committed = 15,
682
- isc_tpb_autocommit = 16,
683
- isc_tpb_rec_version = 17,
684
- isc_tpb_no_rec_version = 18,
685
- isc_tpb_restart_requests = 19,
686
- isc_tpb_no_auto_undo = 20,
687
- isc_tpb_lock_timeout = 21; // >= FB20
688
-
689
- /****************************/
690
- /* Common, structural codes */
691
- /****************************/
692
- const
693
- isc_info_end = 1,
694
- isc_info_truncated = 2,
695
- isc_info_error = 3,
696
- isc_info_data_not_ready = 4,
697
- isc_info_length = 126,
698
- isc_info_flag_end = 127;
699
-
700
- /*************************/
701
- /* SQL information items */
702
- /*************************/
703
- const
704
- isc_info_sql_select = 4,
705
- isc_info_sql_bind = 5,
706
- isc_info_sql_num_variables = 6,
707
- isc_info_sql_describe_vars = 7,
708
- isc_info_sql_describe_end = 8,
709
- isc_info_sql_sqlda_seq = 9,
710
- isc_info_sql_message_seq = 10,
711
- isc_info_sql_type = 11,
712
- isc_info_sql_sub_type = 12,
713
- isc_info_sql_scale = 13,
714
- isc_info_sql_length = 14,
715
- isc_info_sql_null_ind = 15,
716
- isc_info_sql_field = 16,
717
- isc_info_sql_relation = 17,
718
- isc_info_sql_owner = 18,
719
- isc_info_sql_alias = 19,
720
- isc_info_sql_sqlda_start = 20,
721
- isc_info_sql_stmt_type = 21,
722
- isc_info_sql_get_plan = 22,
723
- isc_info_sql_records = 23,
724
- isc_info_sql_batch_fetch = 24,
725
- isc_info_sql_relation_alias = 25, // >= 2.0
726
- isc_info_sql_explain_plan = 26; // >= 3.0
727
-
728
- /*******************/
729
- /* Blr definitions */
730
- /*******************/
731
- const
732
- blr_text = 14,
733
- blr_text2 = 15,
734
- blr_short = 7,
735
- blr_long = 8,
736
- blr_quad = 9,
737
- blr_float = 10,
738
- blr_double = 27,
739
- blr_d_float = 11,
740
- blr_timestamp = 35,
741
- blr_varying = 37,
742
- blr_varying2 = 38,
743
- blr_blob = 261,
744
- blr_cstring = 40,
745
- blr_cstring2 = 41,
746
- blr_blob_id = 45,
747
- blr_sql_date = 12,
748
- blr_sql_time = 13,
749
- blr_int64 = 16,
750
- blr_blob2 = 17, // >= 2.0
751
- blr_domain_name = 18, // >= 2.1
752
- blr_domain_name2 = 19, // >= 2.1
753
- blr_not_nullable = 20, // >= 2.1
754
- blr_column_name = 21, // >= 2.5
755
- blr_column_name2 = 22, // >= 2.5
756
- blr_bool = 23, // >= 3.0
757
-
758
- blr_version4 = 4,
759
- blr_version5 = 5, // dialect 3
760
- blr_eoc = 76,
761
- blr_end = 255,
762
-
763
- blr_assignment = 1,
764
- blr_begin = 2,
765
- blr_dcl_variable = 3,
766
- blr_message = 4;
767
-
768
- const
769
- isc_info_sql_stmt_select = 1,
770
- isc_info_sql_stmt_insert = 2,
771
- isc_info_sql_stmt_update = 3,
772
- isc_info_sql_stmt_delete = 4,
773
- isc_info_sql_stmt_ddl = 5,
774
- isc_info_sql_stmt_get_segment = 6,
775
- isc_info_sql_stmt_put_segment = 7,
776
- isc_info_sql_stmt_exec_procedure = 8,
777
- isc_info_sql_stmt_start_trans = 9,
778
- isc_info_sql_stmt_commit = 10,
779
- isc_info_sql_stmt_rollback = 11,
780
- isc_info_sql_stmt_select_for_upd = 12,
781
- isc_info_sql_stmt_set_generator = 13,
782
- isc_info_sql_stmt_savepoint = 14;
783
-
784
- const
785
- isc_blob_text = 1;
786
-
787
- const DESCRIBE = [
788
- isc_info_sql_stmt_type,
789
- isc_info_sql_select,
790
- isc_info_sql_describe_vars,
791
- isc_info_sql_sqlda_seq,
792
- isc_info_sql_type,
793
- isc_info_sql_sub_type,
794
- isc_info_sql_scale,
795
- isc_info_sql_length,
796
- isc_info_sql_field,
797
- isc_info_sql_relation,
798
- //isc_info_sql_owner,
799
- isc_info_sql_alias,
800
- isc_info_sql_describe_end,
801
- isc_info_sql_bind,
802
- isc_info_sql_describe_vars,
803
- isc_info_sql_sqlda_seq,
804
- isc_info_sql_type,
805
- isc_info_sql_sub_type,
806
- isc_info_sql_scale,
807
- isc_info_sql_length,
808
- isc_info_sql_describe_end
809
- ];
810
-
811
- const
812
- ISOLATION_READ_UNCOMMITTED = [isc_tpb_version3, isc_tpb_write, isc_tpb_wait, isc_tpb_read_committed, isc_tpb_rec_version],
813
- ISOLATION_READ_COMMITTED = [isc_tpb_version3, isc_tpb_write, isc_tpb_wait, isc_tpb_read_committed, isc_tpb_no_rec_version],
814
- ISOLATION_REPEATABLE_READ = [isc_tpb_version3, isc_tpb_write, isc_tpb_wait, isc_tpb_concurrency],
815
- ISOLATION_SERIALIZABLE = [isc_tpb_version3, isc_tpb_write, isc_tpb_wait, isc_tpb_consistency],
816
- ISOLATION_READ_COMMITTED_READ_ONLY = [isc_tpb_version3, isc_tpb_read, isc_tpb_wait, isc_tpb_read_committed, isc_tpb_no_rec_version];
817
-
818
- const
819
- DEFAULT_HOST = '127.0.0.1',
820
- DEFAULT_PORT = 3050,
821
- DEFAULT_USER = 'SYSDBA',
822
- DEFAULT_PASSWORD = 'masterkey',
823
- DEFAULT_LOWERCASE_KEYS = false,
824
- DEFAULT_PAGE_SIZE = 4096,
825
- DEFAULT_SVC_NAME = 'service_mgr';
826
-
827
- const AUTH_PLUGIN_LEGACY = 'Legacy_Auth',
828
- AUTH_PLUGIN_SRP = 'Srp';
829
- // AUTH_PLUGIN_SRP256 = 'Srp256';
830
-
831
- const
832
- // AUTH_PLUGIN_LIST = [AUTH_PLUGIN_SRP256, AUTH_PLUGIN_SRP, AUTH_PLUGIN_LEGACY],
833
- AUTH_PLUGIN_LIST = [AUTH_PLUGIN_SRP, AUTH_PLUGIN_LEGACY],
834
- // AUTH_PLUGIN_SRP_LIST = [AUTH_PLUGIN_SRP256, AUTH_PLUGIN_SRP],
835
- AUTH_PLUGIN_SRP_LIST = [AUTH_PLUGIN_SRP],
836
- LEGACY_AUTH_SALT = '9z',
837
- WIRE_CRYPT_DISABLE = 0,
838
- WIRE_CRYPT_ENABLE = 1;
839
-
840
- exports.AUTH_PLUGIN_LEGACY = AUTH_PLUGIN_LEGACY;
841
- exports.AUTH_PLUGIN_SRP = AUTH_PLUGIN_SRP;
842
- // exports.AUTH_PLUGIN_SRP256 = AUTH_PLUGIN_SRP256;
843
-
844
- exports.WIRE_CRYPT_DISABLE = WIRE_CRYPT_DISABLE;
845
- exports.WIRE_CRYPT_ENABLE = WIRE_CRYPT_ENABLE;
846
-
847
- exports.ISOLATION_READ_UNCOMMITTED = ISOLATION_READ_UNCOMMITTED;
848
- exports.ISOLATION_READ_COMMITTED = ISOLATION_READ_COMMITTED;
849
- exports.ISOLATION_REPEATABLE_READ = ISOLATION_REPEATABLE_READ;
850
- exports.ISOLATION_SERIALIZABLE = ISOLATION_SERIALIZABLE;
851
- exports.ISOLATION_READ_COMMITTED_READ_ONLY = ISOLATION_READ_COMMITTED_READ_ONLY;
852
-
853
- if (!String.prototype.padLeft) {
854
- String.prototype.padLeft = function(max, c) {
855
- var self = this;
856
- return new Array(Math.max(0, max - self.length + 1)).join(c || ' ') + self;
857
- };
858
- }
859
-
860
- /**
861
- * Escape value
862
- * @param {Object} value
863
- * @param {Number} protocolVersion (optional, default: PROTOCOL_VERSION13)
864
- * @return {String}
865
- */
866
- exports.escape = function(value, protocolVersion) {
867
-
868
- if (value === null || value === undefined)
869
- return 'NULL';
870
-
871
- switch (typeof(value)) {
872
- case 'boolean':
873
- if ((protocolVersion || PROTOCOL_VERSION13) >= PROTOCOL_VERSION13)
874
- return value ? 'true' : 'false';
875
- else
876
- return value ? '1' : '0';
877
- case 'number':
878
- return value.toString();
879
- case 'string':
880
- return "'" + value.replace(/'/g, "''").replace(/\\/g, '\\\\') + "'";
881
- }
882
-
883
- if (value instanceof Date)
884
- return "'" + value.getFullYear() + '-' + (value.getMonth()+1).toString().padLeft(2, '0') + '-' + value.getDate().toString().padLeft(2, '0') + ' ' + value.getHours().toString().padLeft(2, '0') + ':' + value.getMinutes().toString().padLeft(2, '0') + ':' + value.getSeconds().toString().padLeft(2, '0') + '.' + value.getMilliseconds().toString().padLeft(3, '0') + "'";
885
-
886
- throw new Error('Escape supports only primitive values.');
887
- };
888
-
889
- const
890
- DEFAULT_ENCODING = 'utf8',
891
- DEFAULT_FETCHSIZE = 200;
892
-
893
- const
894
- MAX_INT = Math.pow(2, 31) - 1,
895
- MIN_INT = - Math.pow(2, 31);
896
-
897
- /***************************************
898
- *
899
- * SQLVar
900
- *
901
- ***************************************/
902
-
903
-
904
- const
905
- ScaleDivisor = [1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000, 100000000000,1000000000000,10000000000000,100000000000000,1000000000000000];
906
- const
907
- DateOffset = 40587,
908
- TimeCoeff = 86400000,
909
- MsPerMinute = 60000;
910
-
911
- //------------------------------------------------------
912
-
913
- function SQLVarText() {}
914
-
915
- SQLVarText.prototype.decode = function(data, lowerV13) {
916
- let ret;
917
- if (this.subType > 1) {
918
- // ToDo: with column charset
919
- ret = data.readText(this.length, DEFAULT_ENCODING);
920
- } else if (this.subType === 0) {
921
- // without charset definition
922
- ret = data.readText(this.length, DEFAULT_ENCODING);
923
- } else {
924
- ret = data.readBuffer(this.length);
925
- }
926
-
927
- if (!lowerV13 || !data.readInt()) {
928
- return ret;
929
- }
930
-
931
- return null;
932
- };
933
-
934
- SQLVarText.prototype.calcBlr = function(blr) {
935
- blr.addByte(blr_text);
936
- blr.addWord(this.length);
937
- };
938
-
939
- //------------------------------------------------------
940
-
941
- function SQLVarNull() {}
942
- SQLVarNull.prototype = new SQLVarText();
943
- SQLVarNull.prototype.constructor = SQLVarNull;
944
-
945
- //------------------------------------------------------
946
-
947
- function SQLVarString() {}
948
-
949
- SQLVarString.prototype.decode = function(data, lowerV13) {
950
- let ret;
951
- if (this.subType > 1) {
952
- // ToDo: with column charset
953
- ret = data.readString(DEFAULT_ENCODING);
954
- } else if (this.subType === 0) {
955
- // without charset definition
956
- ret = data.readString(DEFAULT_ENCODING);
957
- } else {
958
- ret = data.readBuffer();
959
- }
960
-
961
- if (!lowerV13 || !data.readInt()) {
962
- return ret;
963
- }
964
-
965
- return null;
966
- };
967
-
968
- SQLVarString.prototype.calcBlr = function(blr) {
969
- blr.addByte(blr_varying);
970
- blr.addWord(this.length);
971
- };
972
-
973
- //------------------------------------------------------
974
-
975
- function SQLVarQuad() {}
976
-
977
- SQLVarQuad.prototype.decode = function(data, lowerV13) {
978
- var ret = data.readQuad();
979
-
980
- if (!lowerV13 || !data.readInt()) {
981
- return ret;
982
- }
983
- return null;
984
- };
985
-
986
- SQLVarQuad.prototype.calcBlr = function(blr) {
987
- blr.addByte(blr_quad);
988
- blr.addShort(this.scale);
989
- };
990
-
991
- //------------------------------------------------------
992
-
993
- function SQLVarBlob() {}
994
- SQLVarBlob.prototype = new SQLVarQuad();
995
- SQLVarBlob.prototype.constructor = SQLVarBlob;
996
-
997
- SQLVarBlob.prototype.calcBlr = function(blr) {
998
- blr.addByte(blr_quad);
999
- blr.addShort(0);
1000
- };
1001
-
1002
- //------------------------------------------------------
1003
-
1004
- function SQLVarArray() {}
1005
- SQLVarArray.prototype = new SQLVarQuad();
1006
- SQLVarArray.prototype.constructor = SQLVarArray;
1007
-
1008
- SQLVarArray.prototype.calcBlr = function(blr) {
1009
- blr.addByte(blr_quad);
1010
- blr.addShort(0);
1011
- };
1012
-
1013
- //------------------------------------------------------
1014
-
1015
- function SQLVarInt() {}
1016
-
1017
- SQLVarInt.prototype.decode = function(data, lowerV13) {
1018
- var ret = data.readInt();
1019
-
1020
- if (this.scale) {
1021
- ret = ret / ScaleDivisor[Math.abs(this.scale)];
1022
- }
1023
-
1024
- if (!lowerV13 || !data.readInt()) {
1025
- return ret;
1026
- }
1027
-
1028
- return null;
1029
- };
1030
-
1031
- SQLVarInt.prototype.calcBlr = function(blr) {
1032
- blr.addByte(blr_long);
1033
- blr.addShort(this.scale);
1034
- };
1035
-
1036
- //------------------------------------------------------
1037
-
1038
- function SQLVarShort() {}
1039
- SQLVarShort.prototype = new SQLVarInt();
1040
- SQLVarShort.prototype.constructor = SQLVarShort;
1041
-
1042
- SQLVarShort.prototype.calcBlr = function(blr) {
1043
- blr.addByte(blr_short);
1044
- blr.addShort(this.scale);
1045
- };
1046
-
1047
- //------------------------------------------------------
1048
-
1049
- function SQLVarInt64() {}
1050
-
1051
- SQLVarInt64.prototype.decode = function(data, lowerV13) {
1052
- var ret = data.readInt64();
1053
-
1054
- if (this.scale) {
1055
- ret = ret / ScaleDivisor[Math.abs(this.scale)];
1056
- }
1057
-
1058
- if (!lowerV13 || !data.readInt()) {
1059
- return ret;
1060
- }
1061
- return null;
1062
- };
1063
-
1064
- SQLVarInt64.prototype.calcBlr = function(blr) {
1065
- blr.addByte(blr_int64);
1066
- blr.addShort(this.scale);
1067
- };
1068
-
1069
- //------------------------------------------------------
1070
-
1071
- function SQLVarFloat() {}
1072
-
1073
- SQLVarFloat.prototype.decode = function(data, lowerV13) {
1074
- var ret = data.readFloat();
1075
-
1076
- if (!lowerV13 || !data.readInt()) {
1077
- return ret;
1078
- }
1079
-
1080
- return null;
1081
- };
1082
-
1083
- SQLVarFloat.prototype.calcBlr = function(blr) {
1084
- blr.addByte(blr_float);
1085
- };
1086
-
1087
- //------------------------------------------------------
1088
-
1089
- function SQLVarDouble() {}
1090
-
1091
- SQLVarDouble.prototype.decode = function(data, lowerV13) {
1092
- var ret = data.readDouble();
1093
-
1094
- if (!lowerV13 || !data.readInt()) {
1095
- return ret;
1096
- }
1097
-
1098
- return null;
1099
- };
1100
-
1101
- SQLVarDouble.prototype.calcBlr = function(blr) {
1102
- blr.addByte(blr_double);
1103
- };
1104
-
1105
- //------------------------------------------------------
1106
-
1107
- function SQLVarDate() {}
1108
-
1109
- SQLVarDate.prototype.decode = function(data, lowerV13) {
1110
- var ret = data.readInt();
1111
-
1112
- if (!lowerV13 || !data.readInt()) {
1113
- var d = new Date(0);
1114
- d.setMilliseconds((ret - DateOffset) * TimeCoeff + d.getTimezoneOffset() * MsPerMinute);
1115
- return d;
1116
- }
1117
-
1118
- return null;
1119
- };
1120
-
1121
- SQLVarDate.prototype.calcBlr = function(blr) {
1122
- blr.addByte(blr_sql_date);
1123
- };
1124
-
1125
- //------------------------------------------------------
1126
-
1127
- function SQLVarTime() {}
1128
-
1129
- SQLVarTime.prototype.decode = function(data, lowerV13) {
1130
- var ret = data.readUInt();
1131
-
1132
- if (!lowerV13 || !data.readInt()) {
1133
- var d = new Date(0);
1134
- d.setMilliseconds(Math.floor(ret / 10) + d.getTimezoneOffset() * MsPerMinute);
1135
- return d;
1136
- }
1137
- return null;
1138
- };
1139
-
1140
- SQLVarTime.prototype.calcBlr = function(blr) {
1141
- blr.addByte(blr_sql_time);
1142
- };
1143
-
1144
- //------------------------------------------------------
1145
-
1146
- function SQLVarTimeStamp() {}
1147
-
1148
- SQLVarTimeStamp.prototype.decode = function(data, lowerV13) {
1149
- var date = data.readInt();
1150
- var time = data.readUInt();
1151
-
1152
- if (!lowerV13 || !data.readInt()) {
1153
- var d = new Date(0);
1154
- d.setMilliseconds((date - DateOffset) * TimeCoeff + Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
1155
- return d;
1156
- }
1157
-
1158
- return null;
1159
- };
1160
-
1161
- SQLVarTimeStamp.prototype.calcBlr = function(blr) {
1162
- blr.addByte(blr_timestamp);
1163
- };
1164
-
1165
- //------------------------------------------------------
1166
-
1167
- function SQLVarBoolean() {}
1168
-
1169
- SQLVarBoolean.prototype.decode = function(data, lowerV13) {
1170
- var ret = data.readInt();
1171
-
1172
- if (!lowerV13 || !data.readInt()) {
1173
- return Boolean(ret);
1174
- }
1175
- return null;
1176
- };
1177
-
1178
- SQLVarBoolean.prototype.calcBlr = function(blr) {
1179
- blr.addByte(blr_bool);
1180
- };
1181
-
1182
- //------------------------------------------------------
1183
-
1184
- function SQLParamInt(value){
1185
- this.value = value;
1186
- }
1187
-
1188
- SQLParamInt.prototype.calcBlr = function(blr) {
1189
- blr.addByte(blr_long);
1190
- blr.addShort(0);
1191
- };
1192
-
1193
- SQLParamInt.prototype.encode = function(data) {
1194
- if (this.value != null) {
1195
- data.addInt(this.value);
1196
- } else {
1197
- data.addInt(0);
1198
- data.addInt(1);
1199
- }
1200
- };
1201
-
1202
- //------------------------------------------------------
1203
-
1204
- function SQLParamInt64(value){
1205
- this.value = value;
1206
- }
1207
-
1208
- SQLParamInt64.prototype.calcBlr = function(blr) {
1209
- blr.addByte(blr_int64);
1210
- blr.addShort(0);
1211
- };
1212
-
1213
- SQLParamInt64.prototype.encode = function(data) {
1214
- if (this.value != null) {
1215
- data.addInt64(this.value);
1216
- } else {
1217
- data.addInt64(0);
1218
- data.addInt(1);
1219
- }
1220
- };
1221
-
1222
- //------------------------------------------------------
1223
-
1224
- function SQLParamDouble(value) {
1225
- this.value = value;
1226
- }
1227
-
1228
- SQLParamDouble.prototype.encode = function(data) {
1229
- if (this.value != null) {
1230
- data.addDouble(this.value);
1231
- } else {
1232
- data.addDouble(0);
1233
- data.addInt(1);
1234
- }
1235
- };
1236
-
1237
- SQLParamDouble.prototype.calcBlr = function(blr) {
1238
- blr.addByte(blr_double);
1239
- };
1240
-
1241
- //------------------------------------------------------
1242
-
1243
- function SQLParamString(value) {
1244
- this.value = value;
1245
- }
1246
-
1247
- SQLParamString.prototype.encode = function(data) {
1248
- if (this.value != null) {
1249
- data.addText(this.value, DEFAULT_ENCODING);
1250
- } else {
1251
- data.addInt(1);
1252
- }
1253
- };
1254
-
1255
- SQLParamString.prototype.calcBlr = function(blr) {
1256
- blr.addByte(blr_text);
1257
- var len = this.value ? Buffer.byteLength(this.value, DEFAULT_ENCODING) : 0;
1258
- blr.addWord(len);
1259
- };
1260
-
1261
- //------------------------------------------------------
1262
-
1263
- function SQLParamQuad(value) {
1264
- this.value = value;
1265
- }
1266
-
1267
- SQLParamQuad.prototype.encode = function(data) {
1268
- if (this.value != null) {
1269
- data.addInt(this.value.high);
1270
- data.addInt(this.value.low);
1271
- } else {
1272
- data.addInt(0);
1273
- data.addInt(0);
1274
- data.addInt(1);
1275
- }
1276
- };
1277
-
1278
- SQLParamQuad.prototype.calcBlr = function(blr) {
1279
- blr.addByte(blr_quad);
1280
- blr.addShort(0);
1281
- };
1282
-
1283
- //------------------------------------------------------
1284
-
1285
- function SQLParamDate(value) {
1286
- this.value = value;
1287
- }
1288
-
1289
- SQLParamDate.prototype.encode = function(data) {
1290
- if (this.value != null) {
1291
-
1292
- var value = this.value.getTime() - this.value.getTimezoneOffset() * MsPerMinute;
1293
- var time = value % TimeCoeff;
1294
- var date = (value - time) / TimeCoeff + DateOffset;
1295
- time *= 10;
1296
-
1297
- // check overflow
1298
- if (time < 0) {
1299
- date--;
1300
- time = TimeCoeff*10 + time;
1301
- }
1302
-
1303
- data.addInt(date);
1304
- data.addUInt(time);
1305
- } else {
1306
- data.addInt(0);
1307
- data.addUInt(0);
1308
- data.addInt(1);
1309
- }
1310
- };
1311
-
1312
- SQLParamDate.prototype.calcBlr = function(blr) {
1313
- blr.addByte(blr_timestamp);
1314
- };
1315
-
1316
- //------------------------------------------------------
1317
-
1318
- function SQLParamBool(value) {
1319
- this.value = value;
1320
- }
1321
-
1322
- SQLParamBool.prototype.encode = function(data) {
1323
- if (this.value != null) {
1324
- data.addInt(this.value ? 1 : 0);
1325
- } else {
1326
- data.addInt(0);
1327
- data.addInt(1);
1328
- }
1329
- };
1330
-
1331
- SQLParamBool.prototype.calcBlr = function(blr) {
1332
- blr.addByte(blr_short);
1333
- blr.addShort(0);
1334
- };
1335
-
1336
-
1337
- /***************************************
1338
- *
1339
- * Error handling
1340
- *
1341
- ***************************************/
1342
-
1343
- function isError(obj) {
1344
- return Boolean(
1345
- obj != null && typeof obj === "object" && !Array.isArray(obj) && obj.status
1346
- );
1347
- }
1348
-
1349
- function doCallback(obj, callback) {
1350
-
1351
- if (!callback)
1352
- return;
1353
-
1354
- if (obj instanceof Error) {
1355
- callback(obj);
1356
- return;
1357
- }
1358
-
1359
- if (isError(obj)) {
1360
- var error = new Error(obj.message);
1361
- var status = obj.status && obj.status.length && obj.status[0] || {};
1362
- error.gdscode = status.gdscode; // main error gds code
1363
- error.gdsparams = status.params; // parameters (constraint name, table, etc.)
1364
- callback(error);
1365
- return;
1366
- }
1367
-
1368
- callback(undefined, obj);
1369
-
1370
- }
1371
-
1372
- function doError(obj, callback) {
1373
- if (callback)
1374
- callback(obj)
1375
- }
1376
-
1377
- /***************************************
1378
- *
1379
- * Statement
1380
- *
1381
- ***************************************/
1382
-
1383
- function Statement(connection) {
1384
- this.connection = connection;
1385
- }
1386
-
1387
- Statement.prototype.close = function(callback) {
1388
- this.connection.closeStatement(this, callback);
1389
- };
1390
-
1391
- Statement.prototype.drop = function(callback) {
1392
- this.connection.dropStatement(this, callback);
1393
- };
1394
-
1395
- Statement.prototype.release = function(callback) {
1396
- var cache_query = this.connection.getCachedQuery(this.query);
1397
- if (cache_query)
1398
- this.connection.closeStatement(this, callback);
1399
- else
1400
- this.connection.dropStatement(this, callback);
1401
- };
1402
-
1403
- Statement.prototype.execute = function(transaction, params, callback, custom) {
1404
-
1405
- if (params instanceof Function) {
1406
- custom = callback;
1407
- callback = params;
1408
- params = undefined;
1409
- }
1410
-
1411
- this.custom = custom;
1412
- this.connection.executeStatement(transaction, this, params, callback, custom);
1413
- };
1414
-
1415
- Statement.prototype.fetch = function(transaction, count, callback) {
1416
- this.connection.fetch(this, transaction, count, callback);
1417
- };
1418
-
1419
- Statement.prototype.fetchAll = function(transaction, callback) {
1420
- this.connection.fetchAll(this, transaction, callback);
1421
- };
1422
-
1423
- /***************************************
1424
- *
1425
- * Transaction
1426
- *
1427
- ***************************************/
1428
-
1429
- function Transaction(connection) {
1430
- this.connection = connection;
1431
- this.db = connection.db;
1432
- }
1433
-
1434
- Transaction.prototype.newStatement = function(query, callback) {
1435
- var cnx = this.connection;
1436
- var self = this;
1437
- var query_cache = cnx.getCachedQuery(query);
1438
-
1439
- if (query_cache) {
1440
- callback(null, query_cache);
1441
- } else {
1442
- cnx.prepare(self, query, false, callback);
1443
- }
1444
- };
1445
-
1446
- Transaction.prototype.execute = function(query, params, callback, custom) {
1447
-
1448
- if (params instanceof Function) {
1449
- custom = callback;
1450
- callback = params;
1451
- params = undefined;
1452
- }
1453
-
1454
- var self = this;
1455
- this.newStatement(query, function(err, statement) {
1456
- if (err) {
1457
- doError(err, callback);
1458
- return;
1459
- }
1460
-
1461
- function dropError(err) {
1462
- statement.release();
1463
- doCallback(err, callback);
1464
- }
1465
-
1466
- statement.execute(self, params, function(err, ret) {
1467
- if (err) {
1468
- dropError(err);
1469
- return;
1470
- }
1471
-
1472
- switch (statement.type) {
1473
- case isc_info_sql_stmt_select:
1474
- statement.fetchAll(self, function(err, r) {
1475
- if (err) {
1476
- dropError(err);
1477
- return;
1478
- }
1479
-
1480
- statement.release();
1481
-
1482
- if (callback)
1483
- callback(undefined, r, statement.output, true);
1484
-
1485
- });
1486
-
1487
- break;
1488
-
1489
- case isc_info_sql_stmt_exec_procedure:
1490
- if (ret && ret.data && ret.data.length > 0) {
1491
- statement.release();
1492
-
1493
- if (callback)
1494
- callback(undefined, ret.data[0], statement.output, true);
1495
-
1496
- break;
1497
- } else if (statement.output.length) {
1498
- statement.fetch(self, 1, function(err, ret) {
1499
- if (err) {
1500
- dropError(err);
1501
- return;
1502
- }
1503
-
1504
- statement.release();
1505
-
1506
- if (callback)
1507
- callback(undefined, ret.data[0], statement.output, false);
1508
- });
1509
-
1510
- break;
1511
- }
1512
-
1513
- // Fall through is normal
1514
- default:
1515
- statement.release();
1516
- if (callback)
1517
- callback()
1518
- break;
1519
- }
1520
-
1521
- }, custom);
1522
- });
1523
- };
1524
-
1525
- Transaction.prototype.sequentially = function (query, params, on, callback, asArray) {
1526
-
1527
- if (params instanceof Function) {
1528
- asArray = callback;
1529
- callback = on;
1530
- on = params;
1531
- params = undefined;
1532
- }
1533
-
1534
- if (on === undefined){
1535
- throw new Error('Expected "on" delegate.');
1536
- }
1537
-
1538
- if (callback instanceof Boolean) {
1539
- asArray = callback;
1540
- callback = undefined;
1541
- }
1542
-
1543
- var self = this;
1544
- self.execute(query, params, callback, { asObject: !asArray, asStream: true, on: on });
1545
- return self;
1546
- };
1547
-
1548
- Transaction.prototype.query = function(query, params, callback) {
1549
-
1550
- if (params instanceof Function) {
1551
- callback = params;
1552
- params = undefined;
1553
- }
1554
-
1555
- if (callback === undefined)
1556
- callback = noop;
1557
-
1558
- this.execute(query, params, callback, { asObject: true, asStream: callback === undefined || callback === null });
1559
-
1560
- };
1561
-
1562
- Transaction.prototype.commit = function(callback) {
1563
- this.connection.commit(this, callback);
1564
- };
1565
-
1566
- Transaction.prototype.rollback = function(callback) {
1567
- this.connection.rollback(this, callback);
1568
- };
1569
-
1570
- Transaction.prototype.commitRetaining = function(callback) {
1571
- this.connection.commitRetaining(this, callback);
1572
- };
1573
-
1574
- Transaction.prototype.rollbackRetaining = function(callback) {
1575
- this.connection.rollbackRetaining(this, callback);
1576
- };
1577
-
1578
- /***************************************
1579
- *
1580
- * Database
1581
- *
1582
- ***************************************/
1583
-
1584
- function Database(connection) {
1585
- this.connection = connection;
1586
- connection.db = this;
1587
- }
1588
-
1589
- Database.prototype.__proto__ = Object.create(Events.EventEmitter.prototype, {
1590
- constructor: {
1591
- value: Database,
1592
- enumberable: false
1593
- }
1594
- });
1595
-
1596
- Database.prototype.escape = function(value) {
1597
- return exports.escape(value, this.connection.accept.protocolVersion);
1598
- };
1599
-
1600
- Database.prototype.detach = function(callback, force) {
1601
-
1602
- var self = this;
1603
-
1604
- if (!force && self.connection._pending.length > 0) {
1605
- self.connection._detachAuto = true;
1606
- self.connection._detachCallback = callback;
1607
- return self;
1608
- }
1609
-
1610
- if (self.connection._pooled === false) {
1611
- self.connection.detach(function (err, obj) {
1612
-
1613
- self.connection.disconnect();
1614
- self.emit('detach', false);
1615
-
1616
- if (callback)
1617
- callback(err, obj);
1618
-
1619
- }, force);
1620
- } else {
1621
- self.emit('detach', false);
1622
- if (callback)
1623
- callback();
1624
- }
1625
-
1626
- return self;
1627
- };
1628
-
1629
- Database.prototype.transaction = function(isolation, callback) {
1630
- return this.startTransaction(isolation, callback);
1631
- };
1632
-
1633
- Database.prototype.startTransaction = function(isolation, callback) {
1634
- this.connection.startTransaction(isolation, callback);
1635
- return this;
1636
- };
1637
-
1638
- Database.prototype.newStatement = function (query, callback) {
1639
-
1640
- this.startTransaction(function(err, transaction) {
1641
-
1642
- if (err) {
1643
- callback(err);
1644
- return;
1645
- }
1646
-
1647
- transaction.newStatement(query, function(err, statement) {
1648
-
1649
- if (err) {
1650
- callback(err);
1651
- return;
1652
- }
1653
-
1654
- transaction.commit(function(err) {
1655
- callback(err, statement);
1656
- });
1657
- });
1658
- });
1659
-
1660
- return this;
1661
- };
1662
-
1663
- Database.prototype.execute = function(query, params, callback, custom) {
1664
-
1665
- if (params instanceof Function) {
1666
- custom = callback;
1667
- callback = params;
1668
- params = undefined;
1669
- }
1670
-
1671
- var self = this;
1672
-
1673
- self.connection.startTransaction(function(err, transaction) {
1674
-
1675
- if (err) {
1676
- doError(err, callback);
1677
- return;
1678
- }
1679
-
1680
- transaction.execute(query, params, function(err, result, meta, isSelect) {
1681
- if (err) {
1682
- transaction.rollback(function() {
1683
- doError(err, callback);
1684
- });
1685
- return;
1686
- }
1687
-
1688
- transaction.commit(function(err) {
1689
- if (callback)
1690
- callback(err, result, meta, isSelect);
1691
- });
1692
-
1693
- }, custom);
1694
- });
1695
-
1696
- return self;
1697
- };
1698
-
1699
- Database.prototype.sequentially = function(query, params, on, callback, asArray) {
1700
-
1701
- if (params instanceof Function) {
1702
- asArray = callback;
1703
- callback = on;
1704
- on = params;
1705
- params = undefined;
1706
- }
1707
-
1708
- if (on === undefined){
1709
- throw new Error('Expected "on" delegate.');
1710
- }
1711
-
1712
- if (callback instanceof Boolean) {
1713
- asArray = callback;
1714
- callback = undefined;
1715
- }
1716
-
1717
- var self = this;
1718
- self.execute(query, params, callback, { asObject: !asArray, asStream: true, on: on });
1719
- return self;
1720
- };
1721
-
1722
- Database.prototype.query = function(query, params, callback) {
1723
-
1724
- if (params instanceof Function) {
1725
- callback = params;
1726
- params = undefined;
1727
- }
1728
-
1729
- var self = this;
1730
- self.execute(query, params, callback, { asObject: true, asStream: callback === undefined || callback === null });
1731
- return self;
1732
- };
1733
-
1734
- Database.prototype.drop = function(callback) {
1735
- return this.connection.dropDatabase(callback);
1736
- };
1737
-
1738
- exports.attach = function(options, callback) {
1739
-
1740
- var host = options.host || DEFAULT_HOST;
1741
- var port = options.port || DEFAULT_PORT;
1742
- var manager = options.manager || false;
1743
- var cnx = this.connection = new Connection(host, port, function(err) {
1744
-
1745
- if (err) {
1746
- doError(err, callback);
1747
- return;
1748
- }
1749
-
1750
- cnx.connect(options, function(err) {
1751
- if (err) {
1752
- doError(err, callback);
1753
- } else {
1754
- if (manager)
1755
- cnx.svcattach(options, callback);
1756
- else
1757
- cnx.attach(options, callback);
1758
- }
1759
- });
1760
-
1761
- }, options);
1762
- };
1763
-
1764
- exports.drop = function(options, callback) {
1765
- exports.attach(options, function(err, db) {
1766
- if (err) {
1767
- callback({ error: err, message: "Drop error" });
1768
- return;
1769
- }
1770
-
1771
- db.drop(callback);
1772
- });
1773
- };
1774
-
1775
- exports.create = function(options, callback) {
1776
- var host = options.host || DEFAULT_HOST;
1777
- var port = options.port || DEFAULT_PORT;
1778
- var cnx = this.connection = new Connection(host, port, function(err) {
1779
-
1780
- var self = cnx;
1781
-
1782
- if (err) {
1783
- callback({ error: err, message: "Connect error" });
1784
- return;
1785
- }
1786
-
1787
- cnx.connect(options, function(err) {
1788
- if (err) {
1789
- self.db.emit('error', err);
1790
- doError(err, callback);
1791
- return;
1792
- }
1793
-
1794
- cnx.createDatabase(options, callback);
1795
- });
1796
- }, options);
1797
- };
1798
-
1799
- exports.attachOrCreate = function(options, callback) {
1800
-
1801
- var host = options.host || DEFAULT_HOST;
1802
- var port = options.port || DEFAULT_PORT;
1803
-
1804
- var cnx = this.connection = new Connection(host, port, function(err) {
1805
-
1806
- var self = cnx;
1807
-
1808
- if (err) {
1809
- callback({ error: err, message: "Connect error" });
1810
- return;
1811
- }
1812
-
1813
- cnx.connect(options, function(err) {
1814
-
1815
- if (err) {
1816
- doError(err, callback);
1817
- return;
1818
- }
1819
-
1820
- cnx.attach(options, function(err, ret) {
1821
-
1822
- if (!err) {
1823
- if (self.db)
1824
- self.db.emit('connect', ret);
1825
- doCallback(ret, callback);
1826
- return;
1827
- }
1828
-
1829
- cnx.createDatabase(options, callback);
1830
- });
1831
- });
1832
-
1833
- }, options);
1834
- };
1835
-
1836
- /***************************************
1837
- *
1838
- * Service Manager
1839
- *
1840
- ***************************************/
1841
-
1842
- function ServiceManager(connection) {
1843
- this.connection = connection;
1844
- connection.svc = this;
1845
- }
1846
-
1847
- ServiceManager.prototype.__proto__ = Object.create(Events.EventEmitter.prototype, {
1848
- constructor: {
1849
- value: ServiceManager,
1850
- enumberable: false
1851
- }
1852
- });
1853
-
1854
- ServiceManager.prototype._createOutputStream = function (optread, buffersize, callback) {
1855
- var self = this;
1856
- optread = optread || 'byline';
1857
- var t = new stream.Readable({ objectMode: optread === 'byline' }); // chunk by line
1858
- t.__proto__._read = function () {
1859
- var selfread = this;
1860
- var fct = optread === 'byline' ? self.readline : self.readeof;
1861
- fct.call(self, { buffersize: buffersize }, function (err, data) {
1862
- if (err) {
1863
- selfread.push(err.message, DEFAULT_ENCODING);
1864
- return;
1865
- }
1866
- if (data.line && data.line.length)
1867
- selfread.push(data.line, DEFAULT_ENCODING);
1868
- else
1869
- selfread.push(null);
1870
- });
1871
- }
1872
-
1873
- callback(null, t);
1874
- }
1875
-
1876
-
1877
- ServiceManager.prototype._infosmapping = {
1878
- "50"/*isc_info_svc_svr_db_info*/ : "dbinfo",
1879
- "51"/*isc_info_svc_get_license*/ : "licenses",
1880
- "52"/*isc_info_svc_get_license_mask*/ : "licenseoptions",
1881
- "53"/*isc_info_svc_get_config*/ : "fbconfig",
1882
- "54"/*isc_info_svc_version*/ : "svcversion",
1883
- "55"/*isc_info_svc_server_version*/ : "fbversion",
1884
- "56"/*isc_info_svc_implementation*/ : "fbimplementation",
1885
- "57"/*isc_info_svc_capabilities*/ : "fbcapatibilities",
1886
- "58"/*isc_info_svc_user_dbpath*/ : "pathsecuritydb",
1887
- "59"/*isc_info_svc_get_env*/ : "fbenv",
1888
- "60"/*isc_info_svc_get_env_lock*/ : "fbenvlock",
1889
- "61"/*isc_info_svc_get_env_msg*/ : "fbenvmsg",
1890
- "62"/*isc_info_svc_line*/ : "",
1891
- "63"/*isc_info_svc_to_eof*/ : "",
1892
- "64"/*isc_info_svc_timeout*/ : "",
1893
- "65"/*isc_info_svc_get_licensed_users*/ : "",
1894
- "66"/*isc_info_svc_limbo_trans*/ : "limbotrans",
1895
- "67"/*isc_info_svc_running*/ : "",
1896
- "68"/*isc_info_svc_get_users*/ : "fbusers",
1897
- "78"/*isc_info_svc_stdin*/ : ""
1898
- };
1899
-
1900
- ServiceManager.prototype._processcapabilities = function (blr, res) {
1901
- var capArray = [
1902
- "WAL_SUPPORT",
1903
- "MULTI_CLIENT_SUPPORT",
1904
- "REMOTE_HOP_SUPPORT",
1905
- "NO_SVR_STATS_SUPPORT",
1906
- "NO_DB_STATS_SUPPORT",
1907
- "LOCAL_ENGINE_SUPPORT",
1908
- "NO_FORCED_WRITE_SUPPORT",
1909
- "NO_SHUTDOWN_SUPPORT",
1910
- "NO_SERVER_SHUTDOWN_SUPPORT",
1911
- "SERVER_CONFIG_SUPPORT",
1912
- "QUOTED_FILENAME_SUPPORT"
1913
- ];
1914
- var dbcapa = res[this._infosmapping[57]] = [];
1915
- var caps = blr.readInt32();
1916
-
1917
- for (var i = 0; i < capArray.length; ++i)
1918
- if (caps & (1 << i))
1919
- dbcapa.push(capArray[i]);
1920
- }
1921
-
1922
- ServiceManager.prototype._processdbinfo = function (blr, res) {
1923
- var tinfo = blr.readByteCode();
1924
- var dbinfo = res[this._infosmapping[50]] = {};
1925
-
1926
- dbinfo.database = [];
1927
- for (; tinfo != isc_info_flag_end; tinfo = blr.readByteCode()) {
1928
- switch (tinfo) {
1929
- case isc_spb_dbname:
1930
- dbinfo.database.push(blr.readString());
1931
- break;
1932
- case isc_spb_num_att:
1933
- dbinfo.nbattachment = blr.readInt32();
1934
- break;
1935
- case isc_spb_num_db:
1936
- dbinfo.nbdatabase = blr.readInt32();
1937
- break;
1938
- }
1939
- }
1940
- }
1941
-
1942
- ServiceManager.prototype._processquery = function (buffer, callback) {
1943
- //console.log(buffer);
1944
- var br = new BlrReader(buffer);
1945
- var tinfo = br.readByteCode();
1946
- var res = {};
1947
- res.result = 0;
1948
- for (; tinfo !== isc_info_end; tinfo = br.readByteCode()) {
1949
- switch (tinfo) {
1950
- case isc_info_svc_server_version:
1951
- case isc_info_svc_implementation:
1952
- case isc_info_svc_user_dbpath:
1953
- case isc_info_svc_get_env:
1954
- case isc_info_svc_get_env_lock:
1955
- case isc_info_svc_get_env_msg:
1956
- res[this._infosmapping[tinfo]] = br.readString();
1957
- break;
1958
- case isc_info_svc_version:
1959
- res[this._infosmapping[tinfo]] = br.readInt32();
1960
- break;
1961
- case isc_info_svc_svr_db_info:
1962
- this._processdbinfo(br, res);
1963
- break;
1964
- case isc_info_svc_limbo_trans:
1965
- // not implemented
1966
- for (; tinfo !== isc_info_flag_end; tinfo = br.readByteCode())
1967
- break;
1968
- case isc_info_svc_get_users:
1969
- br.pos += 2
1970
- res[this._infosmapping[tinfo]] = [];
1971
- break;
1972
- case isc_spb_sec_username:
1973
- var tuser = res[this._infosmapping[68]];
1974
- tuser.push({});
1975
- tuser[tuser.length - 1].username = br.readString();
1976
- break;
1977
- case isc_spb_sec_firstname:
1978
- var tuser = res[this._infosmapping[68]];
1979
- var user = tuser[tuser.length-1];
1980
- user.firstname = br.readString();
1981
- break;
1982
- case isc_spb_sec_middlename:
1983
- var tuser = res[this._infosmapping[68]];
1984
- var user = tuser[tuser.length-1];
1985
- user.middlename = br.readString();
1986
- break;
1987
- case isc_spb_sec_lastname:
1988
- var tuser = res[this._infosmapping[68]];
1989
- var user = tuser[tuser.length-1];
1990
- user.lastname = br.readString();
1991
- break;
1992
- case isc_spb_sec_groupid:
1993
- var tuser = res[this._infosmapping[68]];
1994
- var user = tuser[tuser.length-1];
1995
- user.groupid = br.readInt32();
1996
- break;
1997
- case isc_spb_sec_userid:
1998
- var tuser = res[this._infosmapping[68]];
1999
- var user = tuser[tuser.length-1];
2000
- user.userid = br.readInt32();
2001
-
2002
- break;
2003
- case isc_spb_sec_admin:
2004
- var tuser = res[this._infosmapping[68]];
2005
- var user = tuser[tuser.length-1];
2006
- user.admin = br.readInt32();
2007
- break;
2008
-
2009
- case isc_info_svc_line:
2010
- res.line = br.readString();
2011
- break;
2012
-
2013
- case isc_info_svc_to_eof:
2014
- res.line = br.readString();
2015
- break;
2016
-
2017
- case isc_info_truncated:
2018
- res.result = 1; // too much data for the result buffer increase size of it (buffersize parameter))
2019
- break;
2020
-
2021
- case isc_info_data_not_ready:
2022
- res.result = 2;
2023
- break;
2024
-
2025
- case isc_info_svc_timeout:
2026
- res.result = 3;
2027
- break;
2028
-
2029
- case isc_info_svc_stdin:
2030
-
2031
- break;
2032
-
2033
- case isc_info_svc_capabilities:
2034
- this._processcapabilities(br, res);
2035
- break;
2036
- }
2037
- }
2038
- callback(null, res);
2039
- }
2040
-
2041
- ServiceManager.prototype.detach = function(callback, force) {
2042
- var self = this;
2043
-
2044
- if (!force && self.connection._pending.length > 0) {
2045
- self.connection._detachAuto = true;
2046
- self.connection._detachCallback = callback;
2047
- return self;
2048
- }
2049
-
2050
- self.connection.svcdetach(function (err, obj) {
2051
-
2052
- self.connection.disconnect();
2053
- self.emit('detach', false);
2054
-
2055
- if (callback)
2056
- callback(err, obj);
2057
-
2058
- }, force);
2059
-
2060
- return self;
2061
- }
2062
-
2063
- ServiceManager.prototype.backup = function (options, callback) {
2064
- var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
2065
- var verbose = options.verbose || false;
2066
- // format of bckfile {filename:'name', sizefile:''} sizefile is length of part in bytes
2067
- var bckfiles = options.backupfiles || options.files || null;
2068
- // for convenience
2069
- if (bckfiles) bckfiles = bckfiles.constructor !== Array?[{ filename: bckfiles, sizefile: '0' }]:bckfiles;
2070
- var factor = options.factor || 0; //If backing up to a physical tape device, this switch lets you specify the tape's blocking factor
2071
- var ignorechecksums = options.ignorechecksums || false;
2072
- var ignorelimbo = options.ignorelimbo || false;
2073
- var metadataonly = options.metadataonly || false;
2074
- var nogarbagecollect = options.nogarbasecollect || false;
2075
- var olddescriptions = options.olddescriptions || false;
2076
- var nontransportable = options.nontransportable || false;
2077
- var convert = options.convert || false;
2078
- var expand = options.expand || false;
2079
- var notriggers = options.notriggers || false;
2080
-
2081
- if (dbpath == null || dbpath.length === 0) {
2082
- doError(new Error('No database specified'), callback);
2083
- return;
2084
- }
2085
-
2086
- if (bckfiles == null || bckfiles.length === 0) {
2087
- doError(new Error('No backup path specified'), callback);
2088
- return;
2089
- }
2090
-
2091
- var blr = this.connection._blr;
2092
- blr.pos = 0;
2093
- blr.addByte(isc_action_svc_backup);
2094
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2095
- for (var i = 0; i < bckfiles.length; i++) {
2096
- blr.addString2(isc_spb_bkp_file, bckfiles[i].filename, DEFAULT_ENCODING);
2097
- if (i !== bckfiles.length - 1) // not the end, so we need to write the size of this part (gsplit)
2098
- blr.addString2(isc_spb_bkp_length, bckfiles[i].sizefile, DEFAULT_ENCODING);
2099
- }
2100
- if (factor)
2101
- blr.addByteInt32(isc_spb_bkp_factor, factor);
2102
-
2103
- var opts = 0;
2104
- if (ignorechecksums) opts = opts | isc_spb_bkp_ignore_checksums;
2105
- if (ignorelimbo) opts = opts | isc_spb_bkp_ignore_limbo;
2106
- if (metadataonly) opts = opts | isc_spb_bkp_metadata_only;
2107
- if (nogarbagecollect) opts = opts | isc_spb_bkp_no_garbage_collect;
2108
- if (olddescriptions) opts = opts | isc_spb_bkp_old_descriptions;
2109
- if (nontransportable) opts = opts | isc_spb_bkp_non_transportable;
2110
- if (convert) opts = opts | isc_spb_bkp_convert;
2111
- if (expand) opts = opts | isc_spb_bkp_expand;
2112
- if (notriggers) opts = opts | isc_spb_bkp_no_triggers;
2113
- if (opts)
2114
- blr.addByteInt32(isc_spb_options, opts);
2115
- if (verbose)
2116
- blr.addByte(isc_spb_verbose);
2117
- var self = this;
2118
- this.connection.svcstart(blr, function (err, data) {
2119
- if (err) {
2120
- doError(new Error(err), callback);
2121
- return;
2122
- }
2123
- self._createOutputStream(options.optread, options.buffersize, callback);
2124
- });
2125
- }
2126
-
2127
- ServiceManager.prototype.nbackup = function (options, callback) {
2128
- var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
2129
- var bckfile = options.backupfile || options.file || null;
2130
- var level = options.level || 0; // nb day for incremental
2131
- var notriggers = options.notriggers || false;
2132
- var direct = options.direct || 'on'; // on or off direct write I/O
2133
-
2134
- if (dbpath == null || dbpath.length === 0) {
2135
- doError(new Error('No database specified'), callback);
2136
- return;
2137
- }
2138
-
2139
- if (bckfile == null || bckfile.length === 0) {
2140
- doError(new Error('No backup path specified'), callback);
2141
- return;
2142
- }
2143
-
2144
- var blr = this.connection._blr;
2145
- blr.pos = 0;
2146
- blr.addByte(isc_action_svc_nbak);
2147
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2148
- blr.addString2(isc_spb_nbk_file, bckfile, DEFAULT_ENCODING);
2149
- blr.addByteInt32(isc_spb_nbk_level, level);
2150
- blr.addString2(isc_spb_nbk_direct, direct, DEFAULT_ENCODING);
2151
- var opts = 0;
2152
- if (notriggers) opts = opts | isc_spb_nbk_no_triggers;
2153
- blr.addByteInt32(isc_spb_options, opts);
2154
- var self = this;
2155
- this.connection.svcstart(blr, function (err, data) {
2156
- if (err) {
2157
- doError(new Error(err), callback);
2158
- return;
2159
- }
2160
- self._createOutputStream(options.optread, options.buffersize, callback);
2161
- });
2162
- }
2163
-
2164
- ServiceManager.prototype.restore = function(options, callback) {
2165
- var bckfiles = options.backupfiles || options.files || null; // format bckfiles ['file1', 'file2', 'file3']
2166
- // for convenience
2167
- if (bckfiles) bckfiles = bckfiles.constructor !== Array?[bckfiles]:bckfiles;
2168
- var dbfile = options.database || this.connection.options.filename || this.connection.options.database;;
2169
- var verbose = options.verbose || false;
2170
- var cachebuffers = options.cachebuffers || 2048; // gbak -buffers
2171
- var pagesize = options.pagesize || 4096; // gbak -page_size
2172
- var readonly = options.readonly || false; // gbak -mode
2173
- var deactivateindexes = options.deactivateindexes || false;
2174
- var noshadow = options.noshadow || false;
2175
- var novalidity = options.novalidity || false;
2176
- var individualcommit = options.individualcommit || true; // otherwise no data
2177
- var replace = options.replace || false;
2178
- var create = options.create || true;
2179
- var useallspace = options.useallspace || false;
2180
- var metadataonly = options.metadataonly || false;
2181
- var fixfssdata = options.fixfssdata || null;
2182
- var fixfssmetadata = options.fixfssmetadata || null;
2183
-
2184
- if (bckfiles == null || bckfiles.length === 0) {
2185
- doError(new Error('No backup file specified'), callback);
2186
- return;
2187
- }
2188
-
2189
- if (dbfile == null || dbfile.length === 0) {
2190
- doError(new Error('No database path specified'), callback);
2191
- return;
2192
- }
2193
-
2194
- var blr = this.connection._blr;
2195
- blr.pos = 0;
2196
- blr.addByte(isc_action_svc_restore);
2197
- for (var i = 0; i < bckfiles.length; i++) {
2198
- blr.addString2(isc_spb_bkp_file, bckfiles[i], DEFAULT_ENCODING);
2199
- }
2200
- blr.addString2(isc_spb_dbname, dbfile, DEFAULT_ENCODING);
2201
- blr.addByte(isc_spb_res_buffers);
2202
- blr.addInt32(cachebuffers);
2203
- blr.addByte(isc_spb_res_page_size);
2204
- blr.addInt32(pagesize);
2205
- blr.addByte(isc_spb_res_access_mode);
2206
- if (readonly)
2207
- blr.addByte(isc_spb_prp_am_readonly);
2208
- else
2209
- blr.addByte(isc_spb_prp_am_readwrite);
2210
- if (fixfssdata) blr.addString2(isc_spb_res_fix_fss_data, fixfssdata, DEFAULT_ENCODING);
2211
- if (fixfssmetadata) blr.addString2(isc_spb_res_fix_fss_metadata, fixfssmetadata, DEFAULT_ENCODING);
2212
- var opts = 0;
2213
- if (deactivateindexes) opts = opts | isc_spb_res_deactivate_idx;
2214
- if (noshadow) opts = opts | isc_spb_res_no_shadow;
2215
- if (novalidity) opts = opts | isc_spb_res_no_validity;
2216
- if (individualcommit) opts = opts | isc_spb_res_one_at_a_time;
2217
- if (replace) opts = opts | isc_spb_res_replace;
2218
- if (create) opts = opts | isc_spb_res_create;
2219
- if (useallspace) opts = opts | isc_spb_res_use_all_space;
2220
- if (metadataonly) opts = opts | isc_spb_res_fix_fss_metadata;
2221
- if (opts)
2222
- blr.addByteInt32(isc_spb_options, opts);
2223
- if (verbose)
2224
- blr.addByte(isc_spb_verbose);
2225
- var self = this;
2226
- this.connection.svcstart(blr, function (err, data) {
2227
- if (err) {
2228
- doError(new Error(err), callback);
2229
- return;
2230
- }
2231
- self._createOutputStream(options.optread, options.buffersize, callback);
2232
- });
2233
- }
2234
-
2235
- ServiceManager.prototype.nrestore = function (options, callback) {
2236
- var bckfiles = options.backupfiles || options.files || null; // format bckfiles ['file1', 'file2', 'file3']
2237
- // for convenience
2238
- if (bckfiles) bckfiles = bckfiles.constructor !== Array?[bckfiles]:bckfiles;
2239
- var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
2240
-
2241
- if (bckfiles == null || bckfiles.length === 0) {
2242
- doError(new Error('No backup file specified'), callback);
2243
- return;
2244
- }
2245
-
2246
- if (dbpath == null || bckfiles.length === 0) {
2247
- doError(new Error('No database path specified'), callback);
2248
- return;
2249
- }
2250
- var blr = this.connection._blr;
2251
- blr.pos = 0;
2252
- blr.addByte(isc_action_svc_nrest);
2253
- for (var i = 0; i < bckfiles.length; i++) {
2254
- blr.addString2(isc_spb_nbk_file, bckfiles[i], DEFAULT_ENCODING);
2255
- }
2256
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2257
- var self = this;
2258
- this.connection.svcstart(blr, function (err, data) {
2259
- if (err) {
2260
- doError(new Error(err), callback);
2261
- return;
2262
- }
2263
- self._createOutputStream(options.optread, options.buffersize, callback);
2264
- });
2265
- }
2266
-
2267
- // only one at time don't use this function directly
2268
- ServiceManager.prototype._fixpropertie = function (options, callback) {
2269
- var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
2270
- var dialect = options.dialect || null;
2271
- var sweep = options.sweepinterval || null;
2272
- var pagebuffers = options.nbpagebuffers || null;
2273
- var online = options.bringonline || false;
2274
- var shutdown = options.shutdown != null ? options.shutdown : null; // 0 Forced, 1 deny transaction, 2 deny attachment
2275
- var shutdowndelay = options.shutdowndelay || 0;
2276
- var shutdownmode = options.shutdownmode; // 0 normal 1 multi 2 single 3 full
2277
- var shadow = options.activateshadow || false;
2278
- var forcewrite = options.forcewrite;
2279
- var reservespace = options.reservespace;
2280
- var accessmode = options.accessmode; // 0 readonly 1 readwrite
2281
-
2282
- if (dbpath == null || dbpath.length === 0) {
2283
- doError(new Error('No database specified'), callback);
2284
- return;
2285
- }
2286
-
2287
- var blr = this.connection._blr;
2288
- blr.pos = 0;
2289
- blr.addByte(isc_action_svc_properties);
2290
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2291
- if (dialect) blr.addByteInt32(isc_spb_prp_set_sql_dialect, dialect);
2292
- if (sweep) blr.addByteInt32(isc_spb_prp_sweep_interval, sweep);
2293
- if (pagebuffers) blr.addByteInt32(isc_spb_prp_page_buffers, pagebuffers);
2294
- if (shutdown != null) {
2295
- if (shutdownmode != null) {
2296
- if (SHUTDOWNEX_KIND[shutdown] === undefined) {
2297
- doError(new Error('Invalid shutdown kind'), callback);
2298
- return;
2299
- }
2300
- if (SHUTDOWNEX_MODE[shutdownmode] === undefined) {
2301
- doError(new Error('Invalid shutdown mode'), callback);
2302
- return;
2303
- }
2304
-
2305
- // New shutdown with mode
2306
- blr.addBytes([isc_spb_prp_shutdown_mode, SHUTDOWNEX_MODE[shutdownmode]]);
2307
- blr.addByteInt32(SHUTDOWNEX_KIND[shutdown], shutdowndelay);
2308
- } else {
2309
- // Old shutdown
2310
- blr.addByteInt32(SHUTDOWN_KIND[shutdown], shutdowndelay);
2311
- }
2312
- }
2313
- if (forcewrite) blr.addBytes([isc_spb_prp_write_mode, isc_spb_prp_wm_sync]);
2314
- if (forcewrite === false) blr.addBytes([isc_spb_prp_write_mode, isc_spb_prp_wm_async]);
2315
- if (accessmode === 1) blr.addBytes([isc_spb_prp_access_mode, isc_spb_prp_am_readwrite]);
2316
- if (accessmode === 0) blr.addBytes([isc_spb_prp_access_mode, isc_spb_prp_am_readonly]);
2317
- if (reservespace) blr.addBytes([isc_spb_prp_reserve_space, isc_spb_prp_res]);
2318
- if (reservespace != null && !reservespace) blr.addBytes([isc_spb_prp_reserve_space, isc_spb_prp_res_use_full]);
2319
- var opts = 0;
2320
- if (shadow) opts = opts | isc_spb_prp_activate;
2321
- if (online) opts = opts | isc_spb_prp_db_online;
2322
- if (opts)
2323
- blr.addByteInt32(isc_spb_options, opts);
2324
- var self = this;
2325
- this.connection.svcstart(blr, function (err, data) {
2326
- if (err) {
2327
- doError(new Error(err), callback);
2328
- return;
2329
- }
2330
- self._createOutputStream(options.optread, options.buffersize, callback);
2331
- });
2332
- }
2333
-
2334
- ServiceManager.prototype.setDialect = function (db, dialect, callback) {
2335
- this._fixpropertie({ database: db, dialect: dialect }, callback);
2336
- }
2337
-
2338
- ServiceManager.prototype.setSweepinterval = function (db, sweepinterval, callback) {
2339
- this._fixpropertie({ database: db, sweepinterval: sweepinterval }, callback);
2340
- }
2341
-
2342
- ServiceManager.prototype.setCachebuffer = function (db, nbpages, callback) {
2343
- this._fixpropertie({ database: db, nbpagebuffers: nbpages }, callback);
2344
- }
2345
-
2346
- ServiceManager.prototype.BringOnline = function (db, callback) {
2347
- this._fixpropertie({ database: db, bringonline: true }, callback);
2348
- }
2349
-
2350
- const SHUTDOWN_KIND = {
2351
- 0: isc_spb_prp_shutdown_db,
2352
- 1: isc_spb_prp_deny_new_transactions,
2353
- 2: isc_spb_prp_deny_new_attachments
2354
- };
2355
- const SHUTDOWNEX_KIND = {
2356
- 0: isc_spb_prp_force_shutdown,
2357
- 1: isc_spb_prp_transactions_shutdown,
2358
- 2: isc_spb_prp_attachments_shutdown
2359
- };
2360
- const SHUTDOWNEX_MODE = {
2361
- //0: isc_spb_prp_sm_normal,
2362
- 1: isc_spb_prp_sm_multi,
2363
- 2: isc_spb_prp_sm_single,
2364
- 3: isc_spb_prp_sm_full
2365
- };
2366
- const ShutdownMode = { NORMAL: 0, MULTI: 1, SINGLE: 2, FULL: 3 };
2367
- const ShutdownKind = { FORCED: 0, DENY_TRANSACTION: 1, DENY_ATTACHMENT: 2 };
2368
- exports.ShutdownMode = ShutdownMode;
2369
- exports.ShutdownKind = ShutdownKind;
2370
-
2371
- ServiceManager.prototype.Shutdown = function (db, kind, delay, mode, callback) {
2372
- // mode parameter is for server version >= 2.0
2373
- if (mode instanceof Function) {
2374
- callback = mode;
2375
- mode = undefined;
2376
- }
2377
-
2378
- this._fixpropertie({ database: db, shutdown: kind, shutdowndelay: delay, shutdownmode: mode }, callback);
2379
- }
2380
-
2381
- ServiceManager.prototype.setShadow = function (db, val, callback) {
2382
- this._fixpropertie({ database: db, activateshadow : val }, callback);
2383
- }
2384
-
2385
- ServiceManager.prototype.setForcewrite = function (db, val, callback) {
2386
- this._fixpropertie({ database: db, forcewrite : val }, callback);
2387
- }
2388
-
2389
- ServiceManager.prototype.setReservespace = function (db, val, callback) {
2390
- this._fixpropertie({ database: db, reservespace : val }, callback);
2391
- }
2392
-
2393
- ServiceManager.prototype.setReadonlyMode = function (db, callback) {
2394
- this._fixpropertie({ database: db, accessmode : 0 }, callback);
2395
- }
2396
-
2397
- ServiceManager.prototype.setReadwriteMode = function (db, callback) {
2398
- this._fixpropertie({ database: db, accessmode : 1 }, callback);
2399
- }
2400
-
2401
- ServiceManager.prototype.validate = function (options, callback) {
2402
- var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
2403
- var checkdb = options.checkdb || false;
2404
- var ignorechecksums = options.ignorechecksums || false;
2405
- var killshadows = options.killshadows || false;
2406
- var mend = options.mend || false;
2407
- var validate = options.validate || false;
2408
- var full = options.full || false;
2409
- var sweep = options.sweep || false;
2410
- var listlimbo = options.listlimbo || false;
2411
- var icu = options.icu || false;
2412
-
2413
- if (dbpath == null || dbpath.length === 0) {
2414
- doError(new Error('No database specified'), callback);
2415
- return;
2416
- }
2417
-
2418
- var blr = this.connection._blr;
2419
- blr.pos = 0;
2420
- blr.addByte(isc_action_svc_repair);
2421
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2422
- var opts = 0;
2423
- if (checkdb) opts = opts | isc_spb_rpr_check_db;
2424
- if (ignorechecksums) opts = opts | isc_spb_rpr_ignore_checksum;
2425
- if (killshadows) opts = opts | isc_spb_rpr_kill_shadows;
2426
- if (mend) opts = opts | isc_spb_rpr_mend_db;
2427
- if (validate) opts = opts | isc_spb_rpr_validate_db;
2428
- if (full) opts = opts | isc_spb_rpr_full;
2429
- if (sweep) opts = opts | isc_spb_rpr_sweep_db;
2430
- if (listlimbo) opts = opts | isc_spb_rpr_list_limbo_trans;
2431
- if (icu) opts = opts | isc_spb_rpr_icu;
2432
- blr.addByteInt32(isc_spb_options, opts);
2433
- var self = this;
2434
- this.connection.svcstart(blr, function (err, data) {
2435
- if (err) {
2436
- doError(new Error(err), callback);
2437
- return;
2438
- }
2439
- self._createOutputStream(options.optread, options.buffersize, callback);
2440
- });
2441
- }
2442
-
2443
- ServiceManager.prototype.commit = function(db, transactid, callback) {
2444
- var dbpath = db || this.connection.options.filename || this.connection.options.database;
2445
- if (dbpath == null || dbpath.length === 0) {
2446
- doError(new Error('No database specified'), callback);
2447
- return;
2448
- }
2449
-
2450
- var blr = this.connection._blr;
2451
- blr.pos = 0;
2452
- blr.addByte(isc_action_svc_repair);
2453
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2454
- blr.addByteInt32(isc_spb_rpr_commit_trans, transactid);
2455
- var self = this;
2456
- this.connection.svcstart(blr, function (err, data) {
2457
- if (err) {
2458
- doError(new Error(err), callback);
2459
- return;
2460
- }
2461
- self._createOutputStream(null, null, callback);
2462
- });
2463
- }
2464
-
2465
- ServiceManager.prototype.rollback = function (db, transactid, callback) {
2466
- var dbpath = db || this.connection.options.filename || this.connection.options.database;
2467
- if (dbpath == null || dbpath.length === 0) {
2468
- doError(new Error('No database specified'), callback);
2469
- return;
2470
- }
2471
-
2472
- var blr = this.connection._blr;
2473
- blr.pos = 0;
2474
- blr.addByte(isc_action_svc_repair);
2475
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2476
- blr.addByteInt32(isc_spb_rpr_rollback_trans, transactid);
2477
- this.connection.svcstart(blr, function (err, data) {
2478
- if (err) {
2479
- doError(new Error(err), callback);
2480
- return;
2481
- }
2482
- self._createOutputStream(null, null, callback);
2483
- });
2484
- }
2485
-
2486
- ServiceManager.prototype.recover = function (db, transactid, callback) {
2487
- var dbpath = db || this.connection.options.filename || this.connection.options.database;
2488
- if (dbpath == null || dbpath.length === 0) {
2489
- doError(new Error('No database specified'), callback);
2490
- return;
2491
- }
2492
-
2493
- var blr = this.connection._blr;
2494
- blr.pos = 0;
2495
- blr.addByte(isc_action_svc_repair);
2496
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2497
- blr.addByteInt32(isc_spb_rpr_recover_two_phase, transactid);
2498
- this.connection.svcstart(blr, function (err, data) {
2499
- if (err) {
2500
- doError(new Error(err), callback);
2501
- return;
2502
- }
2503
- self._createOutputStream(null, null, callback);
2504
- });
2505
- }
2506
-
2507
- ServiceManager.prototype.getStats = function (options, callback) {
2508
- var dbpath = options.database || this.connection.options.filename || this.connection.options.database;
2509
- var record = options.record || false;
2510
- var nocreation = options.nocreation || false;
2511
- var tables = options.tables || false;
2512
- var pages = options.pages || false;
2513
- var header = options.header || false;
2514
- var indexes = options.indexes || false;
2515
- var tablesystem = options.tablesystem || false;
2516
- var encryption = options.encryption || false;
2517
- var objects = options.objects || null; // space-separated list of object index,table,systemtable
2518
- if (dbpath == null || dbpath.length === 0) {
2519
- doError(new Error('No database specified'), callback);
2520
- return;
2521
- }
2522
-
2523
- var blr = this.connection._blr;
2524
- blr.pos = 0;
2525
- blr.addByte(isc_action_svc_db_stats);
2526
- blr.addString2(isc_spb_dbname, dbpath, DEFAULT_ENCODING);
2527
- var opts = 0;
2528
- if (record) opts = opts | isc_spb_sts_record_versions;
2529
- if (nocreation) opts = opts | isc_spb_sts_nocreation;
2530
- if (tables) opts = opts | isc_spb_sts_table;
2531
- if (pages) opts = opts | isc_spb_sts_data_pages;
2532
- if (header) opts = opts | isc_spb_sts_hdr_pages;
2533
- if (indexes) opts = opts | isc_spb_sts_idx_pages;
2534
- if (tablesystem) opts = opts | isc_spb_sts_sys_relations;
2535
- if (encryption) opts = opts | isc_spb_sts_encryption;
2536
- if (opts)
2537
- blr.addByteInt32(isc_spb_options, opts);
2538
- if (objects) blr.addString2(isc_spb_command_line, objects, DEFAULT_ENCODING);
2539
- var self = this;
2540
- this.connection.svcstart(blr, function (err, data) {
2541
- if (err) {
2542
- doError(new Error(err), callback);
2543
- return;
2544
- }
2545
- self._createOutputStream(options.optread, options.buffersize, callback);
2546
- });
2547
-
2548
- }
2549
-
2550
- ServiceManager.prototype.getLog = function (options, callback) {
2551
- var self = this;
2552
- var blr = this.connection._blr;
2553
- var optread = options.optread || 'byline';
2554
- blr.pos = 0;
2555
- blr.addByte(isc_action_svc_get_fb_log);
2556
- this.connection.svcstart(blr, function (err, data) {
2557
- if (err) {
2558
- doError(new Error(err), callback);
2559
- return;
2560
- }
2561
- self._createOutputStream(optread, options.buffersize, callback);
2562
- });
2563
- }
2564
-
2565
- ServiceManager.prototype.getUsers = function (username, callback) {
2566
- var self = this;
2567
- var blr = this.connection._blr;
2568
- blr.pos = 0;
2569
- blr.addByte(isc_action_svc_display_user);
2570
- if (username) blr.addString2(isc_spb_sec_username, username, DEFAULT_ENCODING);
2571
- this.connection.svcstart(blr, function (err, data) {
2572
- if (err) {
2573
- doError(new Error(err), callback);
2574
- return;
2575
- }
2576
- self.readusers({}, callback);
2577
- });
2578
- }
2579
-
2580
- ServiceManager.prototype.addUser = function (username, password, options, callback) {
2581
- var rolename = options.rolename || null;
2582
- var groupname = options.groupname || null;
2583
- var firsname = options.firstname || null;
2584
- var middlename = options.middlename || null;
2585
- var lastname = options.lastname || null;
2586
- var userid = options.userid || null;
2587
- var groupid = options.groupid || null;
2588
- var admin = options.admin || null;
2589
-
2590
- var blr = this.connection._blr;
2591
- blr.pos = 0;
2592
- blr.addByte(isc_action_svc_add_user);
2593
- blr.addString2(isc_spb_sec_username, username, DEFAULT_ENCODING);
2594
- blr.addString2(isc_spb_sec_password, password, DEFAULT_ENCODING);
2595
- if (rolename) blr.addString2(isc_dpb_sql_role_name, rolename, DEFAULT_ENCODING);
2596
- if (groupname) blr.addString2(isc_spb_sec_groupname, groupname, DEFAULT_ENCODING);
2597
- if (firsname) blr.addString2(isc_spb_sec_firstname, firsname, DEFAULT_ENCODING);
2598
- if (middlename) blr.addString2(isc_spb_sec_middlename, middlename, DEFAULT_ENCODING);
2599
- if (lastname) blr.addString2(isc_spb_sec_lastname, lastname, DEFAULT_ENCODING);
2600
- if (userid != null) blr.addByteInt32(isc_spb_sec_userid, userid);
2601
- if (groupid != null) blr.addByteInt32(isc_spb_sec_groupid, groupid);
2602
- if (admin != null) blr.addByteInt32(isc_spb_sec_admin, admin);
2603
-
2604
- var self = this;
2605
- this.connection.svcstart(blr, function (err, data) {
2606
- if (err) {
2607
- doError(new Error(err), callback);
2608
- return;
2609
- }
2610
- self._createOutputStream(options.optread, options.buffersize, callback);
2611
- });
2612
- }
2613
-
2614
- ServiceManager.prototype.editUser = function (username, options, callback) {
2615
- var rolename = options.rolename || null;
2616
- var groupname = options.groupname || null;
2617
- var firsname = options.firstname || null;
2618
- var middlename = options.middlename || null;
2619
- var lastname = options.lastname || null;
2620
- var userid = options.userid || null;
2621
- var groupid = options.groupid || null;
2622
- var admin = options.admin || null;
2623
- var password = options.password || null;
2624
- var blr = this.connection._blr;
2625
- blr.pos = 0;
2626
- blr.addByte(isc_action_svc_modify_user);
2627
- blr.addString2(isc_spb_sec_username, username, DEFAULT_ENCODING);
2628
- if (password) blr.addString2(isc_spb_sec_password, password, DEFAULT_ENCODING);
2629
- if (rolename) blr.addString2(isc_dpb_sql_role_name, rolename, DEFAULT_ENCODING);
2630
- if (groupname) blr.addString2(isc_spb_sec_groupname, groupname, DEFAULT_ENCODING);
2631
- if (firsname) blr.addString2(isc_spb_sec_firstname, firsname, DEFAULT_ENCODING);
2632
- if (middlename) blr.addString2(isc_spb_sec_middlename, middlename, DEFAULT_ENCODING);
2633
- if (lastname) blr.addString2(isc_spb_sec_lastname, lastname, DEFAULT_ENCODING);
2634
- if (userid != null) blr.addByteInt32(isc_spb_sec_userid, userid);
2635
- if (groupid != null) blr.addByteInt32(isc_spb_sec_groupid, groupid);
2636
- if (admin != null) blr.addByteInt32(isc_spb_sec_admin, admin);
2637
-
2638
- var self = this;
2639
- this.connection.svcstart(blr, function (err, data) {
2640
- if (err) {
2641
- doError(new Error(err), callback);
2642
- return;
2643
- }
2644
- self._createOutputStream(options.optread, options.buffersize, callback);
2645
- });
2646
- }
2647
-
2648
- ServiceManager.prototype.removeUser = function (username, rolename, callback) {
2649
- var blr = this.connection._blr;
2650
- blr.pos = 0;
2651
- blr.addByte(isc_action_svc_delete_user);
2652
- blr.addString2(isc_spb_sec_username, username, DEFAULT_ENCODING);
2653
- if (rolename) blr.addString2(isc_dpb_sql_role_name, rolename, DEFAULT_ENCODING);
2654
-
2655
- var self = this, options = {};
2656
- this.connection.svcstart(blr, function (err, data) {
2657
- if (err) {
2658
- doError(new Error(err), callback);
2659
- return;
2660
- }
2661
- self._createOutputStream(options.optread, options.buffersize, callback);
2662
- });
2663
- }
2664
-
2665
- ServiceManager.prototype.getFbserverInfos = function (infos, options, callback) {
2666
- var buffersize = options.buffersize || 2048;
2667
- var timeout = options.timeout || 1;
2668
- var opts = {
2669
- "dbinfo" : isc_info_svc_svr_db_info,
2670
- "fbconfig" : isc_info_svc_get_config,
2671
- "svcversion" : isc_info_svc_version,
2672
- "fbversion" : isc_info_svc_server_version,
2673
- "fbimplementation" : isc_info_svc_implementation,
2674
- "fbcapatibilities" : isc_info_svc_capabilities,
2675
- "pathsecuritydb" : isc_info_svc_user_dbpath,
2676
- "fbenv" : isc_info_svc_get_env,
2677
- "fbenvlock" : isc_info_svc_get_env_lock,
2678
- "fbenvmsg" : isc_info_svc_get_env_msg
2679
- };
2680
- // if infos is empty all options are asked to the service
2681
-
2682
- var tops = [], empty = isEmpty(infos);
2683
- for (let popts in opts)
2684
- if (empty || infos[popts])
2685
- tops.push(opts[popts]);
2686
-
2687
- var self = this;
2688
- this.connection.svcquery(tops, buffersize, timeout, function (err, data) {
2689
- if (err || !data.buffer) {
2690
- doError(new Error(err||'Bad query return'), callback);
2691
- return;
2692
- }
2693
- self._processquery(data.buffer, callback);
2694
- });
2695
- }
2696
-
2697
- function isEmpty(obj){
2698
- for(var p in obj) return false;
2699
- return true;
2700
- }
2701
-
2702
- ServiceManager.prototype.startTrace = function (options, callback) {
2703
- var self = this;
2704
- var blr = this.connection._blr;
2705
- var configfile = options.configfile || '';
2706
- var tracename = options.tracename || '';
2707
-
2708
- if (configfile.length === 0) {
2709
- doError(new Error('No config filename specified'), callback);
2710
- return;
2711
- }
2712
- if (tracename.length === 0) {
2713
- doError(new Error('No tracename specified'), callback);
2714
- return;
2715
- }
2716
-
2717
- blr.pos = 0;
2718
- blr.addByte(isc_action_svc_trace_start);
2719
- blr.addString2(isc_spb_trc_cfg, configfile, DEFAULT_ENCODING);
2720
- blr.addString2(isc_spb_trc_name, tracename, DEFAULT_ENCODING);
2721
- this.connection.svcstart(blr, function (err, data) {
2722
- if (err) {
2723
- doError(new Error(err), callback);
2724
- return;
2725
- }
2726
- self._createOutputStream(options.optread, options.buffersize, callback);
2727
- });
2728
- }
2729
-
2730
- ServiceManager.prototype.suspendTrace = function (options, callback) {
2731
- var self = this;
2732
- var blr = this.connection._blr;
2733
- var traceid = options.traceid || null;
2734
-
2735
- if (traceid == null) {
2736
- doError(new Error('No traceid specified'), callback);
2737
- return;
2738
- }
2739
-
2740
- blr.pos = 0;
2741
- blr.addByte(isc_action_svc_trace_suspend);
2742
- blr.addByteInt32(isc_spb_trc_id, traceid);
2743
- this.connection.svcstart(blr, function (err, data) {
2744
- if (err) {
2745
- doError(new Error(err), callback);
2746
- return;
2747
- }
2748
- self._createOutputStream(options.optread, options.buffersize, callback);
2749
- });
2750
- }
2751
-
2752
- ServiceManager.prototype.resumeTrace = function (options, callback) {
2753
- var self = this;
2754
- var blr = this.connection._blr;
2755
- var traceid = options.traceid || null;
2756
-
2757
- if (traceid == null) {
2758
- doError(new Error('No traceid specified'), callback);
2759
- return;
2760
- }
2761
-
2762
- blr.pos = 0;
2763
- blr.addByte(isc_action_svc_trace_resume);
2764
- blr.addByteInt32(isc_spb_trc_id, traceid);
2765
- this.connection.svcstart(blr, function (err, data) {
2766
- if (err) {
2767
- doError(new Error(err), callback);
2768
- return;
2769
- }
2770
- self._createOutputStream(options.optread, options.buffersize, callback);
2771
- });
2772
- }
2773
-
2774
- ServiceManager.prototype.stopTrace = function (options, callback) {
2775
- var self = this;
2776
- var blr = this.connection._blr;
2777
- var traceid = options.traceid || null;
2778
-
2779
- if (traceid == null) {
2780
- doError(new Error('No traceid specified'), callback);
2781
- return;
2782
- }
2783
-
2784
- blr.pos = 0;
2785
- blr.addByte(isc_action_svc_trace_stop);
2786
- blr.addByteInt32(isc_spb_trc_id, traceid);
2787
- this.connection.svcstart(blr, function (err, data) {
2788
- if (err) {
2789
- doError(new Error(err), callback);
2790
- return;
2791
- }
2792
- self._createOutputStream(options.optread, options.buffersize, callback);
2793
- });
2794
- }
2795
-
2796
- ServiceManager.prototype.getTraceList = function (options, callback) {
2797
- var self = this;
2798
- var blr = this.connection._blr;
2799
- blr.pos = 0;
2800
- blr.addByte(isc_action_svc_trace_list);
2801
- this.connection.svcstart(blr, function (err, data) {
2802
- if (err) {
2803
- doError(new Error(err), callback);
2804
- return;
2805
- }
2806
- self._createOutputStream(options.optread, options.buffersize, callback);
2807
- });
2808
- }
2809
-
2810
- ServiceManager.prototype.readline = function (options, callback) {
2811
- var buffersize = options.buffersize || 2048;
2812
- var timeout = options.timeout || 60;
2813
- var self = this;
2814
- this.connection.svcquery([isc_info_svc_line], buffersize, timeout, function (err, data) {
2815
- if (err || !data.buffer) {
2816
- doError(new Error(err||'Bad query return'), callback);
2817
- return;
2818
- }
2819
- self._processquery(data.buffer, callback);
2820
- });
2821
- }
2822
-
2823
- ServiceManager.prototype.readeof = function (options, callback) {
2824
- var buffersize = options.buffersize || (8 * 1024);
2825
- var timeout = options.timeout || 60;
2826
- var self = this;
2827
- this.connection.svcquery([isc_info_svc_to_eof], buffersize, timeout, function (err, data) {
2828
- if (err || !data.buffer) {
2829
- doError(new Error(err||'Bad query return'), callback);
2830
- return;
2831
- }
2832
- self._processquery(data.buffer, callback);
2833
- });
2834
- }
2835
-
2836
- ServiceManager.prototype.hasRunningAction = function (options, callback) {
2837
- var buffersize = options.buffersize || 2048;
2838
- var timeout = options.timeout || 60;
2839
- var self = this;
2840
- this.connection.svcquery([isc_info_svc_running], buffersize, timeout, function (err, data) {
2841
- if (err || !data.buffer) {
2842
- doError(new Error(err||'Bad query return'), callback);
2843
- return;
2844
- }
2845
- self._processquery(data.buffer, callback);
2846
- });
2847
- }
2848
-
2849
- ServiceManager.prototype.readusers = function (options, callback) {
2850
- var buffersize = options.buffersize || 2048;
2851
- var timeout = options.timeout || 60;
2852
- var self = this;
2853
- this.connection.svcquery([isc_info_svc_get_users], buffersize, timeout, function (err, data) {
2854
- if (err || !data.buffer) {
2855
- doError(new Error(err||'Bad query return'), callback);
2856
- return;
2857
- }
2858
- self._processquery(data.buffer, callback);
2859
- });
2860
- }
2861
-
2862
- ServiceManager.prototype.readlimbo = function (options, callback) {
2863
- var buffersize = options.buffersize || 2048;
2864
- var timeout = options.timeout || 60;
2865
- var self = this;
2866
- this.connection.svcquery([isc_info_svc_limbo_trans], buffersize, timeout, function (err, data) {
2867
- if (err || !data.buffer) {
2868
- doError(new Error(err||'Bad query return'), callback);
2869
- return;
2870
- }
2871
- self._processquery(data.buffer, callback);
2872
- });
2873
- }
2874
-
2875
- // Pooling
2876
- exports.pool = function(max, options) {
2877
- return new Pool(max, Object.assign({}, options, { isPool: true }));
2878
- };
2879
-
2880
- /***************************************
2881
- *
2882
- * Simple Pooling
2883
- *
2884
- ***************************************/
2885
-
2886
- function Pool(max, options) {
2887
- this.internaldb = []; // connection created by the pool (for destroy)
2888
- this.pooldb = []; // available connection in the pool
2889
- this.dbinuse = 0; // connection currently in use into the pool
2890
- this.max = max || 4;
2891
- this.pending = [];
2892
- this.options = options;
2893
- }
2894
-
2895
- Pool.prototype.get = function(callback) {
2896
- var self = this;
2897
- self.pending.push(callback);
2898
- self.check();
2899
- return self;
2900
- };
2901
-
2902
- Pool.prototype.check = function() {
2903
-
2904
- var self = this;
2905
- if (self.dbinuse >= self.max)
2906
- return self;
2907
-
2908
- var cb = self.pending.shift();
2909
- if (!cb)
2910
- return self;
2911
- self.dbinuse++;
2912
- if (self.pooldb.length) {
2913
- cb(null, self.pooldb.shift());
2914
- } else {
2915
- exports.attach(self.options, function (err, db) {
2916
- if (!err) {
2917
- self.internaldb.push(db);
2918
- db.on('detach', function () {
2919
- // also in pool (could be a twice call to detach)
2920
- if (self.pooldb.indexOf(db) !== -1 || self.internaldb.indexOf(db) === -1)
2921
- return;
2922
- // if not usable don't put in again in the pool and remove reference on it
2923
- if (db.connection._isClosed || db.connection._isDetach || db.connection._pooled === false)
2924
- self.internaldb.splice(self.internaldb.indexOf(db), 1);
2925
- else
2926
- self.pooldb.push(db);
2927
-
2928
- if (db.connection._pooled)
2929
- self.dbinuse--;
2930
- self.check();
2931
- });
2932
- } else {
2933
- // attach fail so not in the pool
2934
- self.dbinuse--;
2935
- }
2936
-
2937
- cb(err, db);
2938
- });
2939
- }
2940
- setImmediate(function() {
2941
- self.check();
2942
- });
2943
-
2944
- return self;
2945
- };
2946
-
2947
- Pool.prototype.destroy = function(callback) {
2948
- var self = this;
2949
-
2950
- var connectionCount = this.internaldb.length;
2951
-
2952
- if (connectionCount === 0 && callback) {
2953
- callback();
2954
- }
2955
-
2956
- function detachCallback(err) {
2957
- if (err) {
2958
- if (callback) {
2959
- callback(err);
2960
- }
2961
- return;
2962
- }
2963
-
2964
- connectionCount--;
2965
- if (connectionCount === 0 && callback) {
2966
- callback();
2967
- }
2968
- }
2969
-
2970
- this.internaldb.forEach(function(db) {
2971
- if (db.connection._pooled === false) {
2972
- detachCallback();
2973
- return;
2974
- }
2975
- // check if the db is not free into the pool otherwise user should manual detach it
2976
- var _db_in_pool = self.pooldb.indexOf(db);
2977
- if (_db_in_pool !== -1) {
2978
- self.pooldb.splice(_db_in_pool, 1);
2979
- db.connection._pooled = false;
2980
- db.detach(detachCallback);
2981
- }
2982
- });
2983
- };
2984
-
2985
- /***************************************
2986
- *
2987
- * Connection
2988
- *
2989
- ***************************************/
2990
-
2991
- var Connection = exports.Connection = function (host, port, callback, options, db, svc) {
2992
- var self = this;
2993
- this.db = db;
2994
- this.svc = svc
2995
- this._msg = new XdrWriter(32);
2996
- this._blr = new BlrWriter(32);
2997
- this._queue = [];
2998
- this._detachTimeout;
2999
- this._detachCallback;
3000
- this._detachAuto;
3001
- this._socket = net.createConnection(port, host);
3002
- this._pending = [];
3003
- this._isOpened = false;
3004
- this._isClosed = false;
3005
- this._isDetach = false;
3006
- this._isUsed = false;
3007
- this._pooled = options.isPool||false;
3008
- this.options = options;
3009
- this._bind_events(host, port, callback);
3010
- this.error;
3011
- this._retry_connection_id;
3012
- this._retry_connection_interval = options.retryConnectionInterval || 1000;
3013
- this._max_cached_query = options.maxCachedQuery || -1;
3014
- this._cache_query = options.cacheQuery?{}:null;
3015
- this._messageFile = options.messageFile || path.join(__dirname, 'firebird.msg');
3016
- };
3017
-
3018
- exports.Connection.prototype._setcachedquery = function (query, statement) {
3019
- if (this._cache_query){
3020
- if (this._max_cached_query === -1 || this._max_cached_query > Object.keys(this._cache_query).length){
3021
- this._cache_query[query] = statement;
3022
- }
3023
- }
3024
-
3025
-
3026
- };
3027
-
3028
- exports.Connection.prototype.getCachedQuery = function (query) {
3029
- return this._cache_query ? this._cache_query[query] : null;
3030
- };
3031
-
3032
- exports.Connection.prototype._bind_events = function(host, port, callback) {
3033
-
3034
- var self = this;
3035
-
3036
- self._socket.on('close', function() {
3037
-
3038
- if (!self._isOpened || self._isDetach) {
3039
- return;
3040
- }
3041
-
3042
- self._isOpened = false;
3043
-
3044
- if (!self.db) {
3045
- if (callback)
3046
- callback(self.error);
3047
- return;
3048
- }
3049
-
3050
- self._retry_connection_id = setTimeout(function() {
3051
- self._socket.removeAllListeners();
3052
- self._socket = null;
3053
-
3054
- var ctx = new Connection(host, port, function(err) {
3055
- ctx.connect(self.options, function(err) {
3056
-
3057
- if (err) {
3058
- self.db.emit('error', err);
3059
- return;
3060
- }
3061
-
3062
- ctx.attach(self.options, function(err) {
3063
-
3064
- if (err) {
3065
- self.db.emit('error', err);
3066
- return;
3067
- }
3068
-
3069
- ctx._queue = ctx._queue.concat(self._queue);
3070
- ctx._pending = ctx._pending.concat(self._pending);
3071
- self.db.emit('reconnect');
3072
-
3073
- }, self.db);
3074
- });
3075
-
3076
- Object.assign(self, ctx);
3077
-
3078
- }, self.options, self.db);
3079
- }, self._retry_connection_interval);
3080
-
3081
- });
3082
-
3083
- self._socket.on('error', function(e) {
3084
-
3085
- self.error = e;
3086
-
3087
- if (self.db)
3088
- self.db.emit('error', e)
3089
-
3090
- if (callback)
3091
- callback(e);
3092
-
3093
- });
3094
-
3095
- self._socket.on('connect', function() {
3096
- self._isClosed = false;
3097
- self._isOpened = true;
3098
- if (callback)
3099
- callback();
3100
- });
3101
-
3102
- self._socket.on('data', function (data) {
3103
- var xdr;
3104
-
3105
- if (!self._xdr) {
3106
- xdr = new XdrReader(data);
3107
- } else {
3108
- xdr = new XdrReader(Buffer.concat([self._xdr.buffer, data], self._xdr.buffer.length + data.length));
3109
- delete (self._xdr);
3110
- }
3111
-
3112
- while (xdr.pos < xdr.buffer.length) {
3113
- var cb = self._queue[0], pos = xdr.pos;
3114
-
3115
- decodeResponse(xdr, cb, self, self._lowercase_keys, function (err, obj) {
3116
-
3117
- if (err) {
3118
- xdr.buffer = xdr.buffer.slice(pos);
3119
- xdr.pos = 0;
3120
- self._xdr = xdr;
3121
-
3122
- if (self.accept.protocolMinimumType === ptype_lazy_send && self._queue.length > 0) {
3123
- self._queue[0].lazy_count = 2;
3124
- }
3125
- return;
3126
- }
3127
-
3128
- // remove the op flag, needed for partial packet
3129
- if (xdr.r) {
3130
- delete (xdr.r);
3131
- }
3132
-
3133
- self._queue.shift();
3134
- self._pending.shift();
3135
-
3136
- if (obj && obj.status) {
3137
- obj.message = lookupMessages(obj.status);
3138
- doCallback(obj, cb);
3139
- } else {
3140
- doCallback(obj, cb);
3141
- }
3142
-
3143
- });
3144
-
3145
- if (xdr.pos === 0) {
3146
- break;
3147
- }
3148
- }
3149
-
3150
- if (!self._detachAuto || self._pending.length !== 0) {
3151
- return;
3152
- }
3153
-
3154
- clearTimeout(self._detachTimeout);
3155
- self._detachTimeout = setTimeout(function () {
3156
- self.db.detach(self._detachCallback);
3157
- self._detachAuto = false;
3158
- }, 100);
3159
-
3160
- });
3161
- }
3162
-
3163
- exports.Connection.prototype.disconnect = function() {
3164
- this._socket.end();
3165
- };
3166
-
3167
-
3168
- function decodeResponse(data, callback, cnx, lowercase_keys, cb) {
3169
- try {
3170
- do {
3171
- var r = data.r || data.readInt();
3172
- } while (r === op_dummy);
3173
-
3174
- var item, op, response;
3175
-
3176
- switch (r) {
3177
- case op_response:
3178
-
3179
- if (callback) {
3180
- response = callback.response || {};
3181
- } else {
3182
- response = {};
3183
- }
3184
-
3185
- let loop = function (err) {
3186
- if (err) {
3187
- return cb(err);
3188
- } else {
3189
- if (callback && callback.lazy_count) {
3190
- callback.lazy_count--;
3191
- if (callback.lazy_count > 0) {
3192
- r = data.readInt(); // Read new op
3193
- parseOpResponse(data, response, loop);
3194
- } else {
3195
- cb(null, response);
3196
- }
3197
- } else {
3198
- cb(null, response);
3199
- }
3200
- }
3201
- };
3202
- // Parse normal and lazy response
3203
- return parseOpResponse(data, response, loop);
3204
- case op_fetch_response:
3205
- case op_sql_response:
3206
- var statement = callback.statement;
3207
- var output = statement.output;
3208
- var custom = statement.custom || {};
3209
- var isOpFetch = r === op_fetch_response;
3210
- var _xdrpos;
3211
- statement.nbrowsfetched = statement.nbrowsfetched || 0;
3212
-
3213
- if (isOpFetch && data.fop) { // could be set when a packet is not complete
3214
- data.readBuffer(68); // ??
3215
- op = data.readInt(); // ??
3216
- data.fop = false;
3217
- if (op === op_response) {
3218
- return parseOpResponse(data, {}, cb);
3219
- }
3220
- }
3221
-
3222
- if (!isOpFetch) {
3223
- data.fstatus = 0;
3224
- }
3225
-
3226
- data.fstatus = data.fstatus !== undefined ? data.fstatus : data.readInt();
3227
- data.fcount = data.fcount !== undefined ? data.fcount : data.readInt();
3228
- data.fcolumn = data.fcolumn || 0;
3229
- data.frow = data.frow || (custom.asObject ? {} : new Array(output.length));
3230
- data.frows = data.frows || [];
3231
-
3232
- if (custom.asObject && !data.fcols) {
3233
- if (lowercase_keys) {
3234
- data.fcols = output.map((column) => column.alias.toLowerCase());
3235
- } else {
3236
- data.fcols = output.map((column) => column.alias);
3237
- }
3238
- }
3239
-
3240
- const arrBlob = [];
3241
- const lowerV13 = statement.connection.accept.protocolVersion < PROTOCOL_VERSION13;
3242
-
3243
- while (data.fcount && (data.fstatus !== 100)) {
3244
- let nullBitSet;
3245
- if (!lowerV13) {
3246
- const nullBitsLen = Math.floor((output.length + 7) / 8);
3247
- nullBitSet = new BitSet(data.readBuffer(nullBitsLen, false));
3248
- data.readBuffer((4 - nullBitsLen) & 3, false); // Skip padding
3249
- }
3250
-
3251
- for (let length = output.length; data.fcolumn < length; data.fcolumn++) {
3252
- item = output[data.fcolumn];
3253
-
3254
- if (!lowerV13 && nullBitSet.get(data.fcolumn)) {
3255
- if (custom.asObject) {
3256
- data.frow[data.fcols[data.fcolumn]] = null;
3257
- } else {
3258
- data.frow[data.fcolumn] = null;
3259
- }
3260
-
3261
- continue;
3262
- }
3263
-
3264
- try {
3265
- _xdrpos = data.pos;
3266
- const key = custom.asObject ? data.fcols[data.fcolumn] : data.fcolumn;
3267
- const row = data.frows.length;
3268
- let value = item.decode(data, lowerV13);
3269
-
3270
- if (item.type === SQL_BLOB && value !== null) {
3271
- if (item.subType === isc_blob_text && cnx.options.blobAsText) {
3272
- value = fetch_blob_async_transaction(statement, value, key, row);
3273
- arrBlob.push(value);
3274
- } else {
3275
- value = fetch_blob_async(statement, value, key, row);
3276
- }
3277
- }
3278
-
3279
- data.frow[key] = value;
3280
- } catch (e) {
3281
- // uncomplete packet read
3282
- data.pos = _xdrpos;
3283
- data.r = r;
3284
- return cb(new Error('Packet is not complete'));
3285
- }
3286
-
3287
- }
3288
-
3289
- data.fcolumn = 0;
3290
- // ToDo: emit "row" with blob subtype string decoded
3291
- // use: data.frow['fieldBlob'](transaction?).then(({ value }) => console.log(value))
3292
- // arg "transaction" is optional
3293
- statement.connection.db.emit('row', data.frow, statement.nbrowsfetched, custom.asObject);
3294
- data.frows.push(data.frow);
3295
- data.frow = custom.asObject ? {} : new Array(output.length);
3296
-
3297
- try {
3298
- _xdrpos = data.pos;
3299
- if (isOpFetch) {
3300
- delete data.fstatus;
3301
- delete data.fcount;
3302
- op = data.readInt(); // ??
3303
- if (op === op_response) {
3304
- return parseOpResponse(data, {}, cb);
3305
- }
3306
- data.fstatus = data.readInt();
3307
- data.fcount = data.readInt();
3308
- } else {
3309
- data.fcount--;
3310
- if (r === op_sql_response) {
3311
- op = data.readInt();
3312
- if (op === op_response) {
3313
- parseOpResponse(data, {});
3314
- }
3315
- }
3316
- }
3317
- } catch (e) {
3318
- if (_xdrpos === data.pos) {
3319
- data.fop = true;
3320
- }
3321
- data.r = r;
3322
- return cb(new Error("Packet is not complete"));
3323
- }
3324
- statement.nbrowsfetched++;
3325
- }
3326
-
3327
- // ToDo: emit "result" with blob subtype string decoded
3328
- statement.connection.db.emit('result', data.frows, arrBlob);
3329
- return cb(null, {data: data.frows, fetched: Boolean(!isOpFetch || data.fstatus === 100), arrBlob});
3330
- case op_accept:
3331
- case op_cond_accept:
3332
- case op_accept_data:
3333
- let accept = {
3334
- protocolVersion: data.readInt(),
3335
- protocolArchitecture: data.readInt(),
3336
- protocolMinimumType: data.readInt(),
3337
- pluginName: '',
3338
- authData: '',
3339
- sessionKey: ''
3340
- };
3341
-
3342
- accept.protocolMinimumType = accept.protocolMinimumType & 0xFF;
3343
- //accept.compress = (accept.acceptType & pflag_compress) !== 0; // TODO Handle zlib compression
3344
- if (accept.protocolVersion < 0) {
3345
- accept.protocolVersion = (accept.protocolVersion & FB_PROTOCOL_MASK) | FB_PROTOCOL_FLAG;
3346
- }
3347
-
3348
- if (r === op_cond_accept || r === op_accept_data) {
3349
- var d = new BlrReader(data.readArray());
3350
- accept.pluginName = data.readString(DEFAULT_ENCODING);
3351
- var is_authenticated = data.readInt();
3352
- var keys = data.readString(DEFAULT_ENCODING); // keys
3353
-
3354
- if (is_authenticated === 0) {
3355
- if (cnx.options.pluginName && cnx.options.pluginName !== accept.pluginName) {
3356
- doError(new Error('Server don\'t accept plugin : ' + cnx.options.pluginName + ', but support : ' + accept.pluginName), callback);
3357
- }
3358
-
3359
- if (AUTH_PLUGIN_SRP_LIST.indexOf(accept.pluginName) !== -1) {
3360
- var crypto = {
3361
- Srp: 'sha1',
3362
- Srp256: 'sha256'
3363
- };
3364
- accept.srpAlgo = crypto[accept.pluginName];
3365
-
3366
- // TODO : Fallback Srp256 to Srp ?
3367
- /*if (!d.buffer) {
3368
- cnx.sendOpContAuth(
3369
- cnx.clientKeys.public.toString(16),
3370
- DEFAULT_ENCODING,
3371
- accept.pluginName
3372
- );
3373
-
3374
- return cb(new Error('login'));
3375
- }*/
3376
-
3377
- // Check buffer contains salt
3378
- var saltLen = d.buffer.readUInt16LE(0);
3379
- if (saltLen > 32 * 2) {
3380
- console.log('salt to long'); // TODO : Throw error
3381
- }
3382
-
3383
- // Check buffer contains key
3384
- var keyLen = d.buffer.readUInt16LE(saltLen + 2);
3385
- var keyStart = saltLen + 4;
3386
- if (d.buffer.length - keyStart !== keyLen) {
3387
- console.log('key error'); // TODO : Throw error
3388
- }
3389
-
3390
- // Server keys
3391
- cnx.serverKeys = {
3392
- salt: d.buffer.slice(2, saltLen + 2).toString('utf8'),
3393
- public: BigInt(d.buffer.slice(keyStart, d.buffer.length).toString('utf8'), 16)
3394
- };
3395
-
3396
- var proof = srp.clientProof(
3397
- cnx.options.user.toUpperCase(),
3398
- cnx.options.password,
3399
- cnx.serverKeys.salt,
3400
- cnx.clientKeys.public,
3401
- cnx.serverKeys.public,
3402
- cnx.clientKeys.private,
3403
- accept.srpAlgo
3404
- );
3405
-
3406
- accept.authData = proof.authData.toString(16);
3407
- accept.sessionKey = proof.clientSessionKey;
3408
- } else if (accept.pluginName === AUTH_PLUGIN_LEGACY) {
3409
- accept.authData = crypt.crypt(cnx.options.password, LEGACY_AUTH_SALT).substring(2);
3410
- } else {
3411
- return cb(new Error('Unknow auth plugin : ' + accept.pluginName));
3412
- }
3413
- } else {
3414
- accept.authData = '';
3415
- accept.sessionKey = '';
3416
- }
3417
- }
3418
-
3419
- return cb(undefined, accept);
3420
- case op_cont_auth:
3421
- var d = new BlrReader(data.readArray());
3422
- var pluginName = data.readString(DEFAULT_ENCODING);
3423
- data.readString(DEFAULT_ENCODING); // plist
3424
- data.readString(DEFAULT_ENCODING); // pkey
3425
-
3426
- if (!cnx.options.pluginName) {
3427
- if (cnx.accept.pluginName === pluginName) {
3428
- // Erreur plugin not able to connect
3429
- return cb(new Error("Unable to connect with plugin " + cnx.accept.pluginName));
3430
- }
3431
-
3432
- if (pluginName === AUTH_PLUGIN_LEGACY) { // Fallback to LegacyAuth
3433
- cnx.accept.pluginName = pluginName;
3434
- cnx.accept.authData = crypt.crypt(cnx.options.password, LEGACY_AUTH_SALT).substring(2);
3435
-
3436
- cnx.sendOpContAuth(
3437
- cnx.accept.authData,
3438
- DEFAULT_ENCODING,
3439
- pluginName
3440
- );
3441
-
3442
- return {error: new Error('login')};
3443
- }
3444
- }
3445
-
3446
- return data.accept;
3447
- default:
3448
- return cb(new Error('Unexpected:' + r));
3449
- }
3450
- } catch (err) {
3451
- if (err instanceof RangeError) {
3452
- return cb(err);
3453
- }
3454
- throw err;
3455
- }
3456
- }
3457
-
3458
- function parseOpResponse(data, response, cb) {
3459
- var handle = data.readInt();
3460
-
3461
- if (!response.handle) {
3462
- response.handle = handle;
3463
- }
3464
-
3465
- var oid = data.readQuad();
3466
- if (oid.low || oid.high) {
3467
- response.oid = oid;
3468
- }
3469
-
3470
- var buf = data.readArray();
3471
- if (buf) {
3472
- response.buffer = buf;
3473
- }
3474
-
3475
- var num, op, item = {};
3476
- while (true) {
3477
- op = data.readInt();
3478
-
3479
- switch (op) {
3480
- case isc_arg_end:
3481
- return cb ? cb(undefined, response) : response;
3482
- case isc_arg_gds:
3483
- num = data.readInt();
3484
- if (!num) {
3485
- break;
3486
- }
3487
-
3488
- item = {gdscode: num};
3489
-
3490
- if (response.status) {
3491
- response.status.push(item);
3492
- } else {
3493
- response.status = [item];
3494
- }
3495
-
3496
- break;
3497
- case isc_arg_string:
3498
- case isc_arg_interpreted:
3499
- case isc_arg_sql_state:
3500
- if (item.params) {
3501
- var str = data.readString(DEFAULT_ENCODING);
3502
- item.params.push(str);
3503
- } else {
3504
- item.params = [data.readString(DEFAULT_ENCODING)];
3505
- }
3506
-
3507
- break;
3508
- case isc_arg_number:
3509
- num = data.readInt();
3510
-
3511
- if (item.params) {
3512
- item.params.push(num);
3513
- } else {
3514
- item.params = [num];
3515
- }
3516
-
3517
- if (item.gdscode === isc_sqlerr) {
3518
- response.sqlcode = num;
3519
- }
3520
-
3521
- break;
3522
- default:
3523
- if (cb) {
3524
- cb(new Error('Unexpected: ' + op))
3525
- } else {
3526
- throw new Error('Unexpected: ' + op);
3527
- }
3528
- }
3529
- }
3530
- }
3531
-
3532
- Connection.prototype.sendOpContAuth = function(authData, authDataEnc, pluginName) {
3533
- var msg = this._msg;
3534
- msg.pos = 0;
3535
-
3536
- msg.addInt(op_cont_auth);
3537
- msg.addString(authData, authDataEnc);
3538
- msg.addString(pluginName, DEFAULT_ENCODING)
3539
- msg.addString(AUTH_PLUGIN_LIST.join(','), DEFAULT_ENCODING);
3540
- // msg.addInt(0); // p_list
3541
- msg.addInt(0); // keys
3542
-
3543
- this._socket.write(msg.getData());
3544
- }
3545
-
3546
- Connection.prototype._queueEvent = function(callback){
3547
- var self = this;
3548
-
3549
- if (self._isClosed) {
3550
- if (callback)
3551
- callback(new Error('Connection is closed.'));
3552
- return;
3553
- }
3554
-
3555
- self._queue.push(callback);
3556
- self._socket.write(self._msg.getData());
3557
- };
3558
-
3559
- Connection.prototype.connect = function (options, callback) {
3560
- var pluginName = options.manager ? AUTH_PLUGIN_LEGACY : options.pluginName || AUTH_PLUGIN_LIST[0]; // TODO Srp for service
3561
- var msg = this._msg;
3562
- var blr = this._blr;
3563
-
3564
- this._pending.push('connect');
3565
-
3566
- msg.pos = 0;
3567
- blr.pos = 0;
3568
-
3569
- blr.addString(CNCT_login, options.user, DEFAULT_ENCODING);
3570
- blr.addString(CNCT_plugin_name, pluginName, DEFAULT_ENCODING);
3571
- blr.addString(CNCT_plugin_list, AUTH_PLUGIN_LIST.join(','), DEFAULT_ENCODING);
3572
-
3573
- var specificData = '';
3574
- if (AUTH_PLUGIN_SRP_LIST.indexOf(pluginName) > -1) {
3575
- this.clientKeys = srp.clientSeed();
3576
- specificData = this.clientKeys.public.toString(16);
3577
- blr.addMultiblockPart(CNCT_specific_data, specificData, DEFAULT_ENCODING);
3578
- } else if (pluginName === AUTH_PLUGIN_LEGACY) {
3579
- specificData = crypt.crypt(options.password, LEGACY_AUTH_SALT).substring(2);
3580
- blr.addMultiblockPart(CNCT_specific_data, specificData, DEFAULT_ENCODING);
3581
- } else {
3582
- doError(new Error('Invalide auth plugin \'' + pluginName + '\''), callback);
3583
- return;
3584
- }
3585
- blr.addBytes([CNCT_client_crypt, 4, WIRE_CRYPT_DISABLE, 0, 0, 0]); // WireCrypt = Disabled
3586
- blr.addString(CNCT_user, os.userInfo().username || 'Unknown', DEFAULT_ENCODING);
3587
- blr.addString(CNCT_host, os.hostname(), DEFAULT_ENCODING);
3588
- blr.addBytes([CNCT_user_verification, 0]);
3589
-
3590
- msg.addInt(op_connect);
3591
- msg.addInt(op_attach);
3592
- msg.addInt(CONNECT_VERSION3);
3593
- msg.addInt(ARCHITECTURE_GENERIC);
3594
- msg.addString(options.database || options.filename, DEFAULT_ENCODING);
3595
- msg.addInt(SUPPORTED_PROTOCOL.length); // Count of Protocol version understood count.
3596
- msg.addBlr(this._blr);
3597
-
3598
- for (var protocol of SUPPORTED_PROTOCOL) {
3599
- msg.addInt(protocol[0]); // Version
3600
- msg.addInt(protocol[1]); // Architecture
3601
- msg.addInt(protocol[2]); // Min type
3602
- msg.addInt(protocol[3]); // Max type
3603
- msg.addInt(protocol[4]); // Preference weight
3604
- }
3605
-
3606
- var self = this;
3607
- function cb(err, ret) {
3608
- if (err) {
3609
- doError(err, callback);
3610
- return;
3611
- }
3612
-
3613
- self.accept = ret;
3614
- if (callback)
3615
- callback(undefined, ret);
3616
- }
3617
-
3618
- this._queueEvent(cb);
3619
- };
3620
-
3621
- Connection.prototype.attach = function (options, callback, db) {
3622
- this._lowercase_keys = options.lowercase_keys || DEFAULT_LOWERCASE_KEYS;
3623
-
3624
- var database = options.database || options.filename;
3625
- if (database == null || database.length === 0) {
3626
- doError(new Error('No database specified'), callback);
3627
- return;
3628
- }
3629
-
3630
- var user = options.user || DEFAULT_USER;
3631
- var password = options.password || DEFAULT_PASSWORD;
3632
- var role = options.role;
3633
- var self = this;
3634
- var msg = this._msg;
3635
- var blr = this._blr;
3636
- msg.pos = 0;
3637
- blr.pos = 0;
3638
-
3639
- blr.addByte(isc_dpb_version1);
3640
- blr.addString(isc_dpb_lc_ctype, options.encoding || 'UTF8', DEFAULT_ENCODING);
3641
- blr.addString(isc_dpb_user_name, user, DEFAULT_ENCODING);
3642
- if (options.password && !this.accept.authData) {
3643
- if (this.accept.protocolVersion < PROTOCOL_VERSION13) {
3644
- if (this.accept.protocolVersion === PROTOCOL_VERSION10) {
3645
- blr.addString(isc_dpb_password, password, DEFAULT_ENCODING);
3646
- } else {
3647
- blr.addString(isc_dpb_password_enc, crypt.crypt(password, LEGACY_AUTH_SALT).substring(2), DEFAULT_ENCODING);
3648
- }
3649
- }
3650
- }
3651
-
3652
- if (role)
3653
- blr.addString(isc_dpb_sql_role_name, role, DEFAULT_ENCODING);
3654
-
3655
- blr.addBytes([isc_dpb_process_id, 4]);
3656
- blr.addInt32(process.pid);
3657
-
3658
- let processName = process.title || "";
3659
- blr.addString(isc_dpb_process_name, processName.length > 255 ? processName.substring(processName.length - 255, processName.length) : processName, DEFAULT_ENCODING);
3660
-
3661
- if (this.accept.authData) {
3662
- blr.addString(isc_dpb_specific_auth_data, this.accept.authData, DEFAULT_ENCODING);
3663
- }
3664
-
3665
- msg.addInt(op_attach);
3666
- msg.addInt(0); // Database Object ID
3667
- msg.addString(database, DEFAULT_ENCODING);
3668
- msg.addBlr(this._blr);
3669
-
3670
- function cb(err, ret) {
3671
- if (err) {
3672
- doError(err, callback);
3673
- return;
3674
- }
3675
-
3676
- self.dbhandle = ret.handle;
3677
- if (callback)
3678
- callback(undefined, ret);
3679
- }
3680
-
3681
- // For reconnect
3682
- if (db) {
3683
- db.connection = this;
3684
- cb.response = db;
3685
- } else {
3686
- cb.response = new Database(this);
3687
- cb.response.removeAllListeners('error');
3688
- cb.response.on('error', noop);
3689
- }
3690
-
3691
- this._queueEvent(cb);
3692
- };
3693
-
3694
- Connection.prototype.detach = function (callback) {
3695
-
3696
- var self = this;
3697
-
3698
- if (self._isClosed)
3699
- return;
3700
-
3701
- self._isUsed = false;
3702
- self._isDetach = true;
3703
-
3704
- var msg = self._msg;
3705
-
3706
- msg.pos = 0;
3707
- msg.addInt(op_detach);
3708
- msg.addInt(0); // Database Object ID
3709
-
3710
- self._queueEvent(function(err, ret) {
3711
- clearTimeout(self._retry_connection_id);
3712
- delete(self.dbhandle);
3713
- if (callback)
3714
- callback(err, ret);
3715
- });
3716
- };
3717
-
3718
- Connection.prototype.createDatabase = function (options, callback) {
3719
- var database = options.database || options.filename;
3720
- if (database == null || database.length === 0) {
3721
- doError(new Error('No database specified'), callback);
3722
- return;
3723
- }
3724
-
3725
- var user = options.user || DEFAULT_USER;
3726
- var password = options.password || DEFAULT_PASSWORD;
3727
- var pageSize = options.pageSize || DEFAULT_PAGE_SIZE;
3728
- var role = options.role;
3729
- var blr = this._blr;
3730
-
3731
- blr.pos = 0;
3732
- blr.addByte(isc_dpb_version1);
3733
- blr.addString(isc_dpb_set_db_charset, 'UTF8', DEFAULT_ENCODING);
3734
- blr.addString(isc_dpb_lc_ctype, 'UTF8', DEFAULT_ENCODING);
3735
- blr.addString(isc_dpb_user_name, user, DEFAULT_ENCODING);
3736
- if (this.accept.protocolVersion < PROTOCOL_VERSION13) {
3737
- if (this.accept.protocolVersion === PROTOCOL_VERSION10) {
3738
- blr.addString(isc_dpb_password, password, DEFAULT_ENCODING);
3739
- } else {
3740
- blr.addString(isc_dpb_password_enc, crypt.crypt(password, LEGACY_AUTH_SALT).substring(2), DEFAULT_ENCODING);
3741
- }
3742
- }
3743
- if (role)
3744
- blr.addString(isc_dpb_sql_role_name, role, DEFAULT_ENCODING);
3745
-
3746
- blr.addBytes([isc_dpb_process_id, 4]);
3747
- blr.addInt32(process.pid);
3748
-
3749
- let processName = process.title || "";
3750
- blr.addString(isc_dpb_process_name, processName.length > 255 ? processName.substring(processName.length - 255, processName.length) : processName, DEFAULT_ENCODING);
3751
-
3752
- if (this.accept.authData) {
3753
- blr.addString(isc_dpb_specific_auth_data, this.accept.authData, DEFAULT_ENCODING);
3754
- }
3755
-
3756
- blr.addNumeric(isc_dpb_sql_dialect, 3);
3757
- blr.addNumeric(isc_dpb_force_write, 1);
3758
- blr.addNumeric(isc_dpb_overwrite, 1);
3759
- blr.addNumeric(isc_dpb_page_size, pageSize);
3760
-
3761
- var msg = this._msg;
3762
- msg.pos = 0;
3763
- msg.addInt(op_create); // op_create
3764
- msg.addInt(0); // Database Object ID
3765
- msg.addString(database, DEFAULT_ENCODING);
3766
- msg.addBlr(blr);
3767
-
3768
- var self = this;
3769
-
3770
- function cb(err, ret) {
3771
-
3772
- if (ret)
3773
- self.dbhandle = ret.handle;
3774
-
3775
- setImmediate(function() {
3776
- if (self.db)
3777
- self.db.emit('attach', ret);
3778
- });
3779
-
3780
- if (callback)
3781
- callback(err, ret);
3782
- }
3783
-
3784
- cb.response = new Database(this);
3785
- this._queueEvent(cb);
3786
- };
3787
-
3788
- Connection.prototype.dropDatabase = function (callback) {
3789
- var msg = this._msg;
3790
- msg.pos = 0;
3791
-
3792
- msg.addInt(op_drop_database);
3793
- msg.addInt(this.dbhandle);
3794
-
3795
- var self = this;
3796
- this._queueEvent(function(err) {
3797
- self.detach(function() {
3798
- self.disconnect();
3799
-
3800
- if (callback)
3801
- callback(err);
3802
- });
3803
- });
3804
- };
3805
-
3806
- Connection.prototype.throwClosed = function(callback) {
3807
- var err = new Error('Connection is closed.');
3808
- this.db.emit('error', err);
3809
- if (callback)
3810
- callback(err);
3811
- return this;
3812
- };
3813
-
3814
- Connection.prototype.startTransaction = function(isolation, callback) {
3815
-
3816
- if (typeof(isolation) === 'function') {
3817
- var tmp = isolation;
3818
- isolation = callback;
3819
- callback = tmp;
3820
- }
3821
-
3822
- if (this._isClosed)
3823
- return this.throwClosed(callback);
3824
-
3825
- // for auto detach
3826
- this._pending.push('startTransaction');
3827
-
3828
- var blr = this._blr;
3829
- var msg = this._msg;
13
+ exports.AUTH_PLUGIN_LEGACY = Const.AUTH_PLUGIN_LEGACY;
14
+ exports.AUTH_PLUGIN_SRP = Const.AUTH_PLUGIN_SRP;
15
+ // exports.AUTH_PLUGIN_SRP256 = Const.AUTH_PLUGIN_SRP256;
3830
16
 
3831
- blr.pos = 0;
3832
- msg.pos = 0;
17
+ exports.WIRE_CRYPT_DISABLE = Const.WIRE_CRYPT_DISABLE;
18
+ exports.WIRE_CRYPT_ENABLE = Const.WIRE_CRYPT_ENABLE;
3833
19
 
3834
- blr.addBytes(isolation || ISOLATION_REPEATABLE_READ);
3835
- msg.addInt(op_transaction);
3836
- msg.addInt(this.dbhandle);
3837
- msg.addBlr(blr);
3838
- callback.response = new Transaction(this);
20
+ exports.ISOLATION_READ_UNCOMMITTED = Const.ISOLATION_READ_UNCOMMITTED;
21
+ exports.ISOLATION_READ_COMMITTED = Const.ISOLATION_READ_COMMITTED;
22
+ exports.ISOLATION_REPEATABLE_READ = Const.ISOLATION_REPEATABLE_READ;
23
+ exports.ISOLATION_SERIALIZABLE = Const.ISOLATION_SERIALIZABLE;
24
+ exports.ISOLATION_READ_COMMITTED_READ_ONLY = Const.ISOLATION_READ_COMMITTED_READ_ONLY;
3839
25
 
3840
- this.db.emit('transaction', isolation);
3841
- this._queueEvent(callback);
3842
- };
3843
-
3844
- Connection.prototype.commit = function (transaction, callback) {
3845
-
3846
- if (this._isClosed)
3847
- return this.throwClosed(callback);
3848
-
3849
- // for auto detach
3850
- this._pending.push('commit');
3851
-
3852
- var msg = this._msg;
3853
- msg.pos = 0;
3854
- msg.addInt(op_commit);
3855
- msg.addInt(transaction.handle);
3856
- this.db.emit('commit');
3857
- this._queueEvent(callback);
3858
- };
3859
-
3860
- Connection.prototype.rollback = function (transaction, callback) {
3861
-
3862
- if (this._isClosed)
3863
- return this.throwClosed(callback);
3864
-
3865
- // for auto detach
3866
- this._pending.push('rollback');
3867
-
3868
- var msg = this._msg;
3869
- msg.pos = 0;
3870
- msg.addInt(op_rollback);
3871
- msg.addInt(transaction.handle);
3872
- this.db.emit('rollback');
3873
- this._queueEvent(callback);
3874
- };
3875
-
3876
- Connection.prototype.commitRetaining = function (transaction, callback) {
3877
-
3878
- if (this._isClosed)
3879
- throw new Error('Connection is closed.');
3880
-
3881
- // for auto detach
3882
- this._pending.push('commitRetaining');
3883
-
3884
- var msg = this._msg;
3885
- msg.pos = 0;
3886
- msg.addInt(op_commit_retaining);
3887
- msg.addInt(transaction.handle);
3888
- this._queueEvent(callback);
3889
- };
3890
-
3891
- Connection.prototype.rollbackRetaining = function (transaction, callback) {
3892
-
3893
- if (this._isClosed)
3894
- return this.throwClosed(callback);
3895
-
3896
- // for auto detach
3897
- this._pending.push('rollbackRetaining');
3898
-
3899
- var msg = this._msg;
3900
- msg.pos = 0;
3901
- msg.addInt(op_rollback_retaining);
3902
- msg.addInt(transaction.handle);
3903
- this._queueEvent(callback);
3904
- };
3905
-
3906
- Connection.prototype.allocateStatement = function (callback) {
3907
-
3908
- if (this._isClosed)
3909
- return this.throwClosed(callback);
3910
-
3911
- // for auto detach
3912
- this._pending.push('allocateStatement');
3913
-
3914
- var msg = this._msg;
3915
- msg.pos = 0;
3916
- msg.addInt(op_allocate_statement);
3917
- msg.addInt(this.dbhandle);
3918
- callback.response = new Statement(this);
3919
- this._queueEvent(callback);
3920
- };
3921
-
3922
- Connection.prototype.dropStatement = function (statement, callback) {
3923
-
3924
- if (this._isClosed)
3925
- return this.throwClosed(callback);
3926
-
3927
- // for auto detach
3928
- this._pending.push('dropStatement');
3929
-
3930
- var msg = this._msg;
3931
- msg.pos = 0;
3932
- msg.addInt(op_free_statement);
3933
- msg.addInt(statement.handle);
3934
- msg.addInt(DSQL_drop);
3935
- this._queueEvent(callback);
3936
- };
3937
-
3938
- Connection.prototype.closeStatement = function (statement, callback) {
3939
-
3940
- if (this._isClosed)
3941
- return this.throwClosed(callback);
3942
-
3943
- // for auto detach
3944
- this._pending.push('closeStatement');
3945
-
3946
- var msg = this._msg;
3947
- msg.pos = 0;
3948
- msg.addInt(op_free_statement);
3949
- msg.addInt(statement.handle);
3950
- msg.addInt(DSQL_close);
3951
-
3952
- this._queueEvent(callback);
3953
- };
3954
-
3955
- Connection.prototype.allocateAndPrepareStatement = function (transaction, query, plan, callback) {
3956
- var self = this;
3957
- var mainCallback = function(err, ret) {
3958
- if (!err) {
3959
- mainCallback.response.handle = ret.handle;
3960
- describe(ret.buffer, mainCallback.response);
3961
- mainCallback.response.query = query;
3962
- self.db.emit('query', query);
3963
- ret = mainCallback.response;
3964
- self._setcachedquery(query, ret);
3965
- }
3966
-
3967
- if (callback)
3968
- callback(err, ret);
3969
- };
3970
-
3971
- // for auto detach
3972
- this._pending.push('allocateAndPrepareStatement');
3973
-
3974
- var msg = this._msg;
3975
- var blr = this._blr;
3976
-
3977
- msg.pos = 0;
3978
- blr.pos = 0;
3979
-
3980
- msg.addInt(op_allocate_statement);
3981
- msg.addInt(this.dbhandle);
3982
- mainCallback.lazy_count = 1;
3983
-
3984
- blr.addBytes(DESCRIBE);
3985
- if (plan)
3986
- blr.addByte(isc_info_sql_get_plan);
3987
-
3988
- msg.addInt(op_prepare_statement);
3989
- msg.addInt(transaction.handle);
3990
- msg.addInt(0xFFFF);
3991
- msg.addInt(3); // dialect = 3
3992
- msg.addString(query, DEFAULT_ENCODING);
3993
- msg.addBlr(blr);
3994
- msg.addInt(65535); // buffer_length
3995
- mainCallback.lazy_count += 1;
3996
-
3997
- mainCallback.response = new Statement(this);
3998
- this._queueEvent(mainCallback);
3999
- };
4000
-
4001
- Connection.prototype.prepare = function (transaction, query, plan, callback) {
4002
- var self = this;
4003
-
4004
- if (this.accept.protocolMinimumType === ptype_lazy_send) { // V11 Statement or higher
4005
- self.allocateAndPrepareStatement(transaction, query, plan, callback);
4006
- } else { // V10 Statement
4007
- self.allocateStatement(function (err, statement) {
4008
- if (err) {
4009
- doError(err, callback);
4010
- return;
4011
- }
4012
-
4013
- self.prepareStatement(transaction, statement, query, plan, callback);
4014
- });
4015
- }
4016
- };
4017
-
4018
- function describe(buff, statement) {
4019
- var br = new BlrReader(buff);
4020
- var parameters = null;
4021
- var type, param;
4022
-
4023
- while (br.pos < br.buffer.length) {
4024
- switch (br.readByteCode()) {
4025
- case isc_info_sql_stmt_type:
4026
- statement.type = br.readInt();
4027
- break;
4028
- case isc_info_sql_get_plan:
4029
- statement.plan = br.readString(DEFAULT_ENCODING);
4030
- break;
4031
- case isc_info_sql_select:
4032
- statement.output = parameters = [];
4033
- break;
4034
- case isc_info_sql_bind:
4035
- statement.input = parameters = [];
4036
- break;
4037
- case isc_info_sql_num_variables:
4038
- br.readInt(); // eat int
4039
- break;
4040
- case isc_info_sql_describe_vars:
4041
- if (!parameters) {return}
4042
- br.readInt(); // eat int ?
4043
- var finishDescribe = false;
4044
- param = null;
4045
- while (!finishDescribe){
4046
- switch (br.readByteCode()) {
4047
- case isc_info_sql_describe_end:
4048
- break;
4049
- case isc_info_sql_sqlda_seq:
4050
- var num = br.readInt();
4051
- break;
4052
- case isc_info_sql_type:
4053
- type = br.readInt();
4054
- switch (type&~1) {
4055
- case SQL_VARYING: param = new SQLVarString(); break;
4056
- case SQL_NULL: param = new SQLVarNull(); break;
4057
- case SQL_TEXT: param = new SQLVarText(); break;
4058
- case SQL_DOUBLE: param = new SQLVarDouble(); break;
4059
- case SQL_FLOAT:
4060
- case SQL_D_FLOAT: param = new SQLVarFloat(); break;
4061
- case SQL_TYPE_DATE: param = new SQLVarDate(); break;
4062
- case SQL_TYPE_TIME: param = new SQLVarTime(); break;
4063
- case SQL_TIMESTAMP: param = new SQLVarTimeStamp(); break;
4064
- case SQL_BLOB: param = new SQLVarBlob(); break;
4065
- case SQL_ARRAY: param = new SQLVarArray(); break;
4066
- case SQL_QUAD: param = new SQLVarQuad(); break;
4067
- case SQL_LONG: param = new SQLVarInt(); break;
4068
- case SQL_SHORT: param = new SQLVarShort(); break;
4069
- case SQL_INT64: param = new SQLVarInt64(); break;
4070
- case SQL_BOOLEAN: param = new SQLVarBoolean(); break;
4071
- default:
4072
- throw new Error('Unexpected');
4073
- }
4074
- parameters[num-1] = param;
4075
- param.type = type;
4076
- param.nullable = Boolean(param.type & 1);
4077
- param.type &= ~1;
4078
- break;
4079
- case isc_info_sql_sub_type:
4080
- param.subType = br.readInt();
4081
- break;
4082
- case isc_info_sql_scale:
4083
- param.scale = br.readInt();
4084
- break;
4085
- case isc_info_sql_length:
4086
- param.length = br.readInt();
4087
- break;
4088
- case isc_info_sql_null_ind:
4089
- param.nullable = Boolean(br.readInt());
4090
- break;
4091
- case isc_info_sql_field:
4092
- param.field = br.readString(DEFAULT_ENCODING);
4093
- break;
4094
- case isc_info_sql_relation:
4095
- param.relation = br.readString(DEFAULT_ENCODING);
4096
- break;
4097
- case isc_info_sql_owner:
4098
- param.owner = br.readString(DEFAULT_ENCODING);
4099
- break;
4100
- case isc_info_sql_alias:
4101
- param.alias = br.readString(DEFAULT_ENCODING);
4102
- break;
4103
- case isc_info_sql_relation_alias:
4104
- param.relationAlias = br.readString(DEFAULT_ENCODING);
4105
- break;
4106
- case isc_info_truncated:
4107
- throw new Error('Truncated');
4108
- default:
4109
- finishDescribe = true;
4110
- br.pos--;
4111
- }
4112
- }
4113
- }
4114
- }
4115
- }
4116
-
4117
- Connection.prototype.prepareStatement = function (transaction, statement, query, plan, callback) {
4118
-
4119
- if (this._isClosed)
4120
- return this.throwClosed(callback);
4121
-
4122
- var msg = this._msg;
4123
- var blr = this._blr;
4124
-
4125
- msg.pos = 0;
4126
- blr.pos = 0;
4127
-
4128
- if (plan instanceof Function) {
4129
- callback = plan;
4130
- plan = false;
4131
- }
4132
-
4133
- blr.addBytes(DESCRIBE);
4134
-
4135
- if (plan)
4136
- blr.addByte(isc_info_sql_get_plan);
4137
-
4138
- msg.addInt(op_prepare_statement);
4139
- msg.addInt(transaction.handle);
4140
- msg.addInt(statement.handle);
4141
- msg.addInt(3); // dialect = 3
4142
- msg.addString(query, DEFAULT_ENCODING);
4143
- msg.addBlr(blr);
4144
- msg.addInt(65535); // buffer_length
4145
-
4146
- var self = this;
4147
- this._queueEvent(function(err, ret) {
4148
-
4149
- if (!err) {
4150
- describe(ret.buffer, statement);
4151
- statement.query = query;
4152
- self.db.emit('query', query);
4153
- ret = statement;
4154
- self._setcachedquery(query, ret);
4155
- }
4156
-
4157
- if (callback)
4158
- callback(err, ret);
4159
- });
4160
-
4161
- };
4162
-
4163
- function CalcBlr(blr, xsqlda) {
4164
- blr.addBytes([blr_version5, blr_begin, blr_message, 0]); // + message number
4165
- blr.addWord(xsqlda.length * 2);
4166
-
4167
- for (var i = 0, length = xsqlda.length; i < length; i++) {
4168
- xsqlda[i].calcBlr(blr);
4169
- blr.addByte(blr_short);
4170
- blr.addByte(0);
4171
- }
4172
-
4173
- blr.addByte(blr_end);
4174
- blr.addByte(blr_eoc);
26
+ if (!String.prototype.padLeft) {
27
+ String.prototype.padLeft = function(max, c) {
28
+ var self = this;
29
+ return new Array(Math.max(0, max - self.length + 1)).join(c || ' ') + self;
30
+ };
4175
31
  }
4176
32
 
4177
- Connection.prototype.executeStatement = function(transaction, statement, params, callback, custom) {
4178
-
4179
- if (this._isClosed)
4180
- return this.throwClosed(callback);
4181
-
4182
- // for auto detach
4183
- this._pending.push('executeStatement');
4184
-
4185
- if (params instanceof Function) {
4186
- callback = params;
4187
- params = undefined;
4188
- }
4189
-
4190
- var self = this;
4191
-
4192
- var op = op_execute;
4193
- if (
4194
- this.accept.protocolVersion >= PROTOCOL_VERSION13 &&
4195
- statement.type === isc_info_sql_stmt_exec_procedure &&
4196
- statement.output.length
4197
- ) {
4198
- op = op_execute2;
4199
- }
4200
-
4201
- function PrepareParams(params, input, callback) {
4202
-
4203
- var value, meta;
4204
- var ret = new Array(params.length);
4205
- var wait = params.length;
4206
-
4207
- function done() {
4208
- wait--;
4209
- if (wait === 0)
4210
- callback(ret);
4211
- }
4212
-
4213
- function putBlobData(index, value, callback) {
4214
-
4215
- self.createBlob2(transaction, function(err, blob) {
4216
-
4217
- var b;
4218
- var isStream = value.readable;
4219
-
4220
- if (Buffer.isBuffer(value))
4221
- b = value;
4222
- else if (typeof(value) === 'string')
4223
- b = Buffer.from(value, DEFAULT_ENCODING);
4224
- else if (!isStream)
4225
- b = Buffer.from(JSON.stringify(value), DEFAULT_ENCODING);
4226
-
4227
- if (Buffer.isBuffer(b)) {
4228
- bufferReader(b, 1024, function(b, next) {
4229
- self.batchSegments(blob, b, next);
4230
- }, function() {
4231
- ret[index] = new SQLParamQuad(blob.oid);
4232
- self.closeBlob(blob, callback);
4233
- });
4234
- return;
4235
- }
4236
-
4237
- var isReading = false;
4238
- var isEnd = false;
33
+ exports.escape = escape;
4239
34
 
4240
- value.on('data', function(chunk) {
4241
- value.pause();
4242
- isReading = true;
4243
- bufferReader(chunk, 1024, function(b, next) {
4244
- self.batchSegments(blob, b, next);
4245
- }, function() {
4246
- isReading = false;
4247
-
4248
- if (isEnd) {
4249
- ret[index] = new SQLParamQuad(blob.oid);
4250
- self.closeBlob(blob, callback);
4251
- } else
4252
- value.resume();
4253
- });
4254
- });
35
+ exports.attach = function(options, callback) {
36
+ var host = options.host || Const.DEFAULT_HOST;
37
+ var port = options.port || Const.DEFAULT_PORT;
38
+ var manager = options.manager || false;
39
+ var cnx = this.connection = new Connection(host, port, function(err) {
4255
40
 
4256
- value.on('end', function() {
4257
- isEnd = true;
4258
- if (isReading)
4259
- return;
4260
- ret[index] = new SQLParamQuad(blob.oid);
4261
- self.closeBlob(blob, callback);
4262
- });
4263
- });
41
+ if (err) {
42
+ doError(err, callback);
43
+ return;
4264
44
  }
4265
45
 
4266
- for (var i = 0, length = params.length; i < length; i++) {
4267
- value = params[i];
4268
- meta = input[i];
4269
-
4270
- if (value === null || value === undefined) {
4271
- switch (meta.type) {
4272
- case SQL_VARYING:
4273
- case SQL_NULL:
4274
- case SQL_TEXT:
4275
- ret[i] = new SQLParamString(null);
4276
- break;
4277
- case SQL_DOUBLE:
4278
- case SQL_FLOAT:
4279
- case SQL_D_FLOAT:
4280
- ret[i] = new SQLParamDouble(null);
4281
- break;
4282
- case SQL_TYPE_DATE:
4283
- case SQL_TYPE_TIME:
4284
- case SQL_TIMESTAMP:
4285
- ret[i] = new SQLParamDate(null);
4286
- break;
4287
- case SQL_BLOB:
4288
- case SQL_ARRAY:
4289
- case SQL_QUAD:
4290
- ret[i] = new SQLParamQuad(null);
4291
- break;
4292
- case SQL_LONG:
4293
- case SQL_SHORT:
4294
- case SQL_INT64:
4295
- case SQL_BOOLEAN:
4296
- ret[i] = new SQLParamInt(null);
4297
- break;
4298
- default:
4299
- ret[i] = null;
4300
- }
4301
- done();
46
+ cnx.connect(options, function(err) {
47
+ if (err) {
48
+ doError(err, callback);
4302
49
  } else {
4303
- switch (meta.type) {
4304
- case SQL_BLOB:
4305
- putBlobData(i, value, done);
4306
- break;
4307
-
4308
- case SQL_TIMESTAMP:
4309
- case SQL_TYPE_DATE:
4310
- case SQL_TYPE_TIME:
4311
-
4312
- if (value instanceof Date)
4313
- ret[i] = new SQLParamDate(value);
4314
- else if (typeof(value) === 'string')
4315
- ret[i] = new SQLParamDate(parseDate(value));
4316
- else
4317
- ret[i] = new SQLParamDate(new Date(value));
4318
-
4319
- done();
4320
- break;
4321
-
4322
- default:
4323
- switch (typeof value) {
4324
- case 'number':
4325
- if (value % 1 === 0) {
4326
- if (value >= MIN_INT && value <= MAX_INT)
4327
- ret[i] = new SQLParamInt(value);
4328
- else
4329
- ret[i] = new SQLParamInt64(value);
4330
- } else
4331
- ret[i] = new SQLParamDouble(value);
4332
- break;
4333
- case 'string':
4334
- ret[i] = new SQLParamString(value);
4335
- break;
4336
- case 'boolean':
4337
- ret[i] = new SQLParamBool(value);
4338
- break;
4339
- default:
4340
- //throw new Error('Unexpected parametter: ' + JSON.stringify(params) + ' - ' + JSON.stringify(input));
4341
- ret[i] = new SQLParamString(value.toString());
4342
- break;
4343
- }
4344
- done();
4345
- }
50
+ if (manager)
51
+ cnx.svcattach(options, callback);
52
+ else
53
+ cnx.attach(options, callback);
4346
54
  }
4347
- }
4348
- }
4349
-
4350
- var input = statement.input;
4351
-
4352
- if (input.length) {
4353
-
4354
- if (!(params instanceof Array)) {
4355
- if (params !== undefined)
4356
- params = [params];
4357
- else
4358
- params = [];
4359
- }
4360
-
4361
- if (params.length !== input.length) {
4362
- self._pending.pop();
4363
- callback(new Error('Expected parameters: (params=' + params.length + ' vs. expected=' + input.length + ') - ' + statement.query));
4364
- return;
4365
- }
4366
-
4367
- PrepareParams(params, input, function(prms) {
4368
- self.sendExecute(op, statement, transaction, callback, prms);
4369
55
  });
4370
56
 
4371
- return;
4372
- }
4373
-
4374
- this.sendExecute(op, statement, transaction, callback);
57
+ }, options);
4375
58
  };
4376
59
 
4377
- Connection.prototype.sendExecute = function (op, statement, transaction, callback, parameters) {
4378
- var msg = this._msg;
4379
- var blr = this._blr;
4380
- msg.pos = 0;
4381
- blr.pos = 0;
4382
-
4383
- msg.addInt(op);
4384
- msg.addInt(statement.handle);
4385
- msg.addInt(transaction.handle);
4386
-
4387
- if (parameters && parameters.length) {
4388
- CalcBlr(blr, parameters);
4389
- msg.addBlr(blr); // params blr
4390
- msg.addInt(0); // message number
4391
- msg.addInt(1); // param count
4392
-
4393
- if (this.accept.protocolVersion >= PROTOCOL_VERSION13) {
4394
- // start with null indicator bitmap
4395
- var nullBits = new BitSet();
4396
-
4397
- for (var i = 0; i < parameters.length; i++) {
4398
- nullBits.set(i, (parameters[i].value === null) & 1);
4399
- }
4400
-
4401
- var nullBuffer = nullBits.toBuffer();
4402
- var requireBytes = Math.floor((parameters.length + 7) / 8);
4403
- var remainingBytes = requireBytes - nullBuffer.length;
4404
-
4405
- if (nullBuffer.length) {
4406
- msg.addBuffer(nullBuffer);
4407
- }
4408
- if (remainingBytes > 0) {
4409
- msg.addBuffer(Buffer.alloc(remainingBytes));
4410
- }
4411
- msg.addAlignment(requireBytes);
4412
-
4413
- for(var i = 0; i < parameters.length; i++) {
4414
- if (parameters[i].value !== null) {
4415
- parameters[i].encode(msg);
4416
- }
4417
- }
4418
- } else {
4419
- for(var i = 0; i < parameters.length; i++) {
4420
- parameters[i].encode(msg);
4421
- if (parameters[i].value !== null) {
4422
- msg.addInt(0);
4423
- }
4424
- }
4425
- }
4426
- } else {
4427
- msg.addBlr(blr); // empty
4428
- msg.addInt(0); // message number
4429
- msg.addInt(0); // param count
4430
- }
4431
-
4432
- if (op === op_execute2) {
4433
- var outputBlr = new BlrWriter(32);
4434
-
4435
- if (statement.output && statement.output.length) {
4436
- CalcBlr(outputBlr, statement.output);
4437
- msg.addBlr(outputBlr);
4438
- } else {
4439
- msg.addBlr(outputBlr); // empty
60
+ exports.drop = function(options, callback) {
61
+ exports.attach(options, function(err, db) {
62
+ if (err) {
63
+ callback({ error: err, message: "Drop error" });
64
+ return;
4440
65
  }
4441
- msg.addInt(0); // out_message_number = out_message_type
4442
- }
4443
66
 
4444
- callback.statement = statement;
4445
- this._queueEvent(callback);
4446
- }
67
+ db.drop(callback);
68
+ });
69
+ };
4447
70
 
4448
- function fetch_blob_async_transaction(statement, id, column, row) {
4449
- const infoValue = { row, column, value: '' };
71
+ exports.create = function(options, callback) {
72
+ var host = options.host || Const.DEFAULT_HOST;
73
+ var port = options.port || Const.DEFAULT_PORT;
74
+ var cnx = this.connection = new Connection(host, port, function(err) {
4450
75
 
4451
- return (transactionArg) => {
4452
- const singleTransaction = transactionArg === undefined;
76
+ var self = cnx;
4453
77
 
4454
- let promiseTransaction;
4455
- if (singleTransaction) {
4456
- promiseTransaction = new Promise((resolve, reject) => {
4457
- statement.connection.startTransaction(ISOLATION_READ_UNCOMMITTED, (err, transaction) => {
4458
- if (err) {
4459
- return reject(err);
4460
- }
4461
- resolve(transaction);
4462
- });
4463
- });
4464
- } else {
4465
- promiseTransaction = Promise.resolve(transactionArg);
78
+ if (err) {
79
+ callback({ error: err, message: "Connect error" });
80
+ return;
4466
81
  }
4467
82
 
4468
- return promiseTransaction.then((transaction) => {
4469
- return new Promise((resolve, reject) => {
4470
- statement.connection._pending.push('openBlob');
4471
- statement.connection.openBlob(id, transaction, (err, blob) => {
4472
-
4473
- if (err) {
4474
- reject(err);
4475
- return;
4476
- }
4477
-
4478
- const read = () => {
4479
- statement.connection.getSegment(blob, (err, ret) => {
4480
-
4481
- if (err) {
4482
- if (singleTransaction) {
4483
- transaction.rollback(() => reject(err));
4484
- } else {
4485
- reject(err);
4486
- }
4487
- return;
4488
- }
4489
-
4490
- if (ret.buffer) {
4491
- const blr = new BlrReader(ret.buffer);
4492
- const data = blr.readSegment();
4493
- infoValue.value += data.toString(DEFAULT_ENCODING);
4494
- }
4495
-
4496
- if (ret.handle !== 2) {
4497
- read();
4498
- return;
4499
- }
4500
-
4501
- statement.connection.closeBlob(blob);
4502
- if (singleTransaction) {
4503
- transaction.commit((err) => {
4504
- if (err) {
4505
- reject(err);
4506
- } else {
4507
- resolve(infoValue);
4508
- }
4509
- });
4510
- } else {
4511
- resolve(infoValue);
4512
- }
4513
- });
4514
- };
4515
-
4516
- read();
4517
- });
4518
- });
4519
- });
4520
- };
4521
- }
4522
-
4523
- function fetch_blob_async(statement, id, name, row) {
4524
- const cbTransaction = (transaction, close, callback) => {
4525
- statement.connection._pending.push('openBlob');
4526
- statement.connection.openBlob(id, transaction, (err, blob) => {
4527
- let e = new Events.EventEmitter();
4528
-
4529
- e.pipe = (stream) => {
4530
- e.on('data', (chunk) => {
4531
- stream.write(chunk);
4532
- });
4533
- e.on('end', () => {
4534
- stream.end();
4535
- });
4536
- };
4537
-
83
+ cnx.connect(options, function(err) {
4538
84
  if (err) {
4539
- return callback(err, name, e, row);
85
+ self.db.emit('error', err);
86
+ doError(err, callback);
87
+ return;
4540
88
  }
4541
89
 
4542
- const read = () => {
4543
- statement.connection.getSegment(blob, (err, ret) => {
4544
-
4545
- if (err) {
4546
- transaction.rollback(() => {
4547
- e.emit('error', err);
4548
- });
4549
- return;
4550
- }
4551
-
4552
- if (ret.buffer) {
4553
- const blr = new BlrReader(ret.buffer);
4554
- const data = blr.readSegment();
4555
-
4556
- e.emit('data', data);
4557
- }
4558
-
4559
- if (ret.handle !== 2) {
4560
- read();
4561
- return;
4562
- }
4563
-
4564
- statement.connection.closeBlob(blob);
4565
- if (close) {
4566
- transaction.commit((err) => {
4567
- if (err) {
4568
- e.emit('error', err);
4569
- } else {
4570
- e.emit('end');
4571
- }
4572
- e = null;
4573
- });
4574
- } else {
4575
- e.emit('end');
4576
- e = null;
4577
- }
4578
- });
4579
- };
4580
-
4581
- callback(err, name, e, row);
4582
- read();
90
+ cnx.createDatabase(options, callback);
4583
91
  });
4584
- };
4585
-
4586
- return (transaction, callback) => {
4587
- // callback(error, nameField, eventEmitter, row)
4588
- const singleTransaction = callback === undefined;
4589
- if (singleTransaction) {
4590
- callback = transaction;
4591
- statement.connection.startTransaction(ISOLATION_READ_UNCOMMITTED, (err, transaction) => {
4592
- if (err) {
4593
- callback(err);
4594
- return;
4595
- }
4596
- cbTransaction(transaction, singleTransaction, callback);
4597
- });
4598
- } else {
4599
- cbTransaction(transaction, singleTransaction, callback);
4600
- }
4601
- };
4602
- }
4603
-
4604
- Connection.prototype.fetch = function(statement, transaction, count, callback) {
4605
-
4606
- var msg = this._msg;
4607
- var blr = this._blr;
4608
-
4609
- msg.pos = 0;
4610
- blr.pos = 0;
4611
-
4612
- if (count instanceof Function) {
4613
- callback = count;
4614
- count = DEFAULT_FETCHSIZE;
4615
- }
4616
-
4617
- msg.addInt(op_fetch);
4618
- msg.addInt(statement.handle);
4619
- CalcBlr(blr, statement.output);
4620
- msg.addBlr(blr);
4621
- msg.addInt(0); // message number
4622
- msg.addInt(count || DEFAULT_FETCHSIZE); // fetch count
4623
-
4624
- callback.statement = statement;
4625
- this._queueEvent(callback);
4626
- };
4627
-
4628
- Connection.prototype.fetchAll = function (statement, transaction, callback) {
4629
- const self = this, data = [];
4630
- const loop = (err, ret) => {
4631
- if (err) {
4632
- return callback(err);
4633
- } else if (ret && ret.data && ret.data.length) {
4634
- const arrPromise = (ret.arrBlob || []).map(value => value(transaction));
4635
-
4636
- Promise.all(arrPromise).then((arrBlob) => {
4637
- for (let i = 0; i < arrBlob.length; i++) {
4638
- const blob = arrBlob[i];
4639
- ret.data[blob.row][blob.column] = blob.value;
4640
- }
4641
-
4642
- const lastIndex = ret.data.length - 1;
4643
- for (let i = 0; i < ret.data.length; i++) {
4644
- const pos = data.push(ret.data[i]);
4645
- if (statement.custom && statement.custom.asStream && statement.custom.on) {
4646
- statement.custom.on(ret.data[i], pos - 1);
4647
- }
4648
- if (i === lastIndex) {
4649
- if (ret.fetched) {
4650
- return callback(undefined, data);
4651
- } else {
4652
- self.fetch(statement, transaction, DEFAULT_FETCHSIZE, loop);
4653
- }
4654
- }
4655
- }
4656
- }).catch(callback);
4657
- } else if (ret.fetched) {
4658
- callback(undefined, data);
4659
- } else {
4660
- self.fetch(statement, transaction, DEFAULT_FETCHSIZE, loop);
4661
- }
4662
- }
4663
-
4664
- this.fetch(statement, transaction, DEFAULT_FETCHSIZE, loop);
4665
- };
4666
-
4667
-
4668
- Connection.prototype.openBlob = function(blob, transaction, callback) {
4669
- var msg = this._msg;
4670
- msg.pos = 0;
4671
- msg.addInt(op_open_blob);
4672
- msg.addInt(transaction.handle);
4673
- msg.addQuad(blob);
4674
- this._queueEvent(callback);
4675
- };
4676
-
4677
- Connection.prototype.closeBlob = function(blob, callback) {
4678
- var msg = this._msg;
4679
- msg.pos = 0;
4680
- msg.addInt(op_close_blob);
4681
- msg.addInt(blob.handle);
4682
- this._queueEvent(callback);
4683
- };
4684
-
4685
- Connection.prototype.getSegment = function(blob, callback) {
4686
- var msg = this._msg;
4687
- msg.pos = 0;
4688
- msg.addInt(op_get_segment);
4689
- msg.addInt(blob.handle);
4690
- msg.addInt(1024); // buffer length
4691
- msg.addInt(0); // ???
4692
- this._queueEvent(callback);
4693
- };
4694
-
4695
- Connection.prototype.createBlob2 = function (transaction, callback) {
4696
- var msg = this._msg;
4697
- msg.pos = 0;
4698
- msg.addInt(op_create_blob2);
4699
- msg.addInt(0);
4700
- msg.addInt(transaction.handle);
4701
- msg.addInt(0);
4702
- msg.addInt(0);
4703
- this._queueEvent(callback);
4704
- };
4705
-
4706
- Connection.prototype.batchSegments = function(blob, buffer, callback){
4707
- var msg = this._msg;
4708
- var blr = this._blr;
4709
- msg.pos = 0;
4710
- blr.pos = 0;
4711
- msg.addInt(op_batch_segments);
4712
- msg.addInt(blob.handle);
4713
- msg.addInt(buffer.length + 2);
4714
- blr.addBuffer(buffer);
4715
- msg.addBlr(blr);
4716
- this._queueEvent(callback);
92
+ }, options);
4717
93
  };
4718
94
 
4719
- Connection.prototype.svcattach = function (options, callback, svc) {
4720
- this._lowercase_keys = options.lowercase_keys || DEFAULT_LOWERCASE_KEYS;
4721
- var database = options.database || options.filename;
4722
- var user = options.user || DEFAULT_USER;
4723
- var password = options.password || DEFAULT_PASSWORD;
4724
- var role = options.role;
4725
- var msg = this._msg;
4726
- var blr = this._blr;
4727
- msg.pos = 0;
4728
- blr.pos = 0;
4729
-
4730
- blr.addBytes([isc_dpb_version2, isc_dpb_version2]);
4731
- blr.addString(isc_dpb_lc_ctype, 'UTF8', DEFAULT_ENCODING);
4732
- blr.addString(isc_dpb_user_name, user, DEFAULT_ENCODING);
4733
- blr.addString(isc_dpb_password, password, DEFAULT_ENCODING);
4734
- blr.addByte(isc_dpb_dummy_packet_interval);
4735
- blr.addByte(4);
4736
- blr.addBytes([120, 10, 0, 0]); // FROM DOT NET PROVIDER
4737
- if (role)
4738
- blr.addString(isc_dpb_sql_role_name, role, DEFAULT_ENCODING);
95
+ exports.attachOrCreate = function(options, callback) {
4739
96
 
4740
- msg.addInt(op_service_attach);
4741
- msg.addInt(0);
4742
- msg.addString(DEFAULT_SVC_NAME, DEFAULT_ENCODING); // only local for moment
4743
- msg.addBlr(this._blr);
97
+ var host = options.host || Const.DEFAULT_HOST;
98
+ var port = options.port || Const.DEFAULT_PORT;
4744
99
 
4745
- var self = this;
100
+ var cnx = this.connection = new Connection(host, port, function(err) {
4746
101
 
4747
- function cb(err, ret) {
102
+ var self = cnx;
4748
103
 
4749
104
  if (err) {
4750
- doError(err, callback);
105
+ callback({ error: err, message: "Connect error" });
4751
106
  return;
4752
107
  }
4753
108
 
4754
- self.svchandle = ret.handle;
4755
- if (callback)
4756
- callback(undefined, ret);
4757
- }
4758
-
4759
- // For reconnect
4760
- if (svc) {
4761
- svc.connection = this;
4762
- cb.response = svc;
4763
- } else {
4764
- cb.response = new ServiceManager(this);
4765
- cb.response.removeAllListeners('error');
4766
- cb.response.on('error', noop);
4767
- }
4768
-
4769
- this._queueEvent(cb);
4770
- }
4771
-
4772
- Connection.prototype.svcstart = function (spbaction, callback) {
4773
- var msg = this._msg;
4774
- var blr = this._blr;
4775
- msg.pos = 0;
4776
- msg.addInt(op_service_start);
4777
- msg.addInt(this.svchandle);
4778
- msg.addInt(0)
4779
- msg.addBlr(spbaction);
4780
- this._queueEvent(callback);
4781
- }
4782
-
4783
- Connection.prototype.svcquery = function (spbquery, resultbuffersize, timeout,callback) {
4784
- if (resultbuffersize > MAX_BUFFER_SIZE) {
4785
- doError(new Error('Buffer is too big'), callback);
4786
- return;
4787
- }
4788
-
4789
- var msg = this._msg;
4790
- var blr = this._blr;
4791
- msg.pos = 0;
4792
- blr.pos = 0;
4793
- blr.addByte(isc_spb_current_version);
4794
- //blr.addByteInt32(isc_info_svc_timeout, timeout);
4795
- msg.addInt(op_service_info);
4796
- msg.addInt(this.svchandle);
4797
- msg.addInt(0)
4798
- msg.addBlr(blr);
4799
- blr.pos = 0
4800
- blr.addBytes(spbquery);
4801
- msg.addBlr(blr);
4802
- msg.addInt(resultbuffersize);
4803
- this._queueEvent(callback);
4804
- }
4805
-
4806
- Connection.prototype.svcdetach = function (callback) {
4807
- var self = this;
4808
-
4809
- if (self._isClosed)
4810
- return;
4811
-
4812
- self._isUsed = false;
4813
- self._isDetach = true;
4814
-
4815
- var msg = self._msg;
4816
-
4817
- msg.pos = 0;
4818
- msg.addInt(op_service_detach);
4819
- msg.addInt(this.svchandle); // Database Object ID
4820
-
4821
- self._queueEvent(function (err, ret) {
4822
- delete (self.svchandle);
4823
- if (callback)
4824
- callback(err, ret);
4825
- });
4826
- }
4827
-
4828
- function bufferReader(buffer, max, writer, cb, beg, end) {
4829
-
4830
- if (!beg)
4831
- beg = 0;
109
+ cnx.connect(options, function(err) {
4832
110
 
4833
- if (!end)
4834
- end = max;
111
+ if (err) {
112
+ doError(err, callback);
113
+ return;
114
+ }
4835
115
 
4836
- if (end >= buffer.length)
4837
- end = undefined;
116
+ cnx.attach(options, function(err, ret) {
4838
117
 
4839
- var b = buffer.slice(beg, end);
118
+ if (!err) {
119
+ if (self.db)
120
+ self.db.emit('connect', ret);
121
+ doCallback(ret, callback);
122
+ return;
123
+ }
4840
124
 
4841
- writer(b, function() {
125
+ cnx.createDatabase(options, callback);
126
+ });
127
+ });
4842
128
 
4843
- if (end === undefined) {
4844
- cb();
4845
- return;
4846
- }
129
+ }, options);
130
+ };
4847
131
 
4848
- bufferReader(buffer, max, writer, cb, beg + max, end + max);
4849
- });
4850
- }
132
+ // Pooling
133
+ exports.pool = function(max, options) {
134
+ return new Pool(exports.attach, max, Object.assign({}, options, { isPool: true }));
135
+ };