@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.
Files changed (153) hide show
  1. package/batch/index.d.ts +3 -3
  2. package/batch/index.d.ts.map +1 -1
  3. package/client.d.ts +6 -5
  4. package/client.d.ts.map +1 -1
  5. package/client.js +11 -12
  6. package/client.js.map +1 -1
  7. package/cql_gen/create_table.d.ts +1 -1
  8. package/cql_gen/create_table.d.ts.map +1 -1
  9. package/document/index.d.ts +3 -3
  10. package/document/index.d.ts.map +1 -1
  11. package/driver/LICENSE.txt +177 -0
  12. package/driver/NOTICE.txt +67 -0
  13. package/driver/auth/index.d.ts +37 -0
  14. package/driver/auth/index.js +37 -0
  15. package/driver/auth/no-auth-provider.js +73 -0
  16. package/driver/auth/plain-text-auth-provider.js +81 -0
  17. package/driver/auth/provider.js +77 -0
  18. package/driver/client-options.js +442 -0
  19. package/driver/client.js +1267 -0
  20. package/driver/concurrent/index.d.ts +49 -0
  21. package/driver/concurrent/index.js +366 -0
  22. package/driver/connection.js +1034 -0
  23. package/driver/control-connection.js +1282 -0
  24. package/driver/encoder.js +2316 -0
  25. package/driver/errors.js +223 -0
  26. package/driver/execution-options.js +612 -0
  27. package/driver/execution-profile.js +274 -0
  28. package/driver/host-connection-pool.js +587 -0
  29. package/driver/host.js +699 -0
  30. package/driver/index.d.ts +387 -0
  31. package/driver/index.js +81 -0
  32. package/driver/mapping/cache.js +214 -0
  33. package/driver/mapping/doc-info-adapter.js +171 -0
  34. package/driver/mapping/index.d.ts +219 -0
  35. package/driver/mapping/index.js +57 -0
  36. package/driver/mapping/mapper.js +225 -0
  37. package/driver/mapping/mapping-handler.js +641 -0
  38. package/driver/mapping/model-batch-item.js +215 -0
  39. package/driver/mapping/model-batch-mapper.js +141 -0
  40. package/driver/mapping/model-mapper.js +315 -0
  41. package/driver/mapping/model-mapping-info.js +225 -0
  42. package/driver/mapping/object-selector.js +417 -0
  43. package/driver/mapping/q.js +156 -0
  44. package/driver/mapping/query-generator.js +556 -0
  45. package/driver/mapping/result-mapper.js +123 -0
  46. package/driver/mapping/result.js +139 -0
  47. package/driver/mapping/table-mappings.js +133 -0
  48. package/driver/mapping/tree.js +160 -0
  49. package/driver/metadata/aggregate.js +79 -0
  50. package/driver/metadata/client-state.js +119 -0
  51. package/driver/metadata/data-collection.js +182 -0
  52. package/driver/metadata/event-debouncer.js +174 -0
  53. package/driver/metadata/index.d.ts +276 -0
  54. package/driver/metadata/index.js +1156 -0
  55. package/driver/metadata/materialized-view.js +49 -0
  56. package/driver/metadata/schema-function.js +98 -0
  57. package/driver/metadata/schema-index.js +166 -0
  58. package/driver/metadata/schema-parser.js +1399 -0
  59. package/driver/metadata/table-metadata.js +77 -0
  60. package/driver/operation-state.js +206 -0
  61. package/driver/policies/address-resolution.js +145 -0
  62. package/driver/policies/index.d.ts +241 -0
  63. package/driver/policies/index.js +110 -0
  64. package/driver/policies/load-balancing.js +970 -0
  65. package/driver/policies/reconnection.js +166 -0
  66. package/driver/policies/retry.js +326 -0
  67. package/driver/policies/speculative-execution.js +150 -0
  68. package/driver/policies/timestamp-generation.js +176 -0
  69. package/driver/prepare-handler.js +347 -0
  70. package/driver/promise-utils.js +191 -0
  71. package/driver/readers.js +624 -0
  72. package/driver/request-execution.js +644 -0
  73. package/driver/request-handler.js +332 -0
  74. package/driver/requests.js +618 -0
  75. package/driver/stream-id-stack.js +209 -0
  76. package/driver/streams.js +745 -0
  77. package/driver/token.js +325 -0
  78. package/driver/tokenizer.js +631 -0
  79. package/driver/types/big-decimal.js +282 -0
  80. package/driver/types/duration.js +576 -0
  81. package/driver/types/index.d.ts +486 -0
  82. package/driver/types/index.js +733 -0
  83. package/driver/types/inet-address.js +262 -0
  84. package/driver/types/integer.js +818 -0
  85. package/driver/types/local-date.js +280 -0
  86. package/driver/types/local-time.js +299 -0
  87. package/driver/types/mutable-long.js +385 -0
  88. package/driver/types/protocol-version.js +391 -0
  89. package/driver/types/result-set.js +287 -0
  90. package/driver/types/result-stream.js +164 -0
  91. package/driver/types/row.js +85 -0
  92. package/driver/types/time-uuid.js +414 -0
  93. package/driver/types/tuple.js +103 -0
  94. package/driver/types/uuid.js +160 -0
  95. package/driver/types/vector.js +130 -0
  96. package/driver/types/version-number.js +153 -0
  97. package/driver/utils.js +1485 -0
  98. package/driver/writers.js +350 -0
  99. package/global.d.ts +1 -1
  100. package/global.d.ts.map +1 -1
  101. package/index.d.ts +6 -6
  102. package/index.d.ts.map +1 -1
  103. package/index.js +6 -6
  104. package/index.js.map +1 -1
  105. package/migrate/index.d.ts +1 -1
  106. package/migrate/index.d.ts.map +1 -1
  107. package/migrate/index.js +1 -1
  108. package/migrate/index.js.map +1 -1
  109. package/model/index.d.ts +6 -6
  110. package/model/index.d.ts.map +1 -1
  111. package/model/index.js +10 -10
  112. package/model/index.js.map +1 -1
  113. package/operations/countAll.d.ts +1 -1
  114. package/operations/countAll.d.ts.map +1 -1
  115. package/operations/delete.d.ts +3 -4
  116. package/operations/delete.d.ts.map +1 -1
  117. package/operations/delete.js +1 -1
  118. package/operations/delete.js.map +1 -1
  119. package/operations/find.d.ts +2 -2
  120. package/operations/find.d.ts.map +1 -1
  121. package/operations/find.js +1 -1
  122. package/operations/find.js.map +1 -1
  123. package/operations/findOne.d.ts +2 -2
  124. package/operations/findOne.d.ts.map +1 -1
  125. package/operations/findOne.js +1 -1
  126. package/operations/findOne.js.map +1 -1
  127. package/operations/insert.d.ts +3 -3
  128. package/operations/insert.d.ts.map +1 -1
  129. package/operations/insert.js +2 -2
  130. package/operations/insert.js.map +1 -1
  131. package/operations/sync.d.ts +1 -1
  132. package/operations/sync.d.ts.map +1 -1
  133. package/operations/sync.js +1 -1
  134. package/operations/sync.js.map +1 -1
  135. package/operations/tableExists.d.ts +1 -1
  136. package/operations/tableExists.d.ts.map +1 -1
  137. package/operations/update.d.ts +3 -3
  138. package/operations/update.d.ts.map +1 -1
  139. package/operations/update.js +2 -2
  140. package/operations/update.js.map +1 -1
  141. package/package.json +4 -12
  142. package/schema/index.d.ts +1 -1
  143. package/schema/index.d.ts.map +1 -1
  144. package/types.d.ts +4 -4
  145. package/types.d.ts.map +1 -1
  146. package/utils/queryParser.d.ts +1 -1
  147. package/utils/queryParser.d.ts.map +1 -1
  148. package/utils/queryParser.js +1 -1
  149. package/utils/queryParser.js.map +1 -1
  150. package/utils/typeChecker.d.ts +1 -1
  151. package/utils/typeChecker.d.ts.map +1 -1
  152. package/utils/typeChecker.js +1 -1
  153. 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