@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,171 @@
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 errors from "../errors.js"
20
+ import utils from "../utils.js"
21
+
22
+ /**
23
+ * Provides utility methods to adapt and map user provided docInfo and executionOptions to a predictable object format.
24
+ * @ignore
25
+ */
26
+ class DocInfoAdapter {
27
+ /**
28
+ * Returns an Array where each item contains the property name, the column name and the property value (to obtain
29
+ * the operator).
30
+ * When docInfo.fields is specified, it uses that array to obtain the information.
31
+ * @param {Array<String>} docKeys
32
+ * @param {null|{fields}} docInfo
33
+ * @param {Object} doc
34
+ * @param {ModelMappingInfo} mappingInfo
35
+ * @returns {Array}
36
+ */
37
+ static getPropertiesInfo(docKeys, docInfo, doc, mappingInfo) {
38
+ let propertyKeys = docKeys
39
+ if (docInfo && docInfo.fields && docInfo.fields.length > 0) {
40
+ propertyKeys = docInfo.fields
41
+ }
42
+
43
+ return propertyKeys.map((propertyName) => ({
44
+ propertyName,
45
+ columnName: mappingInfo.getColumnName(propertyName),
46
+ value: doc[propertyName],
47
+ fromModel: mappingInfo.getFromModelFn(propertyName),
48
+ }))
49
+ }
50
+
51
+ /**
52
+ * @param {{orderBy}} docInfo
53
+ * @param {ModelMappingInfo} mappingInfo
54
+ * @returns {Array<String>}
55
+ */
56
+ static adaptOrderBy(docInfo, mappingInfo) {
57
+ if (!docInfo || !docInfo.orderBy) {
58
+ return utils.emptyArray
59
+ }
60
+ return Object.keys(docInfo.orderBy).map((key) => {
61
+ const value = docInfo.orderBy[key]
62
+ const ordering =
63
+ typeof value === "string" ? value.toUpperCase() : value
64
+ if (ordering !== "ASC" && ordering !== "DESC") {
65
+ throw new errors.ArgumentError(
66
+ 'Order must be either "ASC" or "DESC", obtained: ' + value,
67
+ )
68
+ }
69
+ return [mappingInfo.getColumnName(key), ordering]
70
+ })
71
+ }
72
+
73
+ /**
74
+ * Returns the QueryOptions for an INSERT/UPDATE/DELETE statement.
75
+ * @param {Object|String|undefined} executionOptions
76
+ * @param {Boolean} isIdempotent
77
+ */
78
+ static adaptOptions(executionOptions, isIdempotent) {
79
+ const options = {
80
+ prepare: true,
81
+ executionProfile: undefined,
82
+ timestamp: undefined,
83
+ isIdempotent: isIdempotent,
84
+ }
85
+
86
+ if (typeof executionOptions === "string") {
87
+ options.executionProfile = executionOptions
88
+ } else if (
89
+ executionOptions !== null &&
90
+ executionOptions !== undefined
91
+ ) {
92
+ options.executionProfile = executionOptions.executionProfile
93
+ options.timestamp = executionOptions.timestamp
94
+
95
+ if (executionOptions.isIdempotent !== undefined) {
96
+ options.isIdempotent = executionOptions.isIdempotent
97
+ }
98
+ }
99
+ return options
100
+ }
101
+
102
+ /**
103
+ * Returns the QueryOptions for a SELECT statement.
104
+ * @param {Object|String|undefined} executionOptions
105
+ * @param {Boolean} [overrideIdempotency]
106
+ */
107
+ static adaptAllOptions(executionOptions, overrideIdempotency) {
108
+ const options = {
109
+ prepare: true,
110
+ executionProfile: undefined,
111
+ fetchSize: undefined,
112
+ pageState: undefined,
113
+ timestamp: undefined,
114
+ isIdempotent: undefined,
115
+ }
116
+
117
+ if (typeof executionOptions === "string") {
118
+ options.executionProfile = executionOptions
119
+ } else if (
120
+ executionOptions !== null &&
121
+ executionOptions !== undefined
122
+ ) {
123
+ options.executionProfile = executionOptions.executionProfile
124
+ options.fetchSize = executionOptions.fetchSize
125
+ options.pageState = executionOptions.pageState
126
+ options.timestamp = executionOptions.timestamp
127
+ options.isIdempotent = executionOptions.isIdempotent
128
+ }
129
+
130
+ if (overrideIdempotency) {
131
+ options.isIdempotent = true
132
+ }
133
+
134
+ return options
135
+ }
136
+
137
+ /**
138
+ * Returns the QueryOptions for a batch statement.
139
+ * @param {Object|String|undefined} executionOptions
140
+ * @param {Boolean} isIdempotent
141
+ * @param {Boolean} isCounter
142
+ */
143
+ static adaptBatchOptions(executionOptions, isIdempotent, isCounter) {
144
+ const options = {
145
+ prepare: true,
146
+ executionProfile: undefined,
147
+ timestamp: undefined,
148
+ logged: undefined,
149
+ isIdempotent: isIdempotent,
150
+ counter: isCounter,
151
+ }
152
+
153
+ if (typeof executionOptions === "string") {
154
+ options.executionProfile = executionOptions
155
+ } else if (
156
+ executionOptions !== null &&
157
+ executionOptions !== undefined
158
+ ) {
159
+ options.executionProfile = executionOptions.executionProfile
160
+ options.timestamp = executionOptions.timestamp
161
+ options.logged = executionOptions.logged !== false
162
+
163
+ if (executionOptions.isIdempotent !== undefined) {
164
+ options.isIdempotent = executionOptions.isIdempotent
165
+ }
166
+ }
167
+ return options
168
+ }
169
+ }
170
+
171
+ export default DocInfoAdapter
@@ -0,0 +1,219 @@
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 { types } from "../types"
20
+ import { Client } from ".."
21
+ import Long = types.Long
22
+
23
+ export namespace mapping {
24
+ interface TableMappings {
25
+ getColumnName(propName: string): string
26
+
27
+ getPropertyName(columnName: string): string
28
+
29
+ newObjectInstance(): any
30
+ }
31
+
32
+ class DefaultTableMappings implements TableMappings {
33
+ getColumnName(propName: string): string
34
+
35
+ getPropertyName(columnName: string): string
36
+
37
+ newObjectInstance(): any
38
+ }
39
+
40
+ class UnderscoreCqlToCamelCaseMappings implements TableMappings {
41
+ getColumnName(propName: string): string
42
+
43
+ getPropertyName(columnName: string): string
44
+
45
+ newObjectInstance(): any
46
+ }
47
+
48
+ interface Result<T = any> extends Iterator<T> {
49
+ wasApplied(): boolean
50
+
51
+ first(): T | null
52
+
53
+ forEach(
54
+ callback: (currentValue: T, index: number) => void,
55
+ thisArg?: any,
56
+ ): void
57
+
58
+ toArray(): T[]
59
+ }
60
+
61
+ type MappingExecutionOptions = {
62
+ executionProfile?: string
63
+ isIdempotent?: boolean
64
+ logged?: boolean
65
+ timestamp?: number | Long
66
+ fetchSize?: number
67
+ pageState?: number
68
+ }
69
+
70
+ interface ModelTables {
71
+ name: string
72
+ isView: boolean
73
+ }
74
+
75
+ class Mapper {
76
+ constructor(client: Client, options?: MappingOptions)
77
+
78
+ batch(
79
+ items: ModelBatchItem[],
80
+ executionOptions?: string | MappingExecutionOptions,
81
+ ): Promise<Result>
82
+
83
+ forModel<T = any>(name: string): ModelMapper<T>
84
+ }
85
+
86
+ type MappingOptions = {
87
+ models: { [key: string]: ModelOptions }
88
+ }
89
+
90
+ type FindDocInfo = {
91
+ fields?: string[]
92
+ orderBy?: { [key: string]: string }
93
+ limit?: number
94
+ }
95
+
96
+ type InsertDocInfo = {
97
+ fields?: string[]
98
+ ttl?: number
99
+ ifNotExists?: boolean
100
+ }
101
+
102
+ type UpdateDocInfo = {
103
+ fields?: string[]
104
+ ttl?: number
105
+ ifExists?: boolean
106
+ when?: { [key: string]: any }
107
+ orderBy?: { [key: string]: string }
108
+ limit?: number
109
+ deleteOnlyColumns?: boolean
110
+ }
111
+
112
+ type RemoveDocInfo = {
113
+ fields?: string[]
114
+ ttl?: number
115
+ ifExists?: boolean
116
+ when?: { [key: string]: any }
117
+ deleteOnlyColumns?: boolean
118
+ }
119
+
120
+ type ModelOptions = {
121
+ tables?: string[] | ModelTables[]
122
+ mappings?: TableMappings
123
+ columns?: { [key: string]: string | ModelColumnOptions }
124
+ keyspace?: string
125
+ }
126
+
127
+ type ModelColumnOptions = {
128
+ name: string
129
+ toModel?: (columnValue: any) => any
130
+ fromModel?: (modelValue: any) => any
131
+ }
132
+
133
+ interface ModelBatchItem {}
134
+
135
+ interface ModelBatchMapper {
136
+ insert(doc: any, docInfo?: InsertDocInfo): ModelBatchItem
137
+
138
+ remove(doc: any, docInfo?: RemoveDocInfo): ModelBatchItem
139
+
140
+ update(doc: any, docInfo?: UpdateDocInfo): ModelBatchItem
141
+ }
142
+
143
+ interface ModelMapper<T = any> {
144
+ name: string
145
+ batching: ModelBatchMapper
146
+
147
+ get(
148
+ doc: { [key: string]: any },
149
+ docInfo?: { fields?: string[] },
150
+ executionOptions?: string | MappingExecutionOptions,
151
+ ): Promise<null | T>
152
+
153
+ find(
154
+ doc: { [key: string]: any },
155
+ docInfo?: FindDocInfo,
156
+ executionOptions?: string | MappingExecutionOptions,
157
+ ): Promise<Result<T>>
158
+
159
+ findAll(
160
+ docInfo?: FindDocInfo,
161
+ executionOptions?: string | MappingExecutionOptions,
162
+ ): Promise<Result<T>>
163
+
164
+ insert(
165
+ doc: { [key: string]: any },
166
+ docInfo?: InsertDocInfo,
167
+ executionOptions?: string | MappingExecutionOptions,
168
+ ): Promise<Result<T>>
169
+
170
+ update(
171
+ doc: { [key: string]: any },
172
+ docInfo?: UpdateDocInfo,
173
+ executionOptions?: string | MappingExecutionOptions,
174
+ ): Promise<Result<T>>
175
+
176
+ remove(
177
+ doc: { [key: string]: any },
178
+ docInfo?: RemoveDocInfo,
179
+ executionOptions?: string | MappingExecutionOptions,
180
+ ): Promise<Result<T>>
181
+
182
+ mapWithQuery(
183
+ query: string,
184
+ paramsHandler: (doc: any) => any[],
185
+ executionOptions?: string | MappingExecutionOptions,
186
+ ): (
187
+ doc: any,
188
+ executionOptions?: string | MappingExecutionOptions,
189
+ ) => Promise<Result<T>>
190
+ }
191
+
192
+ namespace q {
193
+ interface QueryOperator {}
194
+
195
+ function in_(arr: any): QueryOperator
196
+
197
+ function gt(value: any): QueryOperator
198
+
199
+ function gte(value: any): QueryOperator
200
+
201
+ function lt(value: any): QueryOperator
202
+
203
+ function lte(value: any): QueryOperator
204
+
205
+ function notEq(value: any): QueryOperator
206
+
207
+ function and(condition1: any, condition2: any): QueryOperator
208
+
209
+ function incr(value: any): QueryOperator
210
+
211
+ function decr(value: any): QueryOperator
212
+
213
+ function append(value: any): QueryOperator
214
+
215
+ function prepend(value: any): QueryOperator
216
+
217
+ function remove(value: any): QueryOperator
218
+ }
219
+ }
@@ -0,0 +1,57 @@
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
+ /**
20
+ * Module containing classes and fields related to the Mapper.
21
+ * @module mapping
22
+ */
23
+
24
+ import Mapper from "./mapper.js"
25
+ import ModelMapper from "./model-mapper.js"
26
+ import ModelBatchMapper from "./model-batch-mapper.js"
27
+ import { ModelBatchItem } from "./model-batch-item.js"
28
+ import Result from "./result.js"
29
+ import {
30
+ TableMappings,
31
+ DefaultTableMappings,
32
+ UnderscoreCqlToCamelCaseMappings,
33
+ } from "./table-mappings.js"
34
+ import { q } from "./q.js"
35
+
36
+ export {
37
+ Mapper,
38
+ ModelMapper,
39
+ ModelBatchMapper,
40
+ ModelBatchItem,
41
+ Result,
42
+ TableMappings,
43
+ DefaultTableMappings,
44
+ UnderscoreCqlToCamelCaseMappings,
45
+ q,
46
+ }
47
+ export default {
48
+ Mapper,
49
+ ModelMapper,
50
+ ModelBatchMapper,
51
+ ModelBatchItem,
52
+ Result,
53
+ TableMappings,
54
+ DefaultTableMappings,
55
+ UnderscoreCqlToCamelCaseMappings,
56
+ q,
57
+ }
@@ -0,0 +1,225 @@
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 ModelMapper from "./model-mapper.js"
20
+ import MappingHandler from "./mapping-handler.js"
21
+ import DocInfoAdapter from "./doc-info-adapter.js"
22
+ import errors from "../errors.js"
23
+ import Result from "./result.js"
24
+ import ResultMapper from "./result-mapper.js"
25
+ import ModelMappingInfo from "./model-mapping-info.js"
26
+ import { ModelBatchItem } from "./model-batch-item.js"
27
+
28
+ /**
29
+ * Represents an object mapper for Apache Cassandra and DataStax Enterprise.
30
+ * @alias module:mapping~Mapper
31
+ * @example <caption>Creating a Mapper instance with some options for the model 'User'</caption>
32
+ * const mappingOptions = {
33
+ * models: {
34
+ * 'User': {
35
+ * tables: ['users'],
36
+ * mappings: new UnderscoreCqlToCamelCaseMappings(),
37
+ * columnNames: {
38
+ * 'userid': 'id'
39
+ * }
40
+ * }
41
+ * }
42
+ * };
43
+ * const mapper = new Mapper(client, mappingOptions);
44
+ * @example <caption>Creating a Mapper instance with other possible options for a model</caption>
45
+ * const mappingOptions = {
46
+ * models: {
47
+ * 'Video': {
48
+ * tables: ['videos', 'user_videos', 'latest_videos', { name: 'my_videos_view', isView: true }],
49
+ * mappings: new UnderscoreCqlToCamelCaseMappings(),
50
+ * columnNames: {
51
+ * 'videoid': 'id'
52
+ * },
53
+ * keyspace: 'ks1'
54
+ * }
55
+ * }
56
+ * };
57
+ * const mapper = new Mapper(client, mappingOptions);
58
+ */
59
+ class Mapper {
60
+ /**
61
+ * Creates a new instance of Mapper.
62
+ * @param {Client} client The Client instance to use to execute the queries and fetch the metadata.
63
+ * @param {MappingOptions} [options] The [MappingOptions]{@link module:mapping~MappingOptions} containing the
64
+ * information of the models and table mappings.
65
+ */
66
+ constructor(client, options) {
67
+ if (!client) {
68
+ throw new Error("client must be defined")
69
+ }
70
+
71
+ /**
72
+ * The Client instance used to create this Mapper instance.
73
+ * @type {Client}
74
+ */
75
+ this.client = client
76
+
77
+ this._modelMappingInfos = ModelMappingInfo.parse(
78
+ options,
79
+ client.keyspace,
80
+ )
81
+ this._modelMappers = new Map()
82
+ }
83
+
84
+ /**
85
+ * Gets a [ModelMapper]{@link module:mapping~ModelMapper} that is able to map documents of a certain model into
86
+ * CQL rows.
87
+ * @param {String} name The name to identify the model. Note that the name is case-sensitive.
88
+ * @returns {ModelMapper} A [ModelMapper]{@link module:mapping~ModelMapper} instance.
89
+ */
90
+ forModel(name) {
91
+ let modelMapper = this._modelMappers.get(name)
92
+
93
+ if (modelMapper === undefined) {
94
+ let mappingInfo = this._modelMappingInfos.get(name)
95
+
96
+ if (mappingInfo === undefined) {
97
+ if (!this.client.keyspace) {
98
+ throw new Error(
99
+ `No mapping information found for model '${name}'. ` +
100
+ `Mapper is unable to create default mappings without setting the keyspace`,
101
+ )
102
+ }
103
+
104
+ mappingInfo = ModelMappingInfo.createDefault(
105
+ name,
106
+ this.client.keyspace,
107
+ )
108
+ this.client.log(
109
+ "info",
110
+ `Mapping information for model '${name}' not found, creating default mapping. ` +
111
+ `Keyspace: ${mappingInfo.keyspace}; Table: ${mappingInfo.tables[0].name}.`,
112
+ )
113
+ } else {
114
+ this.client.log(
115
+ "info",
116
+ `Creating model mapper for '${name}' using mapping information. Keyspace: ${
117
+ mappingInfo.keyspace
118
+ }; Table${mappingInfo.tables.length > 1 ? "s" : ""}: ${mappingInfo.tables.map(
119
+ (t) => t.name,
120
+ )}.`,
121
+ )
122
+ }
123
+
124
+ modelMapper = new ModelMapper(
125
+ name,
126
+ new MappingHandler(this.client, mappingInfo),
127
+ )
128
+ this._modelMappers.set(name, modelMapper)
129
+ }
130
+
131
+ return modelMapper
132
+ }
133
+
134
+ /**
135
+ * Executes a batch of queries represented in the items.
136
+ * @param {Array<ModelBatchItem>} items
137
+ * @param {Object|String} [executionOptions] An object containing the options to be used for the requests
138
+ * execution or a string representing the name of the execution profile.
139
+ * @param {String} [executionOptions.executionProfile] The name of the execution profile.
140
+ * @param {Boolean} [executionOptions.isIdempotent] Defines whether the query can be applied multiple times without
141
+ * changing the result beyond the initial application.
142
+ * <p>
143
+ * The mapper uses the generated queries to determine the default value. When an UPDATE is generated with a
144
+ * counter column or appending/prepending to a list column, the execution is marked as not idempotent.
145
+ * </p>
146
+ * <p>
147
+ * Additionally, the mapper uses the safest approach for queries with lightweight transactions (Compare and
148
+ * Set) by considering them as non-idempotent. Lightweight transactions at client level with transparent retries can
149
+ * break linearizability. If that is not an issue for your application, you can manually set this field to true.
150
+ * </p>
151
+ * @param {Boolean} [executionOptions.logged=true] Determines whether the batch should be written to the batchlog.
152
+ * @param {Number|Long} [executionOptions.timestamp] The default timestamp for the query in microseconds from the
153
+ * unix epoch (00:00:00, January 1st, 1970).
154
+ * @returns {Promise<Result>} A Promise that resolves to a [Result]{@link module:mapping~Result}.
155
+ */
156
+ batch(items, executionOptions) {
157
+ if (!Array.isArray(items) || !(items.length > 0)) {
158
+ return Promise.reject(
159
+ new errors.ArgumentError(
160
+ "First parameter items should be an Array with 1 or more ModelBatchItem instances",
161
+ ),
162
+ )
163
+ }
164
+
165
+ const queries = []
166
+ let isIdempotent = true
167
+ let isCounter
168
+
169
+ return Promise.all(
170
+ items.map((item) => {
171
+ if (!(item instanceof ModelBatchItem)) {
172
+ return Promise.reject(
173
+ new Error(
174
+ "Batch items must be instances of ModelBatchItem, use modelMapper.batching object to create each item",
175
+ ),
176
+ )
177
+ }
178
+
179
+ return item.pushQueries(queries).then((options) => {
180
+ // The batch is idempotent when all the queries contained are idempotent
181
+ isIdempotent = isIdempotent && options.isIdempotent
182
+
183
+ // Let it fail at server level when there is a mix of counter and normal mutations
184
+ isCounter = options.isCounter
185
+ })
186
+ }),
187
+ )
188
+ .then(() =>
189
+ this.client.batch(
190
+ queries,
191
+ DocInfoAdapter.adaptBatchOptions(
192
+ executionOptions,
193
+ isIdempotent,
194
+ isCounter,
195
+ ),
196
+ ),
197
+ )
198
+ .then((rs) => {
199
+ // Results should only be adapted when the batch contains LWT (single table)
200
+ const info = items[0].getMappingInfo()
201
+ return new Result(rs, info, ResultMapper.getMutationAdapter(rs))
202
+ })
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Represents the mapping options.
208
+ * @typedef {Object} module:mapping~MappingOptions
209
+ * @property {Object<String, ModelOptions>} models An associative array containing the
210
+ * name of the model as key and the table and column information as value.
211
+ */
212
+
213
+ /**
214
+ * Represents a set of options that applies to a certain model.
215
+ * @typedef {Object} module:mapping~ModelOptions
216
+ * @property {Array<String>|Array<{name, isView}>} tables An Array containing the name of the tables or An Array
217
+ * containing the name and isView property to describe the table.
218
+ * @property {TableMappings} mappings The TableMappings implementation instance that is used to convert from column
219
+ * names to property names and the other way around.
220
+ * @property {Object.<String, String>} [columnNames] An associative array containing the name of the columns and
221
+ * properties that doesn't follow the convention defined in the <code>TableMappings</code>.
222
+ * @property {String} [keyspace] The name of the keyspace. Only mandatory when the Client is not using a keyspace.
223
+ */
224
+
225
+ export default Mapper