@ragestudio/scylla-odm 0.22.2 → 0.22.4
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/batch/index.d.ts +3 -3
- package/batch/index.d.ts.map +1 -1
- package/client.d.ts +6 -5
- package/client.d.ts.map +1 -1
- package/client.js +11 -12
- package/client.js.map +1 -1
- package/cql_gen/create_table.d.ts +1 -1
- package/cql_gen/create_table.d.ts.map +1 -1
- package/document/index.d.ts +3 -3
- package/document/index.d.ts.map +1 -1
- package/driver/LICENSE.txt +177 -0
- package/driver/NOTICE.txt +67 -0
- package/driver/auth/index.d.ts +37 -0
- package/driver/auth/index.js +37 -0
- package/driver/auth/no-auth-provider.js +73 -0
- package/driver/auth/plain-text-auth-provider.js +81 -0
- package/driver/auth/provider.js +77 -0
- package/driver/client-options.js +442 -0
- package/driver/client.js +1267 -0
- package/driver/concurrent/index.d.ts +49 -0
- package/driver/concurrent/index.js +366 -0
- package/driver/connection.js +1034 -0
- package/driver/control-connection.js +1282 -0
- package/driver/encoder.js +2316 -0
- package/driver/errors.js +223 -0
- package/driver/execution-options.js +612 -0
- package/driver/execution-profile.js +274 -0
- package/driver/host-connection-pool.js +587 -0
- package/driver/host.js +699 -0
- package/driver/index.d.ts +387 -0
- package/driver/index.js +81 -0
- package/driver/mapping/cache.js +214 -0
- package/driver/mapping/doc-info-adapter.js +171 -0
- package/driver/mapping/index.d.ts +219 -0
- package/driver/mapping/index.js +57 -0
- package/driver/mapping/mapper.js +225 -0
- package/driver/mapping/mapping-handler.js +641 -0
- package/driver/mapping/model-batch-item.js +215 -0
- package/driver/mapping/model-batch-mapper.js +141 -0
- package/driver/mapping/model-mapper.js +315 -0
- package/driver/mapping/model-mapping-info.js +225 -0
- package/driver/mapping/object-selector.js +417 -0
- package/driver/mapping/q.js +156 -0
- package/driver/mapping/query-generator.js +556 -0
- package/driver/mapping/result-mapper.js +123 -0
- package/driver/mapping/result.js +139 -0
- package/driver/mapping/table-mappings.js +133 -0
- package/driver/mapping/tree.js +160 -0
- package/driver/metadata/aggregate.js +79 -0
- package/driver/metadata/client-state.js +119 -0
- package/driver/metadata/data-collection.js +182 -0
- package/driver/metadata/event-debouncer.js +174 -0
- package/driver/metadata/index.d.ts +276 -0
- package/driver/metadata/index.js +1156 -0
- package/driver/metadata/materialized-view.js +49 -0
- package/driver/metadata/schema-function.js +98 -0
- package/driver/metadata/schema-index.js +166 -0
- package/driver/metadata/schema-parser.js +1399 -0
- package/driver/metadata/table-metadata.js +77 -0
- package/driver/operation-state.js +206 -0
- package/driver/policies/address-resolution.js +145 -0
- package/driver/policies/index.d.ts +241 -0
- package/driver/policies/index.js +110 -0
- package/driver/policies/load-balancing.js +970 -0
- package/driver/policies/reconnection.js +166 -0
- package/driver/policies/retry.js +326 -0
- package/driver/policies/speculative-execution.js +150 -0
- package/driver/policies/timestamp-generation.js +176 -0
- package/driver/prepare-handler.js +347 -0
- package/driver/promise-utils.js +191 -0
- package/driver/readers.js +624 -0
- package/driver/request-execution.js +644 -0
- package/driver/request-handler.js +332 -0
- package/driver/requests.js +618 -0
- package/driver/stream-id-stack.js +209 -0
- package/driver/streams.js +745 -0
- package/driver/token.js +325 -0
- package/driver/tokenizer.js +631 -0
- package/driver/types/big-decimal.js +282 -0
- package/driver/types/duration.js +576 -0
- package/driver/types/index.d.ts +486 -0
- package/driver/types/index.js +733 -0
- package/driver/types/inet-address.js +262 -0
- package/driver/types/integer.js +818 -0
- package/driver/types/local-date.js +280 -0
- package/driver/types/local-time.js +299 -0
- package/driver/types/mutable-long.js +385 -0
- package/driver/types/protocol-version.js +391 -0
- package/driver/types/result-set.js +287 -0
- package/driver/types/result-stream.js +164 -0
- package/driver/types/row.js +85 -0
- package/driver/types/time-uuid.js +414 -0
- package/driver/types/tuple.js +103 -0
- package/driver/types/uuid.js +160 -0
- package/driver/types/vector.js +130 -0
- package/driver/types/version-number.js +153 -0
- package/driver/utils.js +1485 -0
- package/driver/writers.js +350 -0
- package/global.d.ts +1 -1
- package/global.d.ts.map +1 -1
- package/index.d.ts +6 -6
- package/index.d.ts.map +1 -1
- package/index.js +6 -6
- package/index.js.map +1 -1
- package/migrate/index.d.ts +1 -1
- package/migrate/index.d.ts.map +1 -1
- package/migrate/index.js +1 -1
- package/migrate/index.js.map +1 -1
- package/model/index.d.ts +6 -6
- package/model/index.d.ts.map +1 -1
- package/model/index.js +10 -10
- package/model/index.js.map +1 -1
- package/operations/countAll.d.ts +1 -1
- package/operations/countAll.d.ts.map +1 -1
- package/operations/delete.d.ts +3 -4
- package/operations/delete.d.ts.map +1 -1
- package/operations/delete.js +1 -1
- package/operations/delete.js.map +1 -1
- package/operations/find.d.ts +2 -2
- package/operations/find.d.ts.map +1 -1
- package/operations/find.js +1 -1
- package/operations/find.js.map +1 -1
- package/operations/findOne.d.ts +2 -2
- package/operations/findOne.d.ts.map +1 -1
- package/operations/findOne.js +1 -1
- package/operations/findOne.js.map +1 -1
- package/operations/insert.d.ts +3 -3
- package/operations/insert.d.ts.map +1 -1
- package/operations/insert.js +2 -2
- package/operations/insert.js.map +1 -1
- package/operations/sync.d.ts +1 -1
- package/operations/sync.d.ts.map +1 -1
- package/operations/sync.js +1 -1
- package/operations/sync.js.map +1 -1
- package/operations/tableExists.d.ts +1 -1
- package/operations/tableExists.d.ts.map +1 -1
- package/operations/update.d.ts +3 -3
- package/operations/update.d.ts.map +1 -1
- package/operations/update.js +2 -2
- package/operations/update.js.map +1 -1
- package/package.json +4 -12
- package/schema/index.d.ts +1 -1
- package/schema/index.d.ts.map +1 -1
- package/types.d.ts +4 -4
- package/types.d.ts.map +1 -1
- package/utils/queryParser.d.ts +1 -1
- package/utils/queryParser.d.ts.map +1 -1
- package/utils/queryParser.js +1 -1
- package/utils/queryParser.js.map +1 -1
- package/utils/typeChecker.d.ts +1 -1
- package/utils/typeChecker.d.ts.map +1 -1
- package/utils/typeChecker.js +1 -1
- package/utils/typeChecker.js.map +1 -1
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import utils from "../utils.js"
|
|
20
|
+
import VersionNumber from "./version-number.js"
|
|
21
|
+
|
|
22
|
+
const v200 = VersionNumber.parse("2.0.0")
|
|
23
|
+
const v210 = VersionNumber.parse("2.1.0")
|
|
24
|
+
const v220 = VersionNumber.parse("2.2.0")
|
|
25
|
+
const v300 = VersionNumber.parse("3.0.0")
|
|
26
|
+
const v510 = VersionNumber.parse("5.1.0")
|
|
27
|
+
const v600 = VersionNumber.parse("6.0.0")
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Contains information for the different protocol versions supported by the driver.
|
|
31
|
+
* @type {Object}
|
|
32
|
+
* @property {Number} v1 Cassandra protocol v1, supported in Apache Cassandra 1.2-->2.2.
|
|
33
|
+
* @property {Number} v2 Cassandra protocol v2, supported in Apache Cassandra 2.0-->2.2.
|
|
34
|
+
* @property {Number} v3 Cassandra protocol v3, supported in Apache Cassandra 2.1-->3.x.
|
|
35
|
+
* @property {Number} v4 Cassandra protocol v4, supported in Apache Cassandra 2.2-->3.x.
|
|
36
|
+
* @property {Number} v5 Cassandra protocol v5, in beta from Apache Cassandra 3.x+. Currently not supported by the
|
|
37
|
+
* driver.
|
|
38
|
+
* @property {Number} dseV1 DataStax Enterprise protocol v1, DSE 5.1+
|
|
39
|
+
* @property {Number} dseV2 DataStax Enterprise protocol v2, DSE 6.0+
|
|
40
|
+
* @property {Number} maxSupported Returns the higher protocol version that is supported by this driver.
|
|
41
|
+
* @property {Number} minSupported Returns the lower protocol version that is supported by this driver.
|
|
42
|
+
* @property {Function} isSupported A function that returns a boolean determining whether a given protocol version
|
|
43
|
+
* is supported.
|
|
44
|
+
* @alias module:types~protocolVersion
|
|
45
|
+
*/
|
|
46
|
+
const protocolVersion = {
|
|
47
|
+
// Strict equality operators to compare versions are allowed, other comparison operators are discouraged. Instead,
|
|
48
|
+
// use a function that checks if a functionality is present on a certain version, for maintainability purposes.
|
|
49
|
+
v1: 0x01,
|
|
50
|
+
v2: 0x02,
|
|
51
|
+
v3: 0x03,
|
|
52
|
+
v4: 0x04,
|
|
53
|
+
v5: 0x05,
|
|
54
|
+
v6: 0x06,
|
|
55
|
+
dseV1: 0x41,
|
|
56
|
+
dseV2: 0x42,
|
|
57
|
+
maxSupported: 0x42,
|
|
58
|
+
minSupported: 0x01,
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Determines whether the protocol version is a DSE-specific protocol version.
|
|
62
|
+
* @param {Number} version
|
|
63
|
+
* @returns {Boolean}
|
|
64
|
+
* @ignore
|
|
65
|
+
*/
|
|
66
|
+
isDse: function (version) {
|
|
67
|
+
return version >= this.dseV1 && version <= this.dseV2
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Returns true if the protocol version represents a version of Cassandra
|
|
71
|
+
* supported by this driver, false otherwise
|
|
72
|
+
* @param {Number} version
|
|
73
|
+
* @returns {Boolean}
|
|
74
|
+
* @ignore
|
|
75
|
+
*/
|
|
76
|
+
isSupportedCassandra: function (version) {
|
|
77
|
+
return version <= 0x04 && version >= 0x01
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Determines whether the protocol version is supported by this driver.
|
|
81
|
+
* @param {Number} version
|
|
82
|
+
* @returns {Boolean}
|
|
83
|
+
* @ignore
|
|
84
|
+
*/
|
|
85
|
+
isSupported: function (version) {
|
|
86
|
+
return this.isDse(version) || this.isSupportedCassandra(version)
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Determines whether the protocol includes flags for PREPARE messages.
|
|
91
|
+
* @param {Number} version
|
|
92
|
+
* @returns {Boolean}
|
|
93
|
+
* @ignore
|
|
94
|
+
*/
|
|
95
|
+
supportsPrepareFlags: function (version) {
|
|
96
|
+
return version === this.dseV2
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Determines whether the protocol supports sending the keyspace as part of PREPARE, QUERY, EXECUTE, and BATCH.
|
|
100
|
+
* @param {Number} version
|
|
101
|
+
* @returns {Boolean}
|
|
102
|
+
* @ignore
|
|
103
|
+
*/
|
|
104
|
+
supportsKeyspaceInRequest: function (version) {
|
|
105
|
+
return version === this.dseV2
|
|
106
|
+
},
|
|
107
|
+
/**
|
|
108
|
+
* Determines whether the protocol supports result_metadata_id on `prepared` response and
|
|
109
|
+
* and `execute` request.
|
|
110
|
+
* @param {Number} version
|
|
111
|
+
* @returns {Boolean}
|
|
112
|
+
* @ignore
|
|
113
|
+
*/
|
|
114
|
+
supportsResultMetadataId: function (version) {
|
|
115
|
+
return version === this.dseV2
|
|
116
|
+
},
|
|
117
|
+
/**
|
|
118
|
+
* Determines whether the protocol supports partition key indexes in the `prepared` RESULT responses.
|
|
119
|
+
* @param {Number} version
|
|
120
|
+
* @returns {Boolean}
|
|
121
|
+
* @ignore
|
|
122
|
+
*/
|
|
123
|
+
supportsPreparedPartitionKey: function (version) {
|
|
124
|
+
return version >= this.v4
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* Determines whether the protocol supports up to 4 strings (ie: change_type, target, keyspace and table) in the
|
|
128
|
+
* schema change responses.
|
|
129
|
+
* @param version
|
|
130
|
+
* @return {boolean}
|
|
131
|
+
* @ignore
|
|
132
|
+
*/
|
|
133
|
+
supportsSchemaChangeFullMetadata: function (version) {
|
|
134
|
+
return version >= this.v3
|
|
135
|
+
},
|
|
136
|
+
/**
|
|
137
|
+
* Determines whether the protocol supports continuous paging.
|
|
138
|
+
* @param version
|
|
139
|
+
* @return {boolean}
|
|
140
|
+
* @ignore
|
|
141
|
+
*/
|
|
142
|
+
supportsContinuousPaging: function (version) {
|
|
143
|
+
return this.isDse(version)
|
|
144
|
+
},
|
|
145
|
+
/**
|
|
146
|
+
* Determines whether the protocol supports paging state and serial consistency parameters in QUERY and EXECUTE
|
|
147
|
+
* requests.
|
|
148
|
+
* @param version
|
|
149
|
+
* @return {boolean}
|
|
150
|
+
* @ignore
|
|
151
|
+
*/
|
|
152
|
+
supportsPaging: function (version) {
|
|
153
|
+
return version >= this.v2
|
|
154
|
+
},
|
|
155
|
+
/**
|
|
156
|
+
* Determines whether the protocol supports timestamps parameters in BATCH, QUERY and EXECUTE requests.
|
|
157
|
+
* @param {Number} version
|
|
158
|
+
* @return {boolean}
|
|
159
|
+
* @ignore
|
|
160
|
+
*/
|
|
161
|
+
supportsTimestamp: function (version) {
|
|
162
|
+
return version >= this.v3
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* Determines whether the protocol supports named parameters in QUERY and EXECUTE requests.
|
|
166
|
+
* @param {Number} version
|
|
167
|
+
* @return {boolean}
|
|
168
|
+
* @ignore
|
|
169
|
+
*/
|
|
170
|
+
supportsNamedParameters: function (version) {
|
|
171
|
+
return version >= this.v3
|
|
172
|
+
},
|
|
173
|
+
/**
|
|
174
|
+
* Determines whether the protocol supports unset parameters.
|
|
175
|
+
* @param {Number} version
|
|
176
|
+
* @return {boolean}
|
|
177
|
+
* @ignore
|
|
178
|
+
*/
|
|
179
|
+
supportsUnset: function (version) {
|
|
180
|
+
return version >= this.v4
|
|
181
|
+
},
|
|
182
|
+
/**
|
|
183
|
+
* Determines whether the protocol provides a reason map for read and write failure errors.
|
|
184
|
+
* @param version
|
|
185
|
+
* @return {boolean}
|
|
186
|
+
* @ignore
|
|
187
|
+
*/
|
|
188
|
+
supportsFailureReasonMap: function (version) {
|
|
189
|
+
return version >= this.v5
|
|
190
|
+
},
|
|
191
|
+
/**
|
|
192
|
+
* Determines whether the protocol supports timestamp and serial consistency parameters in BATCH requests.
|
|
193
|
+
* @param {Number} version
|
|
194
|
+
* @return {boolean}
|
|
195
|
+
* @ignore
|
|
196
|
+
*/
|
|
197
|
+
uses2BytesStreamIds: function (version) {
|
|
198
|
+
return version >= this.v3
|
|
199
|
+
},
|
|
200
|
+
/**
|
|
201
|
+
* Determines whether the collection length is encoded using 32 bits.
|
|
202
|
+
* @param {Number} version
|
|
203
|
+
* @return {boolean}
|
|
204
|
+
* @ignore
|
|
205
|
+
*/
|
|
206
|
+
uses4BytesCollectionLength: function (version) {
|
|
207
|
+
return version >= this.v3
|
|
208
|
+
},
|
|
209
|
+
/**
|
|
210
|
+
* Determines whether the QUERY, EXECUTE and BATCH flags are encoded using 32 bits.
|
|
211
|
+
* @param {Number} version
|
|
212
|
+
* @return {boolean}
|
|
213
|
+
* @ignore
|
|
214
|
+
*/
|
|
215
|
+
uses4BytesQueryFlags: function (version) {
|
|
216
|
+
return this.isDse(version)
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* Startup responses using protocol v4+ can be a SERVER_ERROR wrapping a ProtocolException, this method returns true
|
|
220
|
+
* when is possible to receive such error.
|
|
221
|
+
* @param {Number} version
|
|
222
|
+
* @return {boolean}
|
|
223
|
+
* @ignore
|
|
224
|
+
*/
|
|
225
|
+
canStartupResponseErrorBeWrapped: function (version) {
|
|
226
|
+
return version >= this.v4
|
|
227
|
+
},
|
|
228
|
+
/**
|
|
229
|
+
* Gets the first version number that is supported, lower than the one provided.
|
|
230
|
+
* Returns zero when there isn't a lower supported version.
|
|
231
|
+
* @param {Number} version
|
|
232
|
+
* @return {Number}
|
|
233
|
+
* @ignore
|
|
234
|
+
*/
|
|
235
|
+
getLowerSupported: function (version) {
|
|
236
|
+
if (version >= this.v5) {
|
|
237
|
+
return this.v4
|
|
238
|
+
}
|
|
239
|
+
if (version <= this.v1) {
|
|
240
|
+
return 0
|
|
241
|
+
}
|
|
242
|
+
return version - 1
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Computes the highest supported protocol version collectively by the given hosts.
|
|
247
|
+
*
|
|
248
|
+
* Considers the cassandra_version of the input hosts to determine what protocol versions
|
|
249
|
+
* are supported and uses the highest common protocol version among them.
|
|
250
|
+
*
|
|
251
|
+
* If hosts >= C* 3.0 are detected, any hosts older than C* 2.1 will not be considered
|
|
252
|
+
* as those cannot be connected to. In general this will not be a problem as C* does
|
|
253
|
+
* not support clusters with nodes that have versions that are more than one major
|
|
254
|
+
* version away from each other.
|
|
255
|
+
* @param {Connection} connection Connection hosts were discovered from.
|
|
256
|
+
* @param {Array.<Host>} hosts The hosts to determine highest protocol version from.
|
|
257
|
+
* @return {Number} Highest supported protocol version among hosts.
|
|
258
|
+
*/
|
|
259
|
+
getHighestCommon: function (connection, hosts) {
|
|
260
|
+
const log = connection.log
|
|
261
|
+
? connection.log.bind(connection)
|
|
262
|
+
: utils.noop
|
|
263
|
+
let maxVersion = connection.protocolVersion
|
|
264
|
+
// whether or not protocol v3 is required (nodes detected that don't support < 3).
|
|
265
|
+
let v3Requirement = false
|
|
266
|
+
// track the common protocol version >= v3 in case we encounter older versions.
|
|
267
|
+
let maxVersionWith3OrMore = maxVersion
|
|
268
|
+
hosts.forEach((h) => {
|
|
269
|
+
let dseVersion = null
|
|
270
|
+
if (h.dseVersion) {
|
|
271
|
+
// As of DSE 5.1, DSE has it's own specific protocol versions. If we detect 5.1+
|
|
272
|
+
// consider those protocol versions.
|
|
273
|
+
dseVersion = VersionNumber.parse(h.dseVersion)
|
|
274
|
+
log(
|
|
275
|
+
"verbose",
|
|
276
|
+
`Encountered host ${h.address} with dse version ${dseVersion}`,
|
|
277
|
+
)
|
|
278
|
+
if (dseVersion.compare(v510) >= 0) {
|
|
279
|
+
v3Requirement = true
|
|
280
|
+
if (dseVersion.compare(v600) >= 0) {
|
|
281
|
+
maxVersion = Math.min(this.dseV2, maxVersion)
|
|
282
|
+
} else {
|
|
283
|
+
maxVersion = Math.min(this.dseV1, maxVersion)
|
|
284
|
+
}
|
|
285
|
+
maxVersionWith3OrMore = maxVersion
|
|
286
|
+
return
|
|
287
|
+
}
|
|
288
|
+
// If DSE < 5.1, we fall back on the cassandra protocol logic.
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (!h.cassandraVersion || h.cassandraVersion.length === 0) {
|
|
292
|
+
log(
|
|
293
|
+
"warning",
|
|
294
|
+
"Encountered host " +
|
|
295
|
+
h.address +
|
|
296
|
+
" with no cassandra version," +
|
|
297
|
+
" skipping as part of protocol version evaluation",
|
|
298
|
+
)
|
|
299
|
+
return
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
const cassandraVersion = VersionNumber.parse(h.cassandraVersion)
|
|
304
|
+
if (!dseVersion) {
|
|
305
|
+
log(
|
|
306
|
+
"verbose",
|
|
307
|
+
"Encountered host " +
|
|
308
|
+
h.address +
|
|
309
|
+
" with cassandra version " +
|
|
310
|
+
cassandraVersion,
|
|
311
|
+
)
|
|
312
|
+
}
|
|
313
|
+
if (cassandraVersion.compare(v300) >= 0) {
|
|
314
|
+
// Anything 3.0.0+ has a max protocol version of V4 and requires at least V3.
|
|
315
|
+
v3Requirement = true
|
|
316
|
+
maxVersion = Math.min(this.v4, maxVersion)
|
|
317
|
+
maxVersionWith3OrMore = maxVersion
|
|
318
|
+
} else if (cassandraVersion.compare(v220) >= 0) {
|
|
319
|
+
// Cassandra 2.2.x has a max protocol version of V4.
|
|
320
|
+
maxVersion = Math.min(this.v4, maxVersion)
|
|
321
|
+
maxVersionWith3OrMore = maxVersion
|
|
322
|
+
} else if (cassandraVersion.compare(v210) >= 0) {
|
|
323
|
+
// Cassandra 2.1.x has a max protocol version of V3.
|
|
324
|
+
maxVersion = Math.min(this.v3, maxVersion)
|
|
325
|
+
maxVersionWith3OrMore = maxVersion
|
|
326
|
+
} else if (cassandraVersion.compare(v200) >= 0) {
|
|
327
|
+
// Cassandra 2.0.x has a max protocol version of V2.
|
|
328
|
+
maxVersion = Math.min(this.v2, maxVersion)
|
|
329
|
+
} else {
|
|
330
|
+
// Anything else is < 2.x and requires protocol version V1.
|
|
331
|
+
maxVersion = this.v1
|
|
332
|
+
}
|
|
333
|
+
} catch (e) {
|
|
334
|
+
log(
|
|
335
|
+
"warning",
|
|
336
|
+
"Encountered host " +
|
|
337
|
+
h.address +
|
|
338
|
+
" with unparseable cassandra version " +
|
|
339
|
+
h.cassandraVersion +
|
|
340
|
+
" skipping as part of protocol version evaluation",
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
if (v3Requirement && maxVersion < this.v3) {
|
|
346
|
+
const addendum =
|
|
347
|
+
". This should not be possible as nodes within a cluster can't be separated by more than one major version"
|
|
348
|
+
if (maxVersionWith3OrMore < this.v3) {
|
|
349
|
+
log(
|
|
350
|
+
"error",
|
|
351
|
+
"Detected hosts that require at least protocol version 0x3, but currently connected to " +
|
|
352
|
+
connection.address +
|
|
353
|
+
":" +
|
|
354
|
+
connection.port +
|
|
355
|
+
" using protocol version 0x" +
|
|
356
|
+
maxVersionWith3OrMore +
|
|
357
|
+
". Will not be able to connect to these hosts" +
|
|
358
|
+
addendum,
|
|
359
|
+
)
|
|
360
|
+
} else {
|
|
361
|
+
log(
|
|
362
|
+
"error",
|
|
363
|
+
"Detected hosts with maximum protocol version of 0x" +
|
|
364
|
+
maxVersion.toString(16) +
|
|
365
|
+
" but there are some hosts that require at least version 0x3. Will not be able to connect to these older hosts" +
|
|
366
|
+
addendum,
|
|
367
|
+
)
|
|
368
|
+
}
|
|
369
|
+
maxVersion = maxVersionWith3OrMore
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
log(
|
|
373
|
+
"verbose",
|
|
374
|
+
"Resolved protocol version 0x" +
|
|
375
|
+
maxVersion.toString(16) +
|
|
376
|
+
" as the highest common protocol version among hosts",
|
|
377
|
+
)
|
|
378
|
+
return maxVersion
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Determines if the protocol is a BETA version of the protocol.
|
|
383
|
+
* @param {Number} version
|
|
384
|
+
* @return {Number}
|
|
385
|
+
*/
|
|
386
|
+
isBeta: function (version) {
|
|
387
|
+
return version === this.v5
|
|
388
|
+
},
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export default protocolVersion
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import utils from "../utils.js"
|
|
20
|
+
import errors from "../errors.js"
|
|
21
|
+
|
|
22
|
+
const asyncIteratorSymbol = Symbol.asyncIterator || "@@asyncIterator"
|
|
23
|
+
|
|
24
|
+
/** @module types */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new instance of ResultSet.
|
|
28
|
+
* @class
|
|
29
|
+
* @classdesc Represents the result of a query.
|
|
30
|
+
* @param {Object} response
|
|
31
|
+
* @param {String} host
|
|
32
|
+
* @param {Object} triedHosts
|
|
33
|
+
* @param {Number} speculativeExecutions
|
|
34
|
+
* @param {Number} consistency
|
|
35
|
+
* @param {Boolean} isSchemaInAgreement
|
|
36
|
+
* @constructor
|
|
37
|
+
*/
|
|
38
|
+
function ResultSet(
|
|
39
|
+
response,
|
|
40
|
+
host,
|
|
41
|
+
triedHosts,
|
|
42
|
+
speculativeExecutions,
|
|
43
|
+
consistency,
|
|
44
|
+
isSchemaInAgreement,
|
|
45
|
+
) {
|
|
46
|
+
// if no execution was made at all, set to 0.
|
|
47
|
+
if (speculativeExecutions === -1) {
|
|
48
|
+
speculativeExecutions = 0
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Information on the execution of a successful query:
|
|
52
|
+
* @member {Object}
|
|
53
|
+
* @property {Number} achievedConsistency The consistency level that has been actually achieved by the query.
|
|
54
|
+
* @property {String} queriedHost The Cassandra host that coordinated this query.
|
|
55
|
+
* @property {Object} triedHosts Gets the associative array of host that were queried before getting a valid response,
|
|
56
|
+
* being the last host the one that replied correctly.
|
|
57
|
+
* @property {Object} speculativeExecutions The number of speculative executions (not including the first) executed before
|
|
58
|
+
* getting a valid response.
|
|
59
|
+
* @property {Uuid} traceId Identifier of the trace session.
|
|
60
|
+
* @property {Array.<string>} warnings Warning messages generated by the server when executing the query.
|
|
61
|
+
* @property {Boolean} isSchemaInAgreement Whether the cluster had reached schema agreement after the execution of
|
|
62
|
+
* this query.
|
|
63
|
+
* <p>
|
|
64
|
+
* After a successful schema-altering query (ex: creating a table), the driver will check if
|
|
65
|
+
* the cluster's nodes agree on the new schema version. If not, it will keep retrying for a given
|
|
66
|
+
* delay (see <code>protocolOptions.maxSchemaAgreementWaitSeconds</code>).
|
|
67
|
+
* </p>
|
|
68
|
+
* <p>
|
|
69
|
+
* Note that the schema agreement check is only performed for schema-altering queries For other
|
|
70
|
+
* query types, this method will always return <code>true</code>. If this method returns <code>false</code>,
|
|
71
|
+
* clients can call [Metadata.checkSchemaAgreement()]{@link module:metadata~Metadata#checkSchemaAgreement} later to
|
|
72
|
+
* perform the check manually.
|
|
73
|
+
* </p>
|
|
74
|
+
*/
|
|
75
|
+
this.info = {
|
|
76
|
+
queriedHost: host,
|
|
77
|
+
triedHosts: triedHosts,
|
|
78
|
+
speculativeExecutions: speculativeExecutions,
|
|
79
|
+
achievedConsistency: consistency,
|
|
80
|
+
traceId: null,
|
|
81
|
+
warnings: null,
|
|
82
|
+
customPayload: null,
|
|
83
|
+
isSchemaInAgreement,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (response.flags) {
|
|
87
|
+
this.info.traceId = response.flags.traceId
|
|
88
|
+
this.info.warnings = response.flags.warnings
|
|
89
|
+
this.info.customPayload = response.flags.customPayload
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Gets an array rows returned by the query.
|
|
94
|
+
* When the result set represents a response from a write query, this property will be <code>undefined</code>.
|
|
95
|
+
* When the read query result contains more rows than the fetch size (5000), this property will only contain the
|
|
96
|
+
* first rows up to fetch size. To obtain all the rows, you can use the built-in async iterator that will retrieve the
|
|
97
|
+
* following pages of results.
|
|
98
|
+
* @type {Array<Row>|undefined}
|
|
99
|
+
*/
|
|
100
|
+
this.rows = response.rows
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Gets the row length of the result, regardless if the result has been buffered or not
|
|
104
|
+
* @type {Number|undefined}
|
|
105
|
+
*/
|
|
106
|
+
this.rowLength = this.rows ? this.rows.length : response.rowLength
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Gets the columns returned in this ResultSet.
|
|
110
|
+
* @type {Array.<{name, type}>}
|
|
111
|
+
* @default null
|
|
112
|
+
*/
|
|
113
|
+
this.columns = null
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* A string token representing the current page state of query. It can be used in the following executions to
|
|
117
|
+
* continue paging and retrieve the remained of the result for the query.
|
|
118
|
+
* @type {String|null}
|
|
119
|
+
* @default null
|
|
120
|
+
*/
|
|
121
|
+
this.pageState = null
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Method used to manually fetch the next page of results.
|
|
125
|
+
* This method is only exposed when using the {@link Client#eachRow} method and there are more rows available in
|
|
126
|
+
* following pages.
|
|
127
|
+
* @type Function
|
|
128
|
+
*/
|
|
129
|
+
this.nextPage = undefined
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Method used internally to fetch the next page of results using promises.
|
|
133
|
+
* @internal
|
|
134
|
+
* @ignore
|
|
135
|
+
* @type {Function}
|
|
136
|
+
*/
|
|
137
|
+
this.nextPageAsync = undefined
|
|
138
|
+
|
|
139
|
+
const meta = response.meta
|
|
140
|
+
|
|
141
|
+
if (meta) {
|
|
142
|
+
this.columns = meta.columns
|
|
143
|
+
|
|
144
|
+
if (meta.pageState) {
|
|
145
|
+
this.pageState = meta.pageState.toString("hex")
|
|
146
|
+
|
|
147
|
+
// Expose rawPageState internally
|
|
148
|
+
Object.defineProperty(this, "rawPageState", {
|
|
149
|
+
value: meta.pageState,
|
|
150
|
+
enumerable: false,
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Returns the first row or null if the result rows are empty.
|
|
158
|
+
*/
|
|
159
|
+
ResultSet.prototype.first = function () {
|
|
160
|
+
if (this.rows && this.rows.length) {
|
|
161
|
+
return this.rows[0]
|
|
162
|
+
}
|
|
163
|
+
return null
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
ResultSet.prototype.getPageState = function () {
|
|
167
|
+
// backward-compatibility
|
|
168
|
+
return this.pageState
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
ResultSet.prototype.getColumns = function () {
|
|
172
|
+
// backward-compatibility
|
|
173
|
+
return this.columns
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* When this instance is the result of a conditional update query, it returns whether it was successful.
|
|
178
|
+
* Otherwise, it returns <code>true</code>.
|
|
179
|
+
* <p>
|
|
180
|
+
* For consistency, this method always returns <code>true</code> for non-conditional queries (although there is
|
|
181
|
+
* no reason to call the method in that case). This is also the case for conditional DDL statements
|
|
182
|
+
* (CREATE KEYSPACE... IF NOT EXISTS, CREATE TABLE... IF NOT EXISTS), for which the server doesn't return
|
|
183
|
+
* information whether it was applied or not.
|
|
184
|
+
* </p>
|
|
185
|
+
*/
|
|
186
|
+
ResultSet.prototype.wasApplied = function () {
|
|
187
|
+
if (!this.rows || this.rows.length === 0) {
|
|
188
|
+
return true
|
|
189
|
+
}
|
|
190
|
+
const firstRow = this.rows[0]
|
|
191
|
+
const applied = firstRow["[applied]"]
|
|
192
|
+
return typeof applied === "boolean" ? applied : true
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Gets the iterator function.
|
|
197
|
+
* <p>
|
|
198
|
+
* Retrieves the iterator of the underlying fetched rows, without causing the driver to fetch the following
|
|
199
|
+
* result pages. For more information on result paging,
|
|
200
|
+
* [visit the documentation]{@link http://docs.datastax.com/en/developer/nodejs-driver/latest/features/paging/}.
|
|
201
|
+
* </p>
|
|
202
|
+
* @alias module:types~ResultSet#@@iterator
|
|
203
|
+
* @see {@link module:types~ResultSet#@@asyncIterator}
|
|
204
|
+
* @example <caption>Using for...of statement</caption>
|
|
205
|
+
* const query = 'SELECT user_id, post_id, content FROM timeline WHERE user_id = ?';
|
|
206
|
+
* const result = await client.execute(query, [ id ], { prepare: true });
|
|
207
|
+
* for (const row of result) {
|
|
208
|
+
* console.log(row['email']);
|
|
209
|
+
* }
|
|
210
|
+
* @returns {Iterator.<Row>}
|
|
211
|
+
*/
|
|
212
|
+
ResultSet.prototype[Symbol.iterator] = function getIterator() {
|
|
213
|
+
if (!this.rows) {
|
|
214
|
+
return utils.emptyArray[Symbol.iterator]()
|
|
215
|
+
}
|
|
216
|
+
return this.rows[Symbol.iterator]()
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Gets the async iterator function.
|
|
221
|
+
* <p>
|
|
222
|
+
* Retrieves the async iterator representing the entire query result, the driver will fetch the following result
|
|
223
|
+
* pages.
|
|
224
|
+
* </p>
|
|
225
|
+
* <p>Use the async iterator when the query result might contain more rows than the <code>fetchSize</code>.</p>
|
|
226
|
+
* <p>
|
|
227
|
+
* Note that using the async iterator will not affect the internal state of the <code>ResultSet</code> instance.
|
|
228
|
+
* You should avoid using both <code>rows</code> property that contains the row instances of the first page of
|
|
229
|
+
* results, and the async iterator, that will yield all the rows in the result regardless on the number of pages.
|
|
230
|
+
* </p>
|
|
231
|
+
* <p>Multiple concurrent async iterations are not supported.</p>
|
|
232
|
+
* @alias module:types~ResultSet#@@asyncIterator
|
|
233
|
+
* @example <caption>Using for await...of statement</caption>
|
|
234
|
+
* const query = 'SELECT user_id, post_id, content FROM timeline WHERE user_id = ?';
|
|
235
|
+
* const result = await client.execute(query, [ id ], { prepare: true });
|
|
236
|
+
* for await (const row of result) {
|
|
237
|
+
* console.log(row['email']);
|
|
238
|
+
* }
|
|
239
|
+
* @returns {AsyncIterator<Row>}
|
|
240
|
+
*/
|
|
241
|
+
ResultSet.prototype[asyncIteratorSymbol] = function getAsyncGenerator() {
|
|
242
|
+
let index = 0
|
|
243
|
+
let pageState = this.rawPageState
|
|
244
|
+
let rows = this.rows
|
|
245
|
+
|
|
246
|
+
if (!rows || rows.length === 0) {
|
|
247
|
+
return { next: () => Promise.resolve({ done: true }) }
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const self = this
|
|
251
|
+
|
|
252
|
+
// Async generators are not present in Node 8, implement it manually
|
|
253
|
+
return {
|
|
254
|
+
async next() {
|
|
255
|
+
if (index >= rows.length && pageState) {
|
|
256
|
+
if (!self.nextPageAsync) {
|
|
257
|
+
throw new errors.DriverInternalError(
|
|
258
|
+
"Property nextPageAsync should be set when pageState is defined",
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const rs = await self.nextPageAsync(pageState)
|
|
263
|
+
rows = rs.rows
|
|
264
|
+
index = 0
|
|
265
|
+
pageState = rs.rawPageState
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (index < rows.length) {
|
|
269
|
+
return { done: false, value: rows[index++] }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return { done: true }
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Determines whether there are more pages of results.
|
|
279
|
+
* If so, the driver will initially retrieve and contain only the first page of results.
|
|
280
|
+
* To obtain all the rows, use the [AsyncIterator]{@linkcode module:types~ResultSet#@@asyncIterator}.
|
|
281
|
+
* @returns {boolean}
|
|
282
|
+
*/
|
|
283
|
+
ResultSet.prototype.isPaged = function () {
|
|
284
|
+
return !!this.rawPageState
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export default ResultSet
|