@ragestudio/scylla-odm 0.22.1 → 0.22.3
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/batch/index.js +2 -6
- package/batch/index.js.map +1 -1
- package/client.d.ts +6 -5
- package/client.d.ts.map +1 -1
- package/client.js +26 -33
- package/client.js.map +1 -1
- package/cql_gen/create_keyspace.js +1 -4
- package/cql_gen/create_keyspace.js.map +1 -1
- package/cql_gen/create_table.d.ts +1 -1
- package/cql_gen/create_table.d.ts.map +1 -1
- package/cql_gen/create_table.js +1 -4
- package/cql_gen/create_table.js.map +1 -1
- package/document/index.d.ts +3 -3
- package/document/index.d.ts.map +1 -1
- package/document/index.js +2 -6
- package/document/index.js.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/global.js +1 -2
- package/index.d.ts +6 -6
- package/index.d.ts.map +1 -1
- package/index.js +8 -19
- package/index.js.map +1 -1
- package/logger/index.js +2 -6
- package/logger/index.js.map +1 -1
- package/migrate/index.d.ts +1 -1
- package/migrate/index.d.ts.map +1 -1
- package/migrate/index.js +10 -53
- 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 +21 -28
- package/model/index.js.map +1 -1
- package/operations/countAll.d.ts +1 -1
- package/operations/countAll.d.ts.map +1 -1
- package/operations/countAll.js +1 -4
- package/operations/countAll.js.map +1 -1
- package/operations/delete.d.ts +3 -4
- package/operations/delete.d.ts.map +1 -1
- package/operations/delete.js +3 -9
- 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 +3 -9
- 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 +3 -9
- 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 +5 -11
- 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 +3 -9
- package/operations/sync.js.map +1 -1
- package/operations/tableExists.d.ts +1 -1
- package/operations/tableExists.d.ts.map +1 -1
- package/operations/tableExists.js +1 -4
- package/operations/tableExists.js.map +1 -1
- package/operations/update.d.ts +3 -3
- package/operations/update.d.ts.map +1 -1
- package/operations/update.js +5 -11
- 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/schema/index.js +2 -6
- package/schema/index.js.map +1 -1
- package/types.d.ts +4 -4
- package/types.d.ts.map +1 -1
- package/types.js +3 -7
- package/types.js.map +1 -1
- package/utils/buildMapper.js +1 -3
- package/utils/buildMapper.js.map +1 -1
- package/utils/delay.js +2 -5
- package/utils/delay.js.map +1 -1
- package/utils/fillDefaults.js +1 -4
- package/utils/fillDefaults.js.map +1 -1
- package/utils/isPlainObject.js +1 -3
- package/utils/isPlainObject.js.map +1 -1
- package/utils/loadModels.js +7 -45
- package/utils/loadModels.js.map +1 -1
- package/utils/queryParser.d.ts +1 -1
- package/utils/queryParser.d.ts.map +1 -1
- package/utils/queryParser.js +7 -15
- 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 +5 -11
- package/utils/typeChecker.js.map +1 -1
|
@@ -0,0 +1,332 @@
|
|
|
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
|
+
import util from "util"
|
|
19
|
+
|
|
20
|
+
import errors from "./errors.js"
|
|
21
|
+
import types from "./types/index.js"
|
|
22
|
+
import utils from "./utils.js"
|
|
23
|
+
import RequestExecution from "./request-execution.js"
|
|
24
|
+
import promiseUtils from "./promise-utils.js"
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Handles a BATCH, QUERY and EXECUTE request to the server, dealing with host fail-over and retries on error
|
|
28
|
+
*/
|
|
29
|
+
class RequestHandler {
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new instance of RequestHandler.
|
|
32
|
+
* @param {Request} request
|
|
33
|
+
* @param {ExecutionOptions} execOptions
|
|
34
|
+
* @param {Client} client Client instance used to retrieve and set the keyspace.
|
|
35
|
+
*/
|
|
36
|
+
constructor(request, execOptions, client) {
|
|
37
|
+
this.client = client
|
|
38
|
+
this._speculativeExecutionPlan =
|
|
39
|
+
client.options.policies.speculativeExecution.newPlan(
|
|
40
|
+
client.keyspace,
|
|
41
|
+
request.query || request.queries,
|
|
42
|
+
)
|
|
43
|
+
this.logEmitter = client.options.logEmitter
|
|
44
|
+
this.log = utils.log
|
|
45
|
+
this.request = request
|
|
46
|
+
this.executionOptions = execOptions
|
|
47
|
+
this.stackContainer = null
|
|
48
|
+
this.triedHosts = {}
|
|
49
|
+
// start at -1 as first request does not count.
|
|
50
|
+
this.speculativeExecutions = -1
|
|
51
|
+
this._hostIterator = null
|
|
52
|
+
this._resolveCallback = null
|
|
53
|
+
this._rejectCallback = null
|
|
54
|
+
this._newExecutionTimeout = null
|
|
55
|
+
/** @type {RequestExecution[]} */
|
|
56
|
+
this._executions = []
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Sends a new BATCH, QUERY or EXECUTE request.
|
|
61
|
+
* @param {Request} request
|
|
62
|
+
* @param {ExecutionOptions} execOptions
|
|
63
|
+
* @param {Client} client Client instance used to retrieve and set the keyspace.
|
|
64
|
+
* @returns {Promise<ResultSet>}
|
|
65
|
+
*/
|
|
66
|
+
static send(request, execOptions, client) {
|
|
67
|
+
const instance = new RequestHandler(request, execOptions, client)
|
|
68
|
+
return instance.send()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Gets a connection from the next host according to the query plan or throws a NoHostAvailableError.
|
|
73
|
+
* @returns {{host, connection}}
|
|
74
|
+
* @throws {NoHostAvailableError}
|
|
75
|
+
*/
|
|
76
|
+
getNextConnection() {
|
|
77
|
+
let host
|
|
78
|
+
let connection
|
|
79
|
+
const iterator = this._hostIterator
|
|
80
|
+
|
|
81
|
+
// Get a host that is UP in a sync loop
|
|
82
|
+
while (true) {
|
|
83
|
+
const item = iterator.next()
|
|
84
|
+
if (item.done) {
|
|
85
|
+
throw new errors.NoHostAvailableError(this.triedHosts)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
host = item.value
|
|
89
|
+
|
|
90
|
+
// Set the distance relative to the client first
|
|
91
|
+
const distance = this.client.profileManager.getDistance(host)
|
|
92
|
+
if (distance === types.distance.ignored) {
|
|
93
|
+
//If its marked as ignore by the load balancing policy, move on.
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!host.isUp()) {
|
|
98
|
+
this.triedHosts[host.address] = "Host considered as DOWN"
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
connection = host.borrowConnection()
|
|
104
|
+
this.triedHosts[host.address] = null
|
|
105
|
+
break
|
|
106
|
+
} catch (err) {
|
|
107
|
+
this.triedHosts[host.address] = err
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { connection, host }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Gets an available connection and sends the request
|
|
116
|
+
* @returns {Promise<ResultSet>}
|
|
117
|
+
*/
|
|
118
|
+
send() {
|
|
119
|
+
if (this.executionOptions.getCaptureStackTrace()) {
|
|
120
|
+
Error.captureStackTrace((this.stackContainer = {}))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
this._resolveCallback = resolve
|
|
125
|
+
this._rejectCallback = reject
|
|
126
|
+
|
|
127
|
+
const lbp = this.executionOptions.getLoadBalancingPolicy()
|
|
128
|
+
const fixedHost = this.executionOptions.getFixedHost()
|
|
129
|
+
|
|
130
|
+
if (fixedHost) {
|
|
131
|
+
// if host is configured bypass load balancing policy and use
|
|
132
|
+
// a single host plan.
|
|
133
|
+
this._hostIterator = utils.arrayIterator([fixedHost])
|
|
134
|
+
promiseUtils.toBackground(this._startNewExecution())
|
|
135
|
+
} else {
|
|
136
|
+
lbp.newQueryPlan(
|
|
137
|
+
this.client.keyspace,
|
|
138
|
+
this.executionOptions,
|
|
139
|
+
(err, iterator) => {
|
|
140
|
+
if (err) {
|
|
141
|
+
return reject(err)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this._hostIterator = iterator
|
|
145
|
+
promiseUtils.toBackground(this._startNewExecution())
|
|
146
|
+
},
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Starts a new execution on the next host of the query plan.
|
|
154
|
+
* @param {Boolean} [isSpecExec]
|
|
155
|
+
* @returns {Promise<void>}
|
|
156
|
+
* @private
|
|
157
|
+
*/
|
|
158
|
+
async _startNewExecution(isSpecExec) {
|
|
159
|
+
if (isSpecExec) {
|
|
160
|
+
this.client.metrics.onSpeculativeExecution()
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let host
|
|
164
|
+
let connection
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
;({ host, connection } = this.getNextConnection())
|
|
168
|
+
} catch (err) {
|
|
169
|
+
return this.handleNoHostAvailable(err, null)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (
|
|
173
|
+
isSpecExec &&
|
|
174
|
+
this._executions.length >= 0 &&
|
|
175
|
+
this._executions[0].wasCancelled()
|
|
176
|
+
) {
|
|
177
|
+
// This method was called on the next tick and could not be cleared, the previous execution was cancelled so
|
|
178
|
+
// there's no point in launching a new execution.
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (
|
|
183
|
+
this.client.keyspace &&
|
|
184
|
+
this.client.keyspace !== connection.keyspace
|
|
185
|
+
) {
|
|
186
|
+
try {
|
|
187
|
+
await connection.changeKeyspace(this.client.keyspace)
|
|
188
|
+
} catch (err) {
|
|
189
|
+
this.triedHosts[host.address] = err
|
|
190
|
+
// The error occurred asynchronously
|
|
191
|
+
// We can blindly re-try to obtain a different host/connection.
|
|
192
|
+
return this._startNewExecution(isSpecExec)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const execution = new RequestExecution(this, host, connection)
|
|
197
|
+
this._executions.push(execution)
|
|
198
|
+
execution.start()
|
|
199
|
+
|
|
200
|
+
if (this.executionOptions.isIdempotent()) {
|
|
201
|
+
this._scheduleSpeculativeExecution(host)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Schedules next speculative execution, if any.
|
|
207
|
+
* @param {Host!} host
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
_scheduleSpeculativeExecution(host) {
|
|
211
|
+
const delay = this._speculativeExecutionPlan.nextExecution(host)
|
|
212
|
+
if (typeof delay !== "number" || delay < 0) {
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (delay === 0) {
|
|
217
|
+
// Parallel speculative execution
|
|
218
|
+
return process.nextTick(() => {
|
|
219
|
+
promiseUtils.toBackground(this._startNewExecution(true))
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Create timer for speculative execution
|
|
224
|
+
this._newExecutionTimeout = setTimeout(
|
|
225
|
+
() => promiseUtils.toBackground(this._startNewExecution(true)),
|
|
226
|
+
delay,
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Sets the keyspace in any connection that is already opened.
|
|
232
|
+
* @param {Client} client
|
|
233
|
+
* @returns {Promise}
|
|
234
|
+
*/
|
|
235
|
+
static setKeyspace(client) {
|
|
236
|
+
let connection
|
|
237
|
+
|
|
238
|
+
for (const host of client.hosts.values()) {
|
|
239
|
+
connection = host.getActiveConnection()
|
|
240
|
+
if (connection) {
|
|
241
|
+
break
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!connection) {
|
|
246
|
+
throw new errors.DriverInternalError("No active connection found")
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return connection.changeKeyspace(client.keyspace)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @param {Error} err
|
|
254
|
+
* @param {ResultSet} [result]
|
|
255
|
+
*/
|
|
256
|
+
setCompleted(err, result) {
|
|
257
|
+
if (this._newExecutionTimeout !== null) {
|
|
258
|
+
clearTimeout(this._newExecutionTimeout)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Mark all executions as cancelled
|
|
262
|
+
for (const execution of this._executions) {
|
|
263
|
+
execution.cancel()
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (err) {
|
|
267
|
+
if (this.executionOptions.getCaptureStackTrace()) {
|
|
268
|
+
utils.fixStack(this.stackContainer.stack, err)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Reject the promise
|
|
272
|
+
return this._rejectCallback(err)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (result.info.warnings) {
|
|
276
|
+
// Log the warnings from the response
|
|
277
|
+
result.info.warnings.forEach(function (message, i, warnings) {
|
|
278
|
+
this.log(
|
|
279
|
+
"warning",
|
|
280
|
+
util.format(
|
|
281
|
+
'Received warning (%d of %d) "%s" for "%s"',
|
|
282
|
+
i + 1,
|
|
283
|
+
warnings.length,
|
|
284
|
+
message,
|
|
285
|
+
this.request.query || "batch",
|
|
286
|
+
),
|
|
287
|
+
)
|
|
288
|
+
}, this)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// We used to invoke the callback on next tick to allow stack unwinding and prevent the optimizing compiler to
|
|
292
|
+
// optimize read and write functions together.
|
|
293
|
+
// As we are resolving a Promise then() and catch() are always scheduled in the microtask queue
|
|
294
|
+
// We can invoke the resolve method directly.
|
|
295
|
+
this._resolveCallback(result)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @param {NoHostAvailableError} err
|
|
300
|
+
* @param {RequestExecution|null} execution
|
|
301
|
+
*/
|
|
302
|
+
handleNoHostAvailable(err, execution) {
|
|
303
|
+
if (execution !== null) {
|
|
304
|
+
// Remove the execution
|
|
305
|
+
const index = this._executions.indexOf(execution)
|
|
306
|
+
this._executions.splice(index, 1)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (this._executions.length === 0) {
|
|
310
|
+
// There aren't any other executions, we should report back to the user that there isn't
|
|
311
|
+
// a host available for executing the request
|
|
312
|
+
this.setCompleted(err)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Gets a long lived closure that can fetch the next page.
|
|
318
|
+
* @returns {Function}
|
|
319
|
+
*/
|
|
320
|
+
getNextPageHandler() {
|
|
321
|
+
const request = this.request
|
|
322
|
+
const execOptions = this.executionOptions
|
|
323
|
+
const client = this.client
|
|
324
|
+
|
|
325
|
+
return function nextPageHandler(pageState) {
|
|
326
|
+
execOptions.setPageState(pageState)
|
|
327
|
+
return new RequestHandler(request, execOptions, client).send()
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export default RequestHandler
|