@ragestudio/scylla-odm 0.22.2 → 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/client.d.ts +6 -5
- package/client.d.ts.map +1 -1
- package/client.js +7 -7
- 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,164 @@
|
|
|
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 { Readable } from "stream"
|
|
20
|
+
import utils from "../utils.js"
|
|
21
|
+
import errors from "../errors.js"
|
|
22
|
+
import clientOptions from "../client-options.js"
|
|
23
|
+
|
|
24
|
+
/** @module types */
|
|
25
|
+
/**
|
|
26
|
+
* Readable stream using to yield data from a result or a field
|
|
27
|
+
*/
|
|
28
|
+
class ResultStream extends Readable {
|
|
29
|
+
constructor(opt) {
|
|
30
|
+
super(opt)
|
|
31
|
+
this.buffer = []
|
|
32
|
+
this.paused = true
|
|
33
|
+
this._cancelAllowed = false
|
|
34
|
+
this._handlersObject = null
|
|
35
|
+
this._highWaterMarkRows = 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_read() {
|
|
39
|
+
this.paused = false
|
|
40
|
+
if (this.buffer.length === 0) {
|
|
41
|
+
this._readableState.reading = false
|
|
42
|
+
}
|
|
43
|
+
while (!this.paused && this.buffer.length > 0) {
|
|
44
|
+
this.paused = !this.push(this.buffer.shift())
|
|
45
|
+
}
|
|
46
|
+
this._checkBelowHighWaterMark()
|
|
47
|
+
if (!this.paused && !this.buffer.length && this._readNext) {
|
|
48
|
+
this._readNext()
|
|
49
|
+
this._readNext = null
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Allows for throttling, helping nodejs keep the internal buffers reasonably sized.
|
|
55
|
+
* @param {function} readNext function that triggers reading the next result chunk
|
|
56
|
+
* @ignore
|
|
57
|
+
*/
|
|
58
|
+
_valve(readNext) {
|
|
59
|
+
this._readNext = null
|
|
60
|
+
if (!readNext) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
if (this.paused || this.buffer.length) {
|
|
64
|
+
this._readNext = readNext
|
|
65
|
+
} else {
|
|
66
|
+
readNext()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
add(chunk) {
|
|
71
|
+
const length = this.buffer.push(chunk)
|
|
72
|
+
this.read(0)
|
|
73
|
+
this._checkAboveHighWaterMark()
|
|
74
|
+
return length
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_checkAboveHighWaterMark() {
|
|
78
|
+
if (
|
|
79
|
+
!this._handlersObject ||
|
|
80
|
+
!this._handlersObject.resumeReadingHandler
|
|
81
|
+
) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
if (
|
|
85
|
+
this._highWaterMarkRows === 0 ||
|
|
86
|
+
this.buffer.length !== this._highWaterMarkRows
|
|
87
|
+
) {
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
this._handlersObject.resumeReadingHandler(false)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_checkBelowHighWaterMark() {
|
|
94
|
+
if (
|
|
95
|
+
!this._handlersObject ||
|
|
96
|
+
!this._handlersObject.resumeReadingHandler
|
|
97
|
+
) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
if (
|
|
101
|
+
this._highWaterMarkRows === 0 ||
|
|
102
|
+
this.buffer.length >= this._highWaterMarkRows
|
|
103
|
+
) {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
// The consumer has dequeued below the watermark
|
|
107
|
+
this._handlersObject.resumeReadingHandler(true)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* When continuous paging is enabled, allows the client to notify to the server to stop pushing further pages.
|
|
112
|
+
* <p>Note: This is not part of the public API yet.</p>
|
|
113
|
+
* @param {Function} [callback] The cancel method accepts an optional callback.
|
|
114
|
+
* @example <caption>Cancelling a continuous paging execution</caption>
|
|
115
|
+
* const stream = client.stream(query, params, { prepare: true, continuousPaging: true });
|
|
116
|
+
* // ...
|
|
117
|
+
* // Ask the server to stop pushing rows.
|
|
118
|
+
* stream.cancel();
|
|
119
|
+
* @ignore
|
|
120
|
+
*/
|
|
121
|
+
cancel(callback) {
|
|
122
|
+
if (!this._cancelAllowed) {
|
|
123
|
+
const err = new Error(
|
|
124
|
+
"You can only cancel streaming executions when continuous paging is enabled",
|
|
125
|
+
)
|
|
126
|
+
if (!callback) {
|
|
127
|
+
throw err
|
|
128
|
+
}
|
|
129
|
+
return callback(err)
|
|
130
|
+
}
|
|
131
|
+
if (!this._handlersObject) {
|
|
132
|
+
throw new errors.DriverInternalError(
|
|
133
|
+
"ResultStream cancel is allowed but the cancel options were not set",
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
callback = callback || utils.noop
|
|
137
|
+
if (!this._handlersObject.cancelHandler) {
|
|
138
|
+
// The handler is not yet set
|
|
139
|
+
// Set the callback as a flag to identify that the cancel handler must be invoked when set
|
|
140
|
+
this._handlersObject.cancelHandler = callback
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
this._handlersObject.cancelHandler(callback)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Sets the pointer to the handler to be used to cancel the continuous page execution.
|
|
148
|
+
* @param options
|
|
149
|
+
* @internal
|
|
150
|
+
* @ignore
|
|
151
|
+
*/
|
|
152
|
+
setHandlers(options) {
|
|
153
|
+
if (!options.continuousPaging) {
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
this._cancelAllowed = true
|
|
157
|
+
this._handlersObject = options
|
|
158
|
+
this._highWaterMarkRows =
|
|
159
|
+
options.continuousPaging.highWaterMarkRows ||
|
|
160
|
+
clientOptions.continuousPageDefaultHighWaterMark
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export default ResultStream
|
|
@@ -0,0 +1,85 @@
|
|
|
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
|
+
/** @module types */
|
|
19
|
+
/**
|
|
20
|
+
* Represents a result row
|
|
21
|
+
* @param {Array} columns
|
|
22
|
+
* @constructor
|
|
23
|
+
*/
|
|
24
|
+
function Row(columns) {
|
|
25
|
+
if (!columns) {
|
|
26
|
+
throw new Error("Columns not defined")
|
|
27
|
+
}
|
|
28
|
+
//Private non-enumerable properties, with double underscore to avoid interfering with column names
|
|
29
|
+
Object.defineProperty(this, "__columns", {
|
|
30
|
+
value: columns,
|
|
31
|
+
enumerable: false,
|
|
32
|
+
writable: false,
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns the cell value.
|
|
38
|
+
* @param {String|Number} columnName Name or index of the column
|
|
39
|
+
*/
|
|
40
|
+
Row.prototype.get = function (columnName) {
|
|
41
|
+
if (typeof columnName === "number") {
|
|
42
|
+
//its an index
|
|
43
|
+
return this[this.__columns[columnName].name]
|
|
44
|
+
}
|
|
45
|
+
return this[columnName]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns an array of the values of the row
|
|
50
|
+
* @returns {Array}
|
|
51
|
+
*/
|
|
52
|
+
Row.prototype.values = function () {
|
|
53
|
+
const valuesArray = []
|
|
54
|
+
this.forEach(function (val) {
|
|
55
|
+
valuesArray.push(val)
|
|
56
|
+
})
|
|
57
|
+
return valuesArray
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns an array of the column names of the row
|
|
62
|
+
* @returns {Array}
|
|
63
|
+
*/
|
|
64
|
+
Row.prototype.keys = function () {
|
|
65
|
+
const keysArray = []
|
|
66
|
+
this.forEach(function (val, key) {
|
|
67
|
+
keysArray.push(key)
|
|
68
|
+
})
|
|
69
|
+
return keysArray
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Executes the callback for each field in the row, containing the value as first parameter followed by the columnName
|
|
74
|
+
* @param {Function} callback
|
|
75
|
+
*/
|
|
76
|
+
Row.prototype.forEach = function (callback) {
|
|
77
|
+
for (const columnName in this) {
|
|
78
|
+
if (!this.hasOwnProperty(columnName)) {
|
|
79
|
+
continue
|
|
80
|
+
}
|
|
81
|
+
callback(this[columnName], columnName)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default Row
|
|
@@ -0,0 +1,414 @@
|
|
|
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
|
+
import crypto from "crypto"
|
|
20
|
+
import Long from "long"
|
|
21
|
+
|
|
22
|
+
import Uuid from "./uuid.js"
|
|
23
|
+
import utils from "../utils.js"
|
|
24
|
+
|
|
25
|
+
/** @module types */
|
|
26
|
+
/**
|
|
27
|
+
* Oct 15, 1582 in milliseconds since unix epoch
|
|
28
|
+
* @const
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
const _unixToGregorian = 12219292800000
|
|
32
|
+
/**
|
|
33
|
+
* 10,000 ticks in a millisecond
|
|
34
|
+
* @const
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
const _ticksInMs = 10000
|
|
38
|
+
|
|
39
|
+
const minNodeId = utils.allocBufferFromString("808080808080", "hex")
|
|
40
|
+
const minClockId = utils.allocBufferFromString("8080", "hex")
|
|
41
|
+
const maxNodeId = utils.allocBufferFromString("7f7f7f7f7f7f", "hex")
|
|
42
|
+
const maxClockId = utils.allocBufferFromString("7f7f", "hex")
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Counter used to generate up to 10000 different timeuuid values with the same Date
|
|
46
|
+
* @private
|
|
47
|
+
* @type {number}
|
|
48
|
+
*/
|
|
49
|
+
let _ticks = 0
|
|
50
|
+
/**
|
|
51
|
+
* Counter used to generate ticks for the current time
|
|
52
|
+
* @private
|
|
53
|
+
* @type {number}
|
|
54
|
+
*/
|
|
55
|
+
let _ticksForCurrentTime = 0
|
|
56
|
+
/**
|
|
57
|
+
* Remember the last time when a ticks for the current time so that it can be reset
|
|
58
|
+
* @private
|
|
59
|
+
* @type {number}
|
|
60
|
+
*/
|
|
61
|
+
let _lastTimestamp = 0
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates a new instance of Uuid based on the parameters provided according to rfc4122.
|
|
65
|
+
* If any of the arguments is not provided, it will be randomly generated, except for the date that will use the current
|
|
66
|
+
* date.
|
|
67
|
+
* <p>
|
|
68
|
+
* Note that when nodeId and/or clockId portions are not provided, the constructor will generate them using
|
|
69
|
+
* <code>crypto.randomBytes()</code>. As it's possible that <code>crypto.randomBytes()</code> might block, it's
|
|
70
|
+
* recommended that you use the callback-based version of the static methods <code>fromDate()</code> or
|
|
71
|
+
* <code>now()</code> in that case.
|
|
72
|
+
* </p>
|
|
73
|
+
* @class
|
|
74
|
+
* @classdesc Represents an immutable version 1 universally unique identifier (UUID). A UUID represents a 128-bit value.
|
|
75
|
+
* <p>Usage: <code>TimeUuid.now()</code></p>
|
|
76
|
+
* @extends module:types~Uuid
|
|
77
|
+
* @param {Date} [value] The datetime for the instance, if not provided, it will use the current Date.
|
|
78
|
+
* @param {Number} [ticks] A number from 0 to 10000 representing the 100-nanoseconds units for this instance to fill in the information not available in the Date,
|
|
79
|
+
* as Ecmascript Dates have only milliseconds precision.
|
|
80
|
+
* @param {String|Buffer} [nodeId] A 6-length Buffer or string of 6 ascii characters representing the node identifier, ie: 'host01'.
|
|
81
|
+
* @param {String|Buffer} [clockId] A 2-length Buffer or string of 6 ascii characters representing the clock identifier.
|
|
82
|
+
* @constructor
|
|
83
|
+
*/
|
|
84
|
+
function TimeUuid(value, ticks, nodeId, clockId) {
|
|
85
|
+
let buffer
|
|
86
|
+
if (value instanceof Buffer) {
|
|
87
|
+
if (value.length !== 16) {
|
|
88
|
+
throw new Error("Buffer for v1 uuid not valid")
|
|
89
|
+
}
|
|
90
|
+
buffer = value
|
|
91
|
+
} else {
|
|
92
|
+
buffer = generateBuffer(value, ticks, nodeId, clockId)
|
|
93
|
+
}
|
|
94
|
+
Uuid.call(this, buffer)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
util.inherits(TimeUuid, Uuid)
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Generates a TimeUuid instance based on the Date provided using random node and clock values.
|
|
101
|
+
* @param {Date} date Date to generate the v1 uuid.
|
|
102
|
+
* @param {Number} [ticks] A number from 0 to 10000 representing the 100-nanoseconds units for this instance to fill in the information not available in the Date,
|
|
103
|
+
* as Ecmascript Dates have only milliseconds precision.
|
|
104
|
+
* @param {String|Buffer} [nodeId] A 6-length Buffer or string of 6 ascii characters representing the node identifier, ie: 'host01'.
|
|
105
|
+
* If not provided, a random nodeId will be generated.
|
|
106
|
+
* @param {String|Buffer} [clockId] A 2-length Buffer or string of 6 ascii characters representing the clock identifier.
|
|
107
|
+
* If not provided a random clockId will be generated.
|
|
108
|
+
* @param {Function} [callback] An optional callback to be invoked with the error as first parameter and the created
|
|
109
|
+
* <code>TimeUuid</code> as second parameter. When a callback is provided, the random portions of the
|
|
110
|
+
* <code>TimeUuid</code> instance are created asynchronously.
|
|
111
|
+
* <p>
|
|
112
|
+
* When nodeId and/or clockId portions are not provided, this method will generate them using
|
|
113
|
+
* <code>crypto.randomBytes()</code>. As it's possible that <code>crypto.randomBytes()</code> might block, it's
|
|
114
|
+
* recommended that you use the callback-based version of this method in that case.
|
|
115
|
+
* </p>
|
|
116
|
+
* @example <caption>Generate a TimeUuid from a ECMAScript Date</caption>
|
|
117
|
+
* const timeuuid = TimeUuid.fromDate(new Date());
|
|
118
|
+
* @example <caption>Generate a TimeUuid from a Date with ticks portion</caption>
|
|
119
|
+
* const timeuuid = TimeUuid.fromDate(new Date(), 1203);
|
|
120
|
+
* @example <caption>Generate a TimeUuid from a Date without any random portion</caption>
|
|
121
|
+
* const timeuuid = TimeUuid.fromDate(new Date(), 1203, 'host01', '02');
|
|
122
|
+
* @example <caption>Generate a TimeUuid from a Date with random node and clock identifiers</caption>
|
|
123
|
+
* TimeUuid.fromDate(new Date(), 1203, function (err, timeuuid) {
|
|
124
|
+
* // do something with the generated timeuuid
|
|
125
|
+
* });
|
|
126
|
+
*/
|
|
127
|
+
TimeUuid.fromDate = function (date, ticks, nodeId, clockId, callback) {
|
|
128
|
+
if (typeof ticks === "function") {
|
|
129
|
+
callback = ticks
|
|
130
|
+
ticks = nodeId = clockId = null
|
|
131
|
+
} else if (typeof nodeId === "function") {
|
|
132
|
+
callback = nodeId
|
|
133
|
+
nodeId = clockId = null
|
|
134
|
+
} else if (typeof clockId === "function") {
|
|
135
|
+
callback = clockId
|
|
136
|
+
clockId = null
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!callback) {
|
|
140
|
+
return new TimeUuid(date, ticks, nodeId, clockId)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
utils.parallel(
|
|
144
|
+
[
|
|
145
|
+
(next) =>
|
|
146
|
+
getOrGenerateRandom(nodeId, 6, (err, buffer) =>
|
|
147
|
+
next(err, (nodeId = buffer)),
|
|
148
|
+
),
|
|
149
|
+
(next) =>
|
|
150
|
+
getOrGenerateRandom(clockId, 2, (err, buffer) =>
|
|
151
|
+
next(err, (clockId = buffer)),
|
|
152
|
+
),
|
|
153
|
+
],
|
|
154
|
+
(err) => {
|
|
155
|
+
if (err) {
|
|
156
|
+
return callback(err)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let timeUuid
|
|
160
|
+
try {
|
|
161
|
+
timeUuid = new TimeUuid(date, ticks, nodeId, clockId)
|
|
162
|
+
} catch (e) {
|
|
163
|
+
return callback(e)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
callback(null, timeUuid)
|
|
167
|
+
},
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Parses a string representation of a TimeUuid
|
|
173
|
+
* @param {String} value
|
|
174
|
+
* @returns {TimeUuid}
|
|
175
|
+
*/
|
|
176
|
+
TimeUuid.fromString = function (value) {
|
|
177
|
+
return new TimeUuid(Uuid.fromString(value).getBuffer())
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Returns the smaller possible type 1 uuid with the provided Date.
|
|
182
|
+
*/
|
|
183
|
+
TimeUuid.min = function (date, ticks) {
|
|
184
|
+
return new TimeUuid(date, ticks, minNodeId, minClockId)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Returns the biggest possible type 1 uuid with the provided Date.
|
|
189
|
+
*/
|
|
190
|
+
TimeUuid.max = function (date, ticks) {
|
|
191
|
+
return new TimeUuid(date, ticks, maxNodeId, maxClockId)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Generates a TimeUuid instance based on the current date using random node and clock values.
|
|
196
|
+
* @param {String|Buffer} [nodeId] A 6-length Buffer or string of 6 ascii characters representing the node identifier, ie: 'host01'.
|
|
197
|
+
* If not provided, a random nodeId will be generated.
|
|
198
|
+
* @param {String|Buffer} [clockId] A 2-length Buffer or string of 6 ascii characters representing the clock identifier.
|
|
199
|
+
* If not provided a random clockId will be generated.
|
|
200
|
+
* @param {Function} [callback] An optional callback to be invoked with the error as first parameter and the created
|
|
201
|
+
* <code>TimeUuid</code> as second parameter. When a callback is provided, the random portions of the
|
|
202
|
+
* <code>TimeUuid</code> instance are created asynchronously.
|
|
203
|
+
* <p>
|
|
204
|
+
* When nodeId and/or clockId portions are not provided, this method will generate them using
|
|
205
|
+
* <code>crypto.randomBytes()</code>. As it's possible that <code>crypto.randomBytes()</code> might block, it's
|
|
206
|
+
* recommended that you use the callback-based version of this method in that case.
|
|
207
|
+
* </p>
|
|
208
|
+
* @example <caption>Generate a TimeUuid from a Date without any random portion</caption>
|
|
209
|
+
* const timeuuid = TimeUuid.now('host01', '02');
|
|
210
|
+
* @example <caption>Generate a TimeUuid with random node and clock identifiers</caption>
|
|
211
|
+
* TimeUuid.now(function (err, timeuuid) {
|
|
212
|
+
* // do something with the generated timeuuid
|
|
213
|
+
* });
|
|
214
|
+
* @example <caption>Generate a TimeUuid based on the current date (might block)</caption>
|
|
215
|
+
* const timeuuid = TimeUuid.now();
|
|
216
|
+
*/
|
|
217
|
+
TimeUuid.now = function (nodeId, clockId, callback) {
|
|
218
|
+
return TimeUuid.fromDate(null, null, nodeId, clockId, callback)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Gets the Date and 100-nanoseconds units representation of this instance.
|
|
223
|
+
* @returns {{date: Date, ticks: Number}}
|
|
224
|
+
*/
|
|
225
|
+
TimeUuid.prototype.getDatePrecision = function () {
|
|
226
|
+
const timeLow = this.buffer.readUInt32BE(0)
|
|
227
|
+
|
|
228
|
+
let timeHigh = 0
|
|
229
|
+
timeHigh |= (this.buffer[4] & 0xff) << 8
|
|
230
|
+
timeHigh |= this.buffer[5] & 0xff
|
|
231
|
+
timeHigh |= (this.buffer[6] & 0x0f) << 24
|
|
232
|
+
timeHigh |= (this.buffer[7] & 0xff) << 16
|
|
233
|
+
|
|
234
|
+
const val = Long.fromBits(timeLow, timeHigh)
|
|
235
|
+
const ticksInMsLong = Long.fromNumber(_ticksInMs)
|
|
236
|
+
const ticks = val.modulo(ticksInMsLong)
|
|
237
|
+
const time = val
|
|
238
|
+
.div(ticksInMsLong)
|
|
239
|
+
.subtract(Long.fromNumber(_unixToGregorian))
|
|
240
|
+
return { date: new Date(time.toNumber()), ticks: ticks.toNumber() }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Gets the Date representation of this instance.
|
|
245
|
+
* @returns {Date}
|
|
246
|
+
*/
|
|
247
|
+
TimeUuid.prototype.getDate = function () {
|
|
248
|
+
return this.getDatePrecision().date
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Returns the node id this instance
|
|
253
|
+
* @returns {Buffer}
|
|
254
|
+
*/
|
|
255
|
+
TimeUuid.prototype.getNodeId = function () {
|
|
256
|
+
return this.buffer.slice(10)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Returns the clock id this instance, with the variant applied (first 2 msb being 1 and 0).
|
|
261
|
+
* @returns {Buffer}
|
|
262
|
+
*/
|
|
263
|
+
TimeUuid.prototype.getClockId = function () {
|
|
264
|
+
return this.buffer.slice(8, 10)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Returns the node id this instance as an ascii string
|
|
269
|
+
* @returns {String}
|
|
270
|
+
*/
|
|
271
|
+
TimeUuid.prototype.getNodeIdString = function () {
|
|
272
|
+
return this.buffer.slice(10).toString("ascii")
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function writeTime(buffer, time, ticks) {
|
|
276
|
+
//value time expressed in ticks precision
|
|
277
|
+
const val = Long.fromNumber(time + _unixToGregorian)
|
|
278
|
+
.multiply(Long.fromNumber(10000))
|
|
279
|
+
.add(Long.fromNumber(ticks))
|
|
280
|
+
const timeHigh = val.getHighBitsUnsigned()
|
|
281
|
+
buffer.writeUInt32BE(val.getLowBitsUnsigned(), 0)
|
|
282
|
+
buffer.writeUInt16BE(timeHigh & 0xffff, 4)
|
|
283
|
+
buffer.writeUInt16BE((timeHigh >>> 16) & 0xffff, 6)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Returns a buffer of length 2 representing the clock identifier
|
|
288
|
+
* @param {String|Buffer} clockId
|
|
289
|
+
* @returns {Buffer}
|
|
290
|
+
* @private
|
|
291
|
+
*/
|
|
292
|
+
function getClockId(clockId) {
|
|
293
|
+
let buffer = clockId
|
|
294
|
+
if (typeof clockId === "string") {
|
|
295
|
+
buffer = utils.allocBufferFromString(clockId, "ascii")
|
|
296
|
+
}
|
|
297
|
+
if (!(buffer instanceof Buffer)) {
|
|
298
|
+
//Generate
|
|
299
|
+
buffer = getRandomBytes(2)
|
|
300
|
+
} else if (buffer.length !== 2) {
|
|
301
|
+
throw new Error("Clock identifier must have 2 bytes")
|
|
302
|
+
}
|
|
303
|
+
return buffer
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Returns a buffer of length 6 representing the clock identifier
|
|
308
|
+
* @param {String|Buffer} nodeId
|
|
309
|
+
* @returns {Buffer}
|
|
310
|
+
* @private
|
|
311
|
+
*/
|
|
312
|
+
function getNodeId(nodeId) {
|
|
313
|
+
let buffer = nodeId
|
|
314
|
+
if (typeof nodeId === "string") {
|
|
315
|
+
buffer = utils.allocBufferFromString(nodeId, "ascii")
|
|
316
|
+
}
|
|
317
|
+
if (!(buffer instanceof Buffer)) {
|
|
318
|
+
//Generate
|
|
319
|
+
buffer = getRandomBytes(6)
|
|
320
|
+
} else if (buffer.length !== 6) {
|
|
321
|
+
throw new Error("Node identifier must have 6 bytes")
|
|
322
|
+
}
|
|
323
|
+
return buffer
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Returns the ticks portion of a timestamp. If the ticks are not provided an internal counter is used that gets reset at 10000.
|
|
328
|
+
* @private
|
|
329
|
+
* @param {Number} [ticks]
|
|
330
|
+
* @returns {Number}
|
|
331
|
+
*/
|
|
332
|
+
function getTicks(ticks) {
|
|
333
|
+
if (typeof ticks !== "number" || ticks >= _ticksInMs) {
|
|
334
|
+
_ticks++
|
|
335
|
+
if (_ticks >= _ticksInMs) {
|
|
336
|
+
_ticks = 0
|
|
337
|
+
}
|
|
338
|
+
ticks = _ticks
|
|
339
|
+
}
|
|
340
|
+
return ticks
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Returns an object with the time representation of the date expressed in milliseconds since unix epoch
|
|
345
|
+
* and a ticks property for the 100-nanoseconds precision.
|
|
346
|
+
* @private
|
|
347
|
+
* @returns {{time: Number, ticks: Number}}
|
|
348
|
+
*/
|
|
349
|
+
function getTimeWithTicks(date, ticks) {
|
|
350
|
+
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
|
351
|
+
// time with ticks for the current time
|
|
352
|
+
date = new Date()
|
|
353
|
+
const time = date.getTime()
|
|
354
|
+
_ticksForCurrentTime++
|
|
355
|
+
if (_ticksForCurrentTime > _ticksInMs || time > _lastTimestamp) {
|
|
356
|
+
_ticksForCurrentTime = 0
|
|
357
|
+
_lastTimestamp = time
|
|
358
|
+
}
|
|
359
|
+
ticks = _ticksForCurrentTime
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
time: date.getTime(),
|
|
363
|
+
ticks: getTicks(ticks),
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function getRandomBytes(length) {
|
|
368
|
+
return crypto.randomBytes(length)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function getOrGenerateRandom(id, length, callback) {
|
|
372
|
+
if (id) {
|
|
373
|
+
return callback(null, id)
|
|
374
|
+
}
|
|
375
|
+
crypto.randomBytes(length, callback)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Generates a 16-length Buffer instance
|
|
380
|
+
* @private
|
|
381
|
+
* @param {Date} date
|
|
382
|
+
* @param {Number} ticks
|
|
383
|
+
* @param {String|Buffer} nodeId
|
|
384
|
+
* @param {String|Buffer} clockId
|
|
385
|
+
* @returns {Buffer}
|
|
386
|
+
*/
|
|
387
|
+
function generateBuffer(date, ticks, nodeId, clockId) {
|
|
388
|
+
const timeWithTicks = getTimeWithTicks(date, ticks)
|
|
389
|
+
nodeId = getNodeId(nodeId)
|
|
390
|
+
clockId = getClockId(clockId)
|
|
391
|
+
const buffer = utils.allocBufferUnsafe(16)
|
|
392
|
+
//Positions 0-7 Timestamp
|
|
393
|
+
writeTime(buffer, timeWithTicks.time, timeWithTicks.ticks)
|
|
394
|
+
//Position 8-9 Clock
|
|
395
|
+
clockId.copy(buffer, 8, 0)
|
|
396
|
+
//Positions 10-15 Node
|
|
397
|
+
nodeId.copy(buffer, 10, 0)
|
|
398
|
+
//Version Byte: Time based
|
|
399
|
+
//0001xxxx
|
|
400
|
+
//turn off first 4 bits
|
|
401
|
+
buffer[6] = buffer[6] & 0x0f
|
|
402
|
+
//turn on fifth bit
|
|
403
|
+
buffer[6] = buffer[6] | 0x10
|
|
404
|
+
|
|
405
|
+
//IETF Variant Byte: 1.0.x
|
|
406
|
+
//10xxxxxx
|
|
407
|
+
//turn off first 2 bits
|
|
408
|
+
buffer[8] = buffer[8] & 0x3f
|
|
409
|
+
//turn on first bit
|
|
410
|
+
buffer[8] = buffer[8] | 0x80
|
|
411
|
+
return buffer
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export default TimeUuid
|