node-firebird 2.9.0 → 2.11.0

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.
Files changed (50) hide show
  1. package/README.md +211 -6
  2. package/lib/index.d.ts +5 -0
  3. package/lib/index.js +32 -1
  4. package/lib/pool.js +1 -1
  5. package/lib/srp.d.ts +3 -3
  6. package/lib/types.d.ts +165 -5
  7. package/lib/uri.js +2 -2
  8. package/lib/wire/connection.d.ts +92 -59
  9. package/lib/wire/connection.js +279 -58
  10. package/lib/wire/const.d.ts +9 -1
  11. package/lib/wire/const.js +23 -9
  12. package/lib/wire/database.d.ts +51 -26
  13. package/lib/wire/database.js +53 -20
  14. package/lib/wire/eventConnection.js +5 -3
  15. package/lib/wire/query-stream.d.ts +18 -0
  16. package/lib/wire/query-stream.js +73 -0
  17. package/lib/wire/serialize.d.ts +20 -2
  18. package/lib/wire/serialize.js +7 -0
  19. package/lib/wire/service.d.ts +42 -0
  20. package/lib/wire/service.js +145 -0
  21. package/lib/wire/socket.d.ts +3 -1
  22. package/lib/wire/socket.js +5 -2
  23. package/lib/wire/statement.d.ts +31 -19
  24. package/lib/wire/statement.js +1 -5
  25. package/lib/wire/transaction.d.ts +30 -18
  26. package/lib/wire/transaction.js +23 -4
  27. package/lib/wire/wire-types.d.ts +116 -0
  28. package/lib/wire/wire-types.js +10 -0
  29. package/lib/wire/xsqlvar.d.ts +57 -18
  30. package/lib/wire/xsqlvar.js +59 -0
  31. package/package.json +1 -1
  32. package/src/index.ts +36 -4
  33. package/src/messages.ts +1 -1
  34. package/src/pool.ts +1 -1
  35. package/src/srp.ts +6 -6
  36. package/src/types.ts +162 -5
  37. package/src/unix-crypt.ts +9 -9
  38. package/src/uri.ts +2 -2
  39. package/src/wire/connection.ts +475 -234
  40. package/src/wire/const.ts +23 -9
  41. package/src/wire/database.ts +101 -54
  42. package/src/wire/eventConnection.ts +8 -5
  43. package/src/wire/query-stream.ts +80 -0
  44. package/src/wire/serialize.ts +31 -0
  45. package/src/wire/service.ts +188 -6
  46. package/src/wire/socket.ts +17 -8
  47. package/src/wire/statement.ts +37 -29
  48. package/src/wire/transaction.ts +57 -32
  49. package/src/wire/wire-types.ts +127 -0
  50. package/src/wire/xsqlvar.ts +85 -7
@@ -0,0 +1,127 @@
1
+ /***************************************
2
+ *
3
+ * Internal wire-protocol types (type-only module)
4
+ *
5
+ * Shared vocabulary for the wire core (connection/statement/transaction/
6
+ * database). Nothing here exists at runtime.
7
+ *
8
+ ***************************************/
9
+
10
+ import type { Callback, FbStatusItem } from '../callback';
11
+ import type Statement from './statement';
12
+ import type { BatchResult, Options, QueryOptions, Statement as PublicStatement } from '../types';
13
+
14
+ /**
15
+ * One entry of the connection's response queue (`connection._queue`).
16
+ * The function itself is the user/driver callback; the extra properties
17
+ * steer decodeResponse:
18
+ *
19
+ * - `response` — pre-allocated object the op_response decode fills in
20
+ * (a Statement, Transaction, or plain response object).
21
+ * - `statement` — statement whose `output` describes the rows of an
22
+ * op_fetch_response / op_sql_response.
23
+ * - `lazy_count`— number of chained lazy op_responses this entry consumes
24
+ * (ptype_lazy_send batches e.g. allocate+prepare).
25
+ *
26
+ * Deferred ops (op_free_statement, op_close_blob, ...) push `undefined`
27
+ * placeholders so every server response still pairs with one entry.
28
+ */
29
+ export interface QueueCallback {
30
+ (err?: any, obj?: any): void;
31
+ response?: any;
32
+ statement?: Statement;
33
+ lazy_count?: number;
34
+ }
35
+
36
+ /** A queue entry: a callback, or a placeholder for a deferred op. */
37
+ export type QueueEntry = QueueCallback | undefined;
38
+
39
+ /** XDR quad — 64-bit value as two 32-bit halves (blob ids, object ids). */
40
+ export interface Quad {
41
+ high: number;
42
+ low: number;
43
+ }
44
+
45
+ /**
46
+ * Decoded op_response packet (see parseOpResponse): object handle, object
47
+ * id, optional info buffer and, on failure, the status vector. Statement /
48
+ * Transaction responses are these fields merged onto the pre-allocated
49
+ * object from QueueCallback.response.
50
+ */
51
+ export interface WireResponse {
52
+ handle?: number;
53
+ oid?: Quad;
54
+ buffer?: Buffer;
55
+ status?: FbStatusItem[];
56
+ /** isc_arg_warning entries — attached to a SUCCESSFUL response */
57
+ warnings?: FbStatusItem[];
58
+ sqlcode?: number;
59
+ message?: string;
60
+ }
61
+
62
+ /** Result of decoding op_fetch_response / op_sql_response row data. */
63
+ export interface FetchResult {
64
+ data: any[];
65
+ /** true when the cursor is exhausted (fetch status 100 / singleton). */
66
+ fetched: boolean;
67
+ /** pending blobAsText fetches to resolve before delivering rows. */
68
+ arrBlob?: any[];
69
+ }
70
+
71
+ /**
72
+ * Protocol negotiation result decoded from op_accept / op_cond_accept /
73
+ * op_accept_data, plus the auth/crypt state accumulated during the
74
+ * handshake (op_cont_auth rounds, wire-crypt keys).
75
+ */
76
+ export interface AcceptPacket {
77
+ protocolVersion: number;
78
+ protocolArchitecture: number;
79
+ protocolMinimumType: number;
80
+ compress: boolean;
81
+ pluginName: string;
82
+ authData: any;
83
+ sessionKey?: any;
84
+ [key: string]: any;
85
+ }
86
+
87
+ /**
88
+ * Query options as the wire core sees them: the public QueryOptions plus
89
+ * the internal row-delivery flags set by the Database/Transaction helpers
90
+ * (query / sequentially / queryStream).
91
+ */
92
+ export type InternalQueryOptions = QueryOptions & {
93
+ /** deliver rows as objects keyed by column alias */
94
+ asObject?: boolean;
95
+ /** deliver rows one by one (row events / `on` delegate) instead of accumulating */
96
+ asStream?: boolean;
97
+ /** per-row delegate installed by sequentially() */
98
+ on?: (row: any, index: number, meta: any[], next: (err?: any) => void) => void;
99
+ [key: string]: any;
100
+ };
101
+
102
+ /**
103
+ * newStatement callback: the internal optional-args shape, or the public
104
+ * strict shape (non-optional statement) declared in types.ts.
105
+ */
106
+ export type StatementCb = Callback<Statement> | ((err: Error | null, statement: PublicStatement) => void);
107
+
108
+ /**
109
+ * executeBatch callback: the internal optional-args shape, or the public
110
+ * strict shape (non-optional result) declared in types.ts.
111
+ */
112
+ export type BatchCb = Callback<BatchResult> | ((err: any, result: BatchResult) => void);
113
+
114
+ /**
115
+ * Connection options as the wire core sees them: the public Options plus
116
+ * internal flags set by the driver itself.
117
+ */
118
+ export type InternalOptions = Options & {
119
+ /** set by the pool so detach() returns the connection instead */
120
+ isPool?: boolean;
121
+ /** override path of the firebird.msg error-message file */
122
+ messageFile?: string;
123
+ /** legacy statement-cache flags (mapped onto statementCacheSize) */
124
+ cacheQuery?: boolean;
125
+ maxCachedQuery?: number;
126
+ [key: string]: any;
127
+ };
@@ -26,7 +26,7 @@ const
26
26
  * Commonly used Firebird charsets not listed here fall back to the
27
27
  * connection-level DEFAULT_ENCODING (typically 'utf8').
28
28
  */
29
- const FirebirdToNodeEncoding = Object.freeze({
29
+ const FirebirdToNodeEncoding: Readonly<Record<string, string>> = Object.freeze({
30
30
  UTF8: 'utf8',
31
31
  UNICODE_FSS: 'utf8',
32
32
  WIN1252: 'latin1',
@@ -36,7 +36,7 @@ const FirebirdToNodeEncoding = Object.freeze({
36
36
  NONE: 'latin1', // unspecified charset – treat as binary-safe latin1
37
37
  });
38
38
 
39
- const FirebirdCharsetWidths = {
39
+ const FirebirdCharsetWidths: Record<string, number> = {
40
40
  'UTF8': 4,
41
41
  'UNICODE_FSS': 3,
42
42
  'SJIS': 2,
@@ -71,11 +71,13 @@ function resolveTextEncoding(options?: any): BufferEncoding {
71
71
  * describe response before decode()/calcBlr() are called.
72
72
  */
73
73
  export abstract class SQLVarBase {
74
- type: number;
75
- subType: number;
76
- scale: number;
77
- length: number;
78
- nullable: boolean;
74
+ // populated externally (see the doc comment above), hence the definite
75
+ // assignment assertions
76
+ type!: number;
77
+ subType!: number;
78
+ scale!: number;
79
+ length!: number;
80
+ nullable!: boolean;
79
81
  field?: string;
80
82
  relation?: string;
81
83
  relationSchema?: string;
@@ -91,6 +93,82 @@ export abstract class SQLVarBase {
91
93
 
92
94
  //------------------------------------------------------
93
95
 
96
+ /** Effective object-row key(s) of one output column (see computeColumnKeys). */
97
+ export interface ColumnKey {
98
+ /** Top-level table key when nestTables === true; undefined otherwise. */
99
+ table?: string;
100
+ /** Property key: the column alias, or 'table<sep>alias' in separator mode. */
101
+ key: string;
102
+ }
103
+
104
+ /**
105
+ * Compute the object-row property keys for a statement's output columns,
106
+ * honouring the nestTables and lowercase_keys options. The table qualifier
107
+ * is the query's relation alias when one is used (relationAlias, requested
108
+ * via isc_info_sql_relation_alias), the relation name otherwise, so
109
+ * self-joins nest under their query aliases. Expression columns (no source
110
+ * relation) qualify as '' exactly like mysql2: they nest under the '' key,
111
+ * and in separator mode become '<sep>alias' — always prefixing keeps
112
+ * qualified keys collision-free (a bare expression alias could otherwise
113
+ * collide with a real column's 'table<sep>column' key). Used by the fetch
114
+ * decoder and by fetchBlobSyncRow, which must agree on where each column
115
+ * landed in the row.
116
+ */
117
+ export function computeColumnKeys(
118
+ output: SQLVarBase[],
119
+ nestTables: boolean | string | undefined,
120
+ lowercaseKeys: boolean | undefined
121
+ ): ColumnKey[] {
122
+ return output.map((column) => {
123
+ let key = column.alias || '';
124
+ if (lowercaseKeys) {
125
+ key = key.toLowerCase();
126
+ }
127
+ if (nestTables !== true && typeof nestTables !== 'string') {
128
+ return { key };
129
+ }
130
+ let table = column.relationAlias || column.relation || '';
131
+ if (lowercaseKeys) {
132
+ table = table.toLowerCase();
133
+ }
134
+ if (nestTables === true) {
135
+ return { table, key };
136
+ }
137
+ return { key: table + nestTables + key };
138
+ });
139
+ }
140
+
141
+ /**
142
+ * Resolve the effective nestTables value: the per-query option wins over
143
+ * the connection option. The decoder and fetchBlobSyncRow both use this —
144
+ * they must agree on whether nesting is active or blob cells are looked
145
+ * up in the wrong place.
146
+ */
147
+ export function resolveNestTables(
148
+ queryOptions: { nestTables?: boolean | string } | undefined,
149
+ connectionOptions: { nestTables?: boolean | string } | undefined
150
+ ): boolean | string | undefined {
151
+ if (queryOptions && queryOptions.nestTables !== undefined) {
152
+ return queryOptions.nestTables;
153
+ }
154
+ return connectionOptions && connectionOptions.nestTables;
155
+ }
156
+
157
+ /**
158
+ * The object a column's value lives in: the row itself, or — when the
159
+ * column carries a nestTables table qualifier — the row's per-table
160
+ * sub-object, created on first use. Every site that reads or writes a
161
+ * cell by ColumnKey must resolve it through here.
162
+ */
163
+ export function nestCell(row: any, table: string | undefined) {
164
+ if (table === undefined) {
165
+ return row;
166
+ }
167
+ return row[table] || (row[table] = {});
168
+ }
169
+
170
+ //------------------------------------------------------
171
+
94
172
  export class SQLVarText extends SQLVarBase {
95
173
  decode(data: XdrReader, lowerV13: boolean, options?: any) {
96
174
  let ret;