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/.github/workflows/node.js.yml +3 -3
- package/README.md +258 -267
- package/lib/callback.js +38 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +86 -4801
- package/lib/pool.js +107 -0
- package/lib/utils.js +164 -0
- package/lib/wire/connection.js +1965 -0
- package/lib/wire/const.js +772 -0
- package/lib/wire/database.js +198 -0
- package/lib/wire/eventConnection.js +113 -0
- package/lib/wire/fbEventManager.js +98 -0
- package/lib/{serialize.js → wire/serialize.js} +24 -1
- package/lib/wire/service.js +1046 -0
- package/lib/wire/statement.js +47 -0
- package/lib/wire/transaction.js +160 -0
- package/lib/wire/xsqlvar.js +518 -0
- package/package.json +4 -9
package/lib/index.js
CHANGED
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
3832
|
-
|
|
17
|
+
exports.WIRE_CRYPT_DISABLE = Const.WIRE_CRYPT_DISABLE;
|
|
18
|
+
exports.WIRE_CRYPT_ENABLE = Const.WIRE_CRYPT_ENABLE;
|
|
3833
19
|
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
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
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
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
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
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
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
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
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
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
|
-
|
|
4372
|
-
}
|
|
4373
|
-
|
|
4374
|
-
this.sendExecute(op, statement, transaction, callback);
|
|
57
|
+
}, options);
|
|
4375
58
|
};
|
|
4376
59
|
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
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
|
-
|
|
4445
|
-
|
|
4446
|
-
}
|
|
67
|
+
db.drop(callback);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
4447
70
|
|
|
4448
|
-
function
|
|
4449
|
-
|
|
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
|
-
|
|
4452
|
-
const singleTransaction = transactionArg === undefined;
|
|
76
|
+
var self = cnx;
|
|
4453
77
|
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
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
|
-
|
|
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
|
-
|
|
85
|
+
self.db.emit('error', err);
|
|
86
|
+
doError(err, callback);
|
|
87
|
+
return;
|
|
4540
88
|
}
|
|
4541
89
|
|
|
4542
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4741
|
-
|
|
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
|
|
100
|
+
var cnx = this.connection = new Connection(host, port, function(err) {
|
|
4746
101
|
|
|
4747
|
-
|
|
102
|
+
var self = cnx;
|
|
4748
103
|
|
|
4749
104
|
if (err) {
|
|
4750
|
-
|
|
105
|
+
callback({ error: err, message: "Connect error" });
|
|
4751
106
|
return;
|
|
4752
107
|
}
|
|
4753
108
|
|
|
4754
|
-
|
|
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
|
-
|
|
4834
|
-
|
|
111
|
+
if (err) {
|
|
112
|
+
doError(err, callback);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
4835
115
|
|
|
4836
|
-
|
|
4837
|
-
end = undefined;
|
|
116
|
+
cnx.attach(options, function(err, ret) {
|
|
4838
117
|
|
|
4839
|
-
|
|
118
|
+
if (!err) {
|
|
119
|
+
if (self.db)
|
|
120
|
+
self.db.emit('connect', ret);
|
|
121
|
+
doCallback(ret, callback);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
4840
124
|
|
|
4841
|
-
|
|
125
|
+
cnx.createDatabase(options, callback);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
4842
128
|
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
return;
|
|
4846
|
-
}
|
|
129
|
+
}, options);
|
|
130
|
+
};
|
|
4847
131
|
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
}
|
|
132
|
+
// Pooling
|
|
133
|
+
exports.pool = function(max, options) {
|
|
134
|
+
return new Pool(exports.attach, max, Object.assign({}, options, { isPool: true }));
|
|
135
|
+
};
|