@twin.org/entity-storage-connector-scylladb 0.0.2-next.9 → 0.0.3-next.2
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/dist/es/abstractScyllaDBConnector.js +545 -0
- package/dist/es/abstractScyllaDBConnector.js.map +1 -0
- package/dist/es/index.js +10 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/models/IScyllaDBConfig.js +4 -0
- package/dist/es/models/IScyllaDBConfig.js.map +1 -0
- package/dist/es/models/IScyllaDBTableConfig.js +2 -0
- package/dist/es/models/IScyllaDBTableConfig.js.map +1 -0
- package/dist/es/models/IScyllaDBTableConnectorConstructorOptions.js +2 -0
- package/dist/es/models/IScyllaDBTableConnectorConstructorOptions.js.map +1 -0
- package/dist/es/models/IScyllaDBViewConfig.js +2 -0
- package/dist/es/models/IScyllaDBViewConfig.js.map +1 -0
- package/dist/es/models/IScyllaDBViewConnectorConstructorOptions.js +2 -0
- package/dist/es/models/IScyllaDBViewConnectorConstructorOptions.js.map +1 -0
- package/dist/es/scyllaDBTableConnector.js +377 -0
- package/dist/es/scyllaDBTableConnector.js.map +1 -0
- package/dist/es/scyllaDBViewConnector.js +130 -0
- package/dist/es/scyllaDBViewConnector.js.map +1 -0
- package/dist/types/abstractScyllaDBConnector.d.ts +16 -6
- package/dist/types/index.d.ts +7 -7
- package/dist/types/models/IScyllaDBTableConfig.d.ts +1 -1
- package/dist/types/models/IScyllaDBTableConnectorConstructorOptions.d.ts +5 -1
- package/dist/types/models/IScyllaDBViewConfig.d.ts +1 -1
- package/dist/types/models/IScyllaDBViewConnectorConstructorOptions.d.ts +5 -1
- package/dist/types/scyllaDBTableConnector.d.ts +8 -9
- package/dist/types/scyllaDBViewConnector.d.ts +8 -3
- package/docs/changelog.md +62 -0
- package/docs/reference/classes/ScyllaDBTableConnector.md +28 -10
- package/docs/reference/classes/ScyllaDBViewConnector.md +28 -10
- package/docs/reference/interfaces/IScyllaDBTableConnectorConstructorOptions.md +8 -0
- package/docs/reference/interfaces/IScyllaDBViewConnectorConstructorOptions.md +8 -0
- package/locales/en.json +16 -6
- package/package.json +12 -9
- package/dist/cjs/index.cjs +0 -900
- package/dist/esm/index.mjs +0 -897
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { ContextIdHelper, ContextIdStore } from "@twin.org/context";
|
|
4
|
+
import { Coerce, ComponentFactory, GeneralError, Guards, Is, ObjectHelper, StringHelper } from "@twin.org/core";
|
|
5
|
+
import { ComparisonOperator, EntitySchemaFactory, EntitySchemaHelper, LogicalOperator, SortDirection } from "@twin.org/entity";
|
|
6
|
+
import { types as CassandraTypes, Client } from "cassandra-driver";
|
|
7
|
+
/**
|
|
8
|
+
* Store entities using ScyllaDB.
|
|
9
|
+
*/
|
|
10
|
+
export class AbstractScyllaDBConnector {
|
|
11
|
+
/**
|
|
12
|
+
* Runtime name for the class.
|
|
13
|
+
*/
|
|
14
|
+
static CLASS_NAME = "AbstractScyllaDBConnector";
|
|
15
|
+
/**
|
|
16
|
+
* Partition id field name.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
static PARTITION_KEY = "partitionId";
|
|
20
|
+
/**
|
|
21
|
+
* Partition id field value.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
static PARTITION_KEY_VALUE = "root";
|
|
25
|
+
/**
|
|
26
|
+
* Limit the number of entities when finding.
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
static _DEFAULT_LIMIT = 40;
|
|
30
|
+
/**
|
|
31
|
+
* The name of the database table.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
_fullTableName;
|
|
35
|
+
/**
|
|
36
|
+
* Configuration to connection to ScyllaDB.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
_config;
|
|
40
|
+
/**
|
|
41
|
+
* The logging component.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
_logging;
|
|
45
|
+
/**
|
|
46
|
+
* The schema for the entity.
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
_entitySchema;
|
|
50
|
+
/**
|
|
51
|
+
* The keys to use from the context ids to create partitions.
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
_partitionContextIds;
|
|
55
|
+
/**
|
|
56
|
+
* The primary key.
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
_primaryKey;
|
|
60
|
+
/**
|
|
61
|
+
* Create a new instance of AbstractScyllaDBConnector.
|
|
62
|
+
* @param options The options for the connector.
|
|
63
|
+
* @param options.loggingComponentType The type of logging component to use, defaults to no logging.
|
|
64
|
+
* @param options.entitySchema The name of the entity schema.
|
|
65
|
+
* @param options.partitionContextIds The keys to use from the context ids to create partitions.
|
|
66
|
+
* @param options.config The configuration for the connector.
|
|
67
|
+
*/
|
|
68
|
+
constructor(options) {
|
|
69
|
+
Guards.object(AbstractScyllaDBConnector.CLASS_NAME, "options", options);
|
|
70
|
+
Guards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, "options.entitySchema", options.entitySchema);
|
|
71
|
+
Guards.object(AbstractScyllaDBConnector.CLASS_NAME, "options.config", options.config);
|
|
72
|
+
Guards.arrayValue(AbstractScyllaDBConnector.CLASS_NAME, "options.config.hosts", options.config.hosts);
|
|
73
|
+
Guards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, "options.config.localDataCenter", options.config.localDataCenter);
|
|
74
|
+
Guards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, "options.config.keyspace", options.config.keyspace);
|
|
75
|
+
this._logging = ComponentFactory.getIfExists(options.loggingComponentType ?? "logging");
|
|
76
|
+
this._entitySchema = EntitySchemaFactory.get(options.entitySchema);
|
|
77
|
+
this._partitionContextIds = options.partitionContextIds;
|
|
78
|
+
this._primaryKey = EntitySchemaHelper.getPrimaryKey(this._entitySchema);
|
|
79
|
+
this._config = options.config;
|
|
80
|
+
this._fullTableName = StringHelper.camelCase(Is.stringValue(options.config.tableName) ? options.config.tableName : options.entitySchema);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Returns the class name of the component.
|
|
84
|
+
* @returns The class name of the component.
|
|
85
|
+
*/
|
|
86
|
+
className() {
|
|
87
|
+
return AbstractScyllaDBConnector.CLASS_NAME;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get the schema for the entities.
|
|
91
|
+
* @returns The schema for the entities.
|
|
92
|
+
*/
|
|
93
|
+
getSchema() {
|
|
94
|
+
return this._entitySchema;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get an entity.
|
|
98
|
+
* @param id The id of the entity to get.
|
|
99
|
+
* @param secondaryIndex Get the item using a secondary index.
|
|
100
|
+
* @param conditions The optional conditions to match for the entities.
|
|
101
|
+
* @returns The object if it can be found or undefined.
|
|
102
|
+
*/
|
|
103
|
+
async get(id, secondaryIndex, conditions) {
|
|
104
|
+
Guards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, "id", id);
|
|
105
|
+
const contextIds = await ContextIdStore.getContextIds();
|
|
106
|
+
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
107
|
+
let connection;
|
|
108
|
+
try {
|
|
109
|
+
const indexField = secondaryIndex ?? this._primaryKey?.property;
|
|
110
|
+
conditions ??= [];
|
|
111
|
+
conditions.unshift({
|
|
112
|
+
property: AbstractScyllaDBConnector.PARTITION_KEY,
|
|
113
|
+
value: partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE
|
|
114
|
+
});
|
|
115
|
+
conditions.unshift({
|
|
116
|
+
property: indexField,
|
|
117
|
+
value: id
|
|
118
|
+
});
|
|
119
|
+
const { sqlCondition, conditionValues } = this.buildConditions(conditions);
|
|
120
|
+
let sql = `SELECT * FROM "${this._fullTableName}" WHERE ${sqlCondition}`;
|
|
121
|
+
if (secondaryIndex) {
|
|
122
|
+
sql += " ALLOW FILTERING";
|
|
123
|
+
}
|
|
124
|
+
await this._logging?.log({
|
|
125
|
+
level: "info",
|
|
126
|
+
source: AbstractScyllaDBConnector.CLASS_NAME,
|
|
127
|
+
ts: Date.now(),
|
|
128
|
+
message: "sql",
|
|
129
|
+
data: { sql }
|
|
130
|
+
});
|
|
131
|
+
connection = await this.openConnection();
|
|
132
|
+
const result = await this.queryDB(connection, sql, conditionValues);
|
|
133
|
+
if (result.rows.length === 1) {
|
|
134
|
+
return this.convertRowToObject(this._entitySchema.properties, result.rows[0]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, "getFailed", {
|
|
139
|
+
id
|
|
140
|
+
}, error);
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
await this.closeConnection(connection);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Find all the entities which match the conditions.
|
|
148
|
+
* @param conditions The conditions to match for the entities.
|
|
149
|
+
* @param sortProperties The optional sort order.
|
|
150
|
+
* @param properties The optional properties to return, defaults to all.
|
|
151
|
+
* @param cursor The cursor to request the next chunk of entities.
|
|
152
|
+
* @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.
|
|
153
|
+
* @returns All the entities for the storage matching the conditions,
|
|
154
|
+
* and a cursor which can be used to request more entities.
|
|
155
|
+
*/
|
|
156
|
+
async query(conditions, sortProperties, properties, cursor, limit) {
|
|
157
|
+
let connection;
|
|
158
|
+
const contextIds = await ContextIdStore.getContextIds();
|
|
159
|
+
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
160
|
+
try {
|
|
161
|
+
let returnSize = limit ?? AbstractScyllaDBConnector._DEFAULT_LIMIT;
|
|
162
|
+
let sql = `SELECT * FROM "${this._fullTableName}"`;
|
|
163
|
+
if (Is.array(properties)) {
|
|
164
|
+
const fields = [];
|
|
165
|
+
for (const property of properties) {
|
|
166
|
+
fields.push(property.toString());
|
|
167
|
+
}
|
|
168
|
+
const selectFields = fields.join(",");
|
|
169
|
+
sql = sql.replace("*", selectFields);
|
|
170
|
+
}
|
|
171
|
+
const conds = [];
|
|
172
|
+
let conditionQuery = "";
|
|
173
|
+
// The params to be used to execute the query
|
|
174
|
+
const params = [];
|
|
175
|
+
let finalConditionQuery = `"${AbstractScyllaDBConnector.PARTITION_KEY}" = ?`;
|
|
176
|
+
params.push(partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE);
|
|
177
|
+
let theConditions = [];
|
|
178
|
+
if (!Is.undefined(conditions)) {
|
|
179
|
+
if ("conditions" in conditions) {
|
|
180
|
+
theConditions = conditions.conditions;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
theConditions.push(conditions);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// TODO: This code needs refactoring to support conditions for sub properties.
|
|
187
|
+
for (const cond of theConditions) {
|
|
188
|
+
const condition = cond;
|
|
189
|
+
const descriptor = this._entitySchema.properties?.find(p => p.property === condition.property);
|
|
190
|
+
if (condition.comparison === ComparisonOperator.Includes ||
|
|
191
|
+
condition.comparison === ComparisonOperator.NotIncludes) {
|
|
192
|
+
const propValue = `'%${condition.value?.toString()}%'`;
|
|
193
|
+
if (condition.comparison === ComparisonOperator.Includes) {
|
|
194
|
+
conds.push(`"${condition.property}" LIKE ${propValue}`);
|
|
195
|
+
}
|
|
196
|
+
else if (condition.comparison === ComparisonOperator.NotIncludes) {
|
|
197
|
+
conds.push(`"${condition.property}" NOT LIKE ${propValue}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else if (condition.comparison === ComparisonOperator.In) {
|
|
201
|
+
let value = [];
|
|
202
|
+
if (!Is.arrayValue(condition.value)) {
|
|
203
|
+
value.push(this.propertyToDbValue(condition.value, descriptor));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
value = condition.value.map(v => this.propertyToDbValue(v, descriptor));
|
|
207
|
+
}
|
|
208
|
+
params.push(value);
|
|
209
|
+
conds.push(`"${condition.property}" IN ?`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const propValue = condition.value;
|
|
213
|
+
params.push(propValue);
|
|
214
|
+
if (condition.comparison === ComparisonOperator.Equals) {
|
|
215
|
+
conds.push(`"${condition.property}" = ?`);
|
|
216
|
+
}
|
|
217
|
+
else if (condition.comparison === ComparisonOperator.NotEquals) {
|
|
218
|
+
conds.push(`"${condition.property}" <> ?`);
|
|
219
|
+
}
|
|
220
|
+
else if (condition.comparison === ComparisonOperator.GreaterThan) {
|
|
221
|
+
conds.push(`"${condition.property}" > ?`);
|
|
222
|
+
}
|
|
223
|
+
else if (condition.comparison === ComparisonOperator.LessThan) {
|
|
224
|
+
conds.push(`"${condition.property}" < ?`);
|
|
225
|
+
}
|
|
226
|
+
else if (condition.comparison === ComparisonOperator.GreaterThanOrEqual) {
|
|
227
|
+
conds.push(`"${condition.property}" >= ?`);
|
|
228
|
+
}
|
|
229
|
+
else if (condition.comparison === ComparisonOperator.LessThanOrEqual) {
|
|
230
|
+
conds.push(`"${condition.property}" <= ?`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const operator = conditions.logicalOperator ?? LogicalOperator.And;
|
|
234
|
+
conditionQuery = `${conds.join(` ${operator} `)}`;
|
|
235
|
+
}
|
|
236
|
+
if (conditionQuery.length > 0) {
|
|
237
|
+
finalConditionQuery += ` AND (${conditionQuery})`;
|
|
238
|
+
}
|
|
239
|
+
sql += ` WHERE ${finalConditionQuery}`;
|
|
240
|
+
connection = await this.openConnection();
|
|
241
|
+
// TODO: Only supported one sort property at the moment. This code would need to be revised in a follow-up
|
|
242
|
+
if (Is.array(sortProperties) && sortProperties.length >= 1) {
|
|
243
|
+
const sortKey = sortProperties[0].property ?? this._primaryKey.property;
|
|
244
|
+
const sortDir = sortProperties[0].sortDirection ??
|
|
245
|
+
this._entitySchema.properties?.find(e => e.property === sortKey)?.sortDirection;
|
|
246
|
+
let sqlSortDir = "asc";
|
|
247
|
+
if (sortDir === SortDirection.Descending) {
|
|
248
|
+
sqlSortDir = "desc";
|
|
249
|
+
}
|
|
250
|
+
sql += ` ORDER BY "${String(sortKey)}" ${sqlSortDir.toUpperCase()}`;
|
|
251
|
+
// Disabling paging in order by situations
|
|
252
|
+
returnSize = 0;
|
|
253
|
+
}
|
|
254
|
+
sql += " ALLOW FILTERING";
|
|
255
|
+
await this._logging?.log({
|
|
256
|
+
level: "info",
|
|
257
|
+
source: AbstractScyllaDBConnector.CLASS_NAME,
|
|
258
|
+
ts: Date.now(),
|
|
259
|
+
message: "sql",
|
|
260
|
+
data: { sql }
|
|
261
|
+
});
|
|
262
|
+
const result = await this.queryDB(connection, sql, params, cursor, returnSize);
|
|
263
|
+
const entities = [];
|
|
264
|
+
for (const row of result.rows) {
|
|
265
|
+
entities.push(this.convertRowToObject(this._entitySchema.properties, row));
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
entities,
|
|
269
|
+
cursor: Is.stringValue(result.pageState) ? result.pageState : undefined
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
throw new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, "findFailed", { table: this._fullTableName }, error);
|
|
274
|
+
}
|
|
275
|
+
finally {
|
|
276
|
+
await this.closeConnection(connection);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Open a new database connection.
|
|
281
|
+
* @param config The config for the connection.
|
|
282
|
+
* @param skipKeySpace Don't include the keyspace in the connection.
|
|
283
|
+
* @returns The new connection.
|
|
284
|
+
* @internal
|
|
285
|
+
*/
|
|
286
|
+
async openConnection(skipKeySpace = false) {
|
|
287
|
+
const client = new Client({
|
|
288
|
+
contactPoints: this._config.hosts,
|
|
289
|
+
localDataCenter: this._config.localDataCenter,
|
|
290
|
+
keyspace: skipKeySpace ? undefined : this._config.keyspace,
|
|
291
|
+
protocolOptions: {
|
|
292
|
+
port: this._config.port
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
await client.connect();
|
|
296
|
+
return client;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Close database connection.
|
|
300
|
+
* @param connection The connection to close.
|
|
301
|
+
* @internal
|
|
302
|
+
*/
|
|
303
|
+
async closeConnection(connection) {
|
|
304
|
+
if (!connection) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
return connection.shutdown();
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Query the database.
|
|
311
|
+
* @param connection The connection to query.
|
|
312
|
+
* @param sql The sql statement to execute.
|
|
313
|
+
* @param params The params to use when executing the query.
|
|
314
|
+
* @param state The state to use when it comes to pagination.
|
|
315
|
+
* @returns The rows.
|
|
316
|
+
* @internal
|
|
317
|
+
*/
|
|
318
|
+
async queryDB(connection, sql, params, pageState, limit) {
|
|
319
|
+
return new Promise((resolve, reject) => {
|
|
320
|
+
const rows = [];
|
|
321
|
+
connection.eachRow(sql, params, {
|
|
322
|
+
prepare: true,
|
|
323
|
+
autoPage: false,
|
|
324
|
+
fetchSize: limit ?? AbstractScyllaDBConnector._DEFAULT_LIMIT,
|
|
325
|
+
pageState
|
|
326
|
+
}, (n, row) => {
|
|
327
|
+
rows.push(row);
|
|
328
|
+
}, (err, res) => {
|
|
329
|
+
if (err) {
|
|
330
|
+
reject(err);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
res.rows = rows;
|
|
334
|
+
resolve(res);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Execute on the database.
|
|
340
|
+
* @param connection The connection to execute.
|
|
341
|
+
* @param sql The sql statement to execute.
|
|
342
|
+
* @internal
|
|
343
|
+
*/
|
|
344
|
+
async execute(connection, sql, params) {
|
|
345
|
+
return connection.execute(sql, params, { prepare: true });
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Create keyspace if it doesn't exist.
|
|
349
|
+
* @param connection The connection to perform the query with.
|
|
350
|
+
* @param keyspaceName The name of the keyspace to create.
|
|
351
|
+
* @internal
|
|
352
|
+
*/
|
|
353
|
+
async createKeyspace(connection, keyspaceName) {
|
|
354
|
+
return this.execute(connection, `CREATE KEYSPACE IF NOT EXISTS "${keyspaceName}" WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1}`);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Check if a keyspace exists.
|
|
358
|
+
* @param connection The connection to perform the query with.
|
|
359
|
+
* @param keyspaceName The name of the keyspace to check.
|
|
360
|
+
* @returns True if the keyspace exists, false otherwise.
|
|
361
|
+
* @internal
|
|
362
|
+
*/
|
|
363
|
+
async checkKeyspaceExists(connection, keyspaceName) {
|
|
364
|
+
const result = await this.queryDB(connection, "SELECT keyspace_name FROM system_schema.keyspaces WHERE keyspace_name = ?", [keyspaceName]);
|
|
365
|
+
return result.rowLength > 0;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Check if a type exists.
|
|
369
|
+
* @param connection The connection to perform the query with.
|
|
370
|
+
* @param typeName The name of the type to check.
|
|
371
|
+
* @returns True if the type exists, false otherwise.
|
|
372
|
+
* @internal
|
|
373
|
+
*/
|
|
374
|
+
async checkTypeExists(connection, typeName) {
|
|
375
|
+
const result = await this.queryDB(connection, "SELECT type_name FROM system_schema.types WHERE type_name = ?", [typeName]);
|
|
376
|
+
return result.rowLength > 0;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Check if a table exists.
|
|
380
|
+
* @param connection The connection to perform the query with.
|
|
381
|
+
* @param keyspaceName The name of the keyspace to check.
|
|
382
|
+
* @param tableName The name of the table to check.
|
|
383
|
+
* @returns True if the table exists, false otherwise.
|
|
384
|
+
* @internal
|
|
385
|
+
*/
|
|
386
|
+
async checkTableExists(connection, keyspaceName, tableName) {
|
|
387
|
+
const result = await this.queryDB(connection, "SELECT table_name FROM system_schema.tables WHERE keyspace_name = ? AND table_name = ?", [keyspaceName, tableName]);
|
|
388
|
+
return result.rowLength > 0;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Format a field from the DB.
|
|
392
|
+
* @param value The value to convert to original form.
|
|
393
|
+
* @param fieldDescriptor The descriptor for the field.
|
|
394
|
+
* @returns The value as a property for the object.
|
|
395
|
+
* @internal
|
|
396
|
+
*/
|
|
397
|
+
dbValueToProperty(value, fieldDescriptor) {
|
|
398
|
+
if (Is.stringValue(fieldDescriptor.itemTypeRef) &&
|
|
399
|
+
(fieldDescriptor.type === "object" || fieldDescriptor.type === "array")) {
|
|
400
|
+
const objSchema = EntitySchemaFactory.get(fieldDescriptor.itemTypeRef);
|
|
401
|
+
return this.convertRowToObject(objSchema.properties, value);
|
|
402
|
+
}
|
|
403
|
+
else if (
|
|
404
|
+
// If the field is json format
|
|
405
|
+
(fieldDescriptor.type === "string" && fieldDescriptor.format === "json") ||
|
|
406
|
+
// Or its and object or array without a type ref
|
|
407
|
+
(!Is.stringValue(fieldDescriptor.itemTypeRef) &&
|
|
408
|
+
(fieldDescriptor.type === "object" || fieldDescriptor.type === "array"))) {
|
|
409
|
+
try {
|
|
410
|
+
return JSON.parse(value);
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
throw new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, "parseJSONFailed", {
|
|
414
|
+
name: fieldDescriptor.property,
|
|
415
|
+
value
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else if (fieldDescriptor.type === "string" &&
|
|
420
|
+
(fieldDescriptor.format === "date-time" || fieldDescriptor.format === "date") &&
|
|
421
|
+
Is.date(value)) {
|
|
422
|
+
return Coerce.string(value);
|
|
423
|
+
}
|
|
424
|
+
else if (fieldDescriptor.type === "object") {
|
|
425
|
+
if (value === "null" ||
|
|
426
|
+
value === "undefined" ||
|
|
427
|
+
value === "" ||
|
|
428
|
+
value === null ||
|
|
429
|
+
value === undefined) {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
else if (fieldDescriptor.format === "uuid") {
|
|
434
|
+
return value.toString();
|
|
435
|
+
}
|
|
436
|
+
return value;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Format a value for the DB. As the driver takes care of conversion from Javascript
|
|
440
|
+
* @param value The value to format.
|
|
441
|
+
* @param fieldDescriptor The descriptor for the field
|
|
442
|
+
* @returns The value after conversion.
|
|
443
|
+
* @internal
|
|
444
|
+
*/
|
|
445
|
+
propertyToDbValue(value, fieldDescriptor) {
|
|
446
|
+
if (fieldDescriptor) {
|
|
447
|
+
// If the field is json format
|
|
448
|
+
if ((fieldDescriptor.type === "string" && fieldDescriptor.format === "json") ||
|
|
449
|
+
// Or its and object or array without a type ref
|
|
450
|
+
(!Is.stringValue(fieldDescriptor.itemTypeRef) &&
|
|
451
|
+
(fieldDescriptor.type === "object" || fieldDescriptor.type === "array"))) {
|
|
452
|
+
return Is.empty(value) ? "null" : this.jsonWrap(value);
|
|
453
|
+
}
|
|
454
|
+
else if (fieldDescriptor.format === "uuid") {
|
|
455
|
+
if (!Is.string(value)) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
return CassandraTypes.Uuid.fromString(value);
|
|
459
|
+
}
|
|
460
|
+
return value;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Convert a row back to an object.
|
|
465
|
+
* @param properties The optional properties to convert.
|
|
466
|
+
* @param row The row to convert.
|
|
467
|
+
* @returns The row as an object.
|
|
468
|
+
* @internal
|
|
469
|
+
*/
|
|
470
|
+
convertRowToObject(properties, row) {
|
|
471
|
+
const obj = {};
|
|
472
|
+
for (const field of properties ?? []) {
|
|
473
|
+
const value = row[field.property];
|
|
474
|
+
if (!Is.empty(value)) {
|
|
475
|
+
obj[field.property] = this.dbValueToProperty(value, field);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return ObjectHelper.removeEmptyProperties(obj, { removeNull: true });
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Wrap a string for DB format.
|
|
482
|
+
* @param value The value to wrap.
|
|
483
|
+
* @returns The wrapped string.
|
|
484
|
+
* @internal
|
|
485
|
+
*/
|
|
486
|
+
stringWrap(value) {
|
|
487
|
+
if (value === undefined || value === null) {
|
|
488
|
+
return "''";
|
|
489
|
+
}
|
|
490
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Wrap an object for json in DB format.
|
|
494
|
+
* @param value The value to wrap.
|
|
495
|
+
* @returns The wrapped string.
|
|
496
|
+
* @internal
|
|
497
|
+
*/
|
|
498
|
+
jsonWrap(value) {
|
|
499
|
+
let json = JSON.stringify(value);
|
|
500
|
+
json = json.replace(/[\b\0\t\n\r\u001A\\]/g, s => {
|
|
501
|
+
switch (s) {
|
|
502
|
+
case "\0":
|
|
503
|
+
return String.raw `\0`;
|
|
504
|
+
case "\n":
|
|
505
|
+
return String.raw `\n`;
|
|
506
|
+
case "\r":
|
|
507
|
+
return String.raw `\r`;
|
|
508
|
+
case "\b":
|
|
509
|
+
return String.raw `\b`;
|
|
510
|
+
case "\t":
|
|
511
|
+
return String.raw `\t`;
|
|
512
|
+
case "\u001A":
|
|
513
|
+
return String.raw `\Z`;
|
|
514
|
+
default:
|
|
515
|
+
return `\\${s}`;
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
return json;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Build the conditions for the query.
|
|
522
|
+
* @param conditions The optional conditions to match for the entities.
|
|
523
|
+
* @returns The SQL conditions and the values.
|
|
524
|
+
* @internal
|
|
525
|
+
*/
|
|
526
|
+
buildConditions(conditions) {
|
|
527
|
+
const conditionValues = [];
|
|
528
|
+
const sqlConditions = [];
|
|
529
|
+
const properties = (this._entitySchema.properties ?? []).concat([
|
|
530
|
+
{
|
|
531
|
+
property: AbstractScyllaDBConnector.PARTITION_KEY,
|
|
532
|
+
type: "string"
|
|
533
|
+
}
|
|
534
|
+
]);
|
|
535
|
+
if (Is.arrayValue(conditions)) {
|
|
536
|
+
for (const condition of conditions) {
|
|
537
|
+
sqlConditions.push(`"${condition.property}"=?`);
|
|
538
|
+
const schemaProperty = properties.find(s => s.property === condition.property);
|
|
539
|
+
conditionValues.push(this.propertyToDbValue(condition.value, schemaProperty));
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return { sqlCondition: sqlConditions.join(" AND "), conditionValues };
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=abstractScyllaDBConnector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abstractScyllaDBConnector.js","sourceRoot":"","sources":["../../src/abstractScyllaDBConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ContextIdHelper, ContextIdStore } from \"@twin.org/context\";\nimport {\n\tCoerce,\n\tComponentFactory,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tObjectHelper,\n\tStringHelper\n} from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\tEntitySchemaFactory,\n\tEntitySchemaHelper,\n\tLogicalOperator,\n\tSortDirection,\n\ttype EntityCondition,\n\ttype IComparator,\n\ttype IComparatorGroup,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty\n} from \"@twin.org/entity\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { types as CassandraTypes, Client } from \"cassandra-driver\";\nimport type { IScyllaDBConfig } from \"./models/IScyllaDBConfig.js\";\nimport type { IScyllaDBTableConfig } from \"./models/IScyllaDBTableConfig.js\";\n\n/**\n * Store entities using ScyllaDB.\n */\nexport abstract class AbstractScyllaDBConnector<T> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<AbstractScyllaDBConnector<unknown>>();\n\n\t/**\n\t * Partition id field name.\n\t * @internal\n\t */\n\tprotected static readonly PARTITION_KEY: string = \"partitionId\";\n\n\t/**\n\t * Partition id field value.\n\t * @internal\n\t */\n\tprotected static readonly PARTITION_KEY_VALUE: string = \"root\";\n\n\t/**\n\t * Limit the number of entities when finding.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_LIMIT: number = 40;\n\n\t/**\n\t * The name of the database table.\n\t * @internal\n\t */\n\tprotected _fullTableName: string;\n\n\t/**\n\t * Configuration to connection to ScyllaDB.\n\t * @internal\n\t */\n\tprotected readonly _config: IScyllaDBConfig;\n\n\t/**\n\t * The logging component.\n\t * @internal\n\t */\n\tprotected readonly _logging?: ILoggingComponent;\n\n\t/**\n\t * The schema for the entity.\n\t * @internal\n\t */\n\tprotected readonly _entitySchema: IEntitySchema<T>;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprotected readonly _partitionContextIds?: string[];\n\n\t/**\n\t * The primary key.\n\t * @internal\n\t */\n\tprotected readonly _primaryKey: IEntitySchemaProperty<T>;\n\n\t/**\n\t * Create a new instance of AbstractScyllaDBConnector.\n\t * @param options The options for the connector.\n\t * @param options.loggingComponentType The type of logging component to use, defaults to no logging.\n\t * @param options.entitySchema The name of the entity schema.\n\t * @param options.partitionContextIds The keys to use from the context ids to create partitions.\n\t * @param options.config The configuration for the connector.\n\t */\n\tconstructor(options: {\n\t\tloggingComponentType?: string;\n\t\tentitySchema: string;\n\t\tpartitionContextIds?: string[];\n\t\tconfig: IScyllaDBTableConfig;\n\t}) {\n\t\tGuards.object(AbstractScyllaDBConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<IScyllaDBConfig>(\n\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.arrayValue(\n\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\tnameof(options.config.hosts),\n\t\t\toptions.config.hosts\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\tnameof(options.config.localDataCenter),\n\t\t\toptions.config.localDataCenter\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\tnameof(options.config.keyspace),\n\t\t\toptions.config.keyspace\n\t\t);\n\n\t\tthis._logging = ComponentFactory.getIfExists(options.loggingComponentType ?? \"logging\");\n\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\t\tthis._primaryKey = EntitySchemaHelper.getPrimaryKey<T>(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._fullTableName = StringHelper.camelCase(\n\t\t\tIs.stringValue(options.config.tableName) ? options.config.tableName : options.entitySchema\n\t\t);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn AbstractScyllaDBConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the schema for the entities.\n\t * @returns The schema for the entities.\n\t */\n\tpublic getSchema(): IEntitySchema {\n\t\treturn this._entitySchema as IEntitySchema;\n\t}\n\n\t/**\n\t * Get an entity.\n\t * @param id The id of the entity to get.\n\t * @param secondaryIndex Get the item using a secondary index.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The object if it can be found or undefined.\n\t */\n\tpublic async get(\n\t\tid: string,\n\t\tsecondaryIndex?: keyof T,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<T | undefined> {\n\t\tGuards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, nameof(id), id);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconst indexField = secondaryIndex ?? this._primaryKey?.property;\n\n\t\t\tconditions ??= [];\n\t\t\tconditions.unshift({\n\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\tvalue: partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE\n\t\t\t});\n\t\t\tconditions.unshift({\n\t\t\t\tproperty: indexField,\n\t\t\t\tvalue: id\n\t\t\t});\n\n\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\n\t\t\tlet sql = `SELECT * FROM \"${this._fullTableName}\" WHERE ${sqlCondition}`;\n\n\t\t\tif (secondaryIndex) {\n\t\t\t\tsql += \" ALLOW FILTERING\";\n\t\t\t}\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: AbstractScyllaDBConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"sql\",\n\t\t\t\tdata: { sql }\n\t\t\t});\n\n\t\t\tconnection = await this.openConnection();\n\n\t\t\tconst result = await this.queryDB(connection, sql, conditionValues);\n\n\t\t\tif (result.rows.length === 1) {\n\t\t\t\treturn this.convertRowToObject(this._entitySchema.properties, result.rows[0]);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\t\t\"getFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terror\n\t\t\t);\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions.\n\t * @param conditions The conditions to match for the entities.\n\t * @param sortProperties The optional sort order.\n\t * @param properties The optional properties to return, defaults to all.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t */\n\tpublic async query(\n\t\tconditions?: EntityCondition<T>,\n\t\tsortProperties?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: Partial<T>[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\tlet connection;\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tlet returnSize = limit ?? AbstractScyllaDBConnector._DEFAULT_LIMIT;\n\t\t\tlet sql = `SELECT * FROM \"${this._fullTableName}\"`;\n\n\t\t\tif (Is.array(properties)) {\n\t\t\t\tconst fields: string[] = [];\n\n\t\t\t\tfor (const property of properties) {\n\t\t\t\t\tfields.push(property.toString());\n\t\t\t\t}\n\n\t\t\t\tconst selectFields = fields.join(\",\");\n\t\t\t\tsql = sql.replace(\"*\", selectFields);\n\t\t\t}\n\n\t\t\tconst conds: string[] = [];\n\t\t\tlet conditionQuery = \"\";\n\t\t\t// The params to be used to execute the query\n\t\t\tconst params: unknown[] = [];\n\n\t\t\tlet finalConditionQuery = `\"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ?`;\n\t\t\tparams.push(partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE);\n\n\t\t\tlet theConditions: EntityCondition<T>[] = [];\n\t\t\tif (!Is.undefined(conditions)) {\n\t\t\t\tif (\"conditions\" in conditions) {\n\t\t\t\t\ttheConditions = (conditions as IComparatorGroup).conditions;\n\t\t\t\t} else {\n\t\t\t\t\ttheConditions.push(conditions as EntityCondition<T>);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// TODO: This code needs refactoring to support conditions for sub properties.\n\t\t\tfor (const cond of theConditions) {\n\t\t\t\tconst condition = cond as IComparator;\n\n\t\t\t\tconst descriptor = this._entitySchema.properties?.find(\n\t\t\t\t\tp => p.property === condition.property\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\tcondition.comparison === ComparisonOperator.Includes ||\n\t\t\t\t\tcondition.comparison === ComparisonOperator.NotIncludes\n\t\t\t\t) {\n\t\t\t\t\tconst propValue = `'%${condition.value?.toString()}%'`;\n\t\t\t\t\tif (condition.comparison === ComparisonOperator.Includes) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" LIKE ${propValue}`);\n\t\t\t\t\t} else if (condition.comparison === ComparisonOperator.NotIncludes) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" NOT LIKE ${propValue}`);\n\t\t\t\t\t}\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.In) {\n\t\t\t\t\tlet value: unknown[] = [];\n\t\t\t\t\tif (!Is.arrayValue(condition.value)) {\n\t\t\t\t\t\tvalue.push(this.propertyToDbValue(condition.value, descriptor));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue = condition.value.map(v => this.propertyToDbValue(v, descriptor));\n\t\t\t\t\t}\n\t\t\t\t\tparams.push(value);\n\t\t\t\t\tconds.push(`\"${condition.property}\" IN ?`);\n\t\t\t\t} else {\n\t\t\t\t\tconst propValue = condition.value;\n\t\t\t\t\tparams.push(propValue);\n\t\t\t\t\tif (condition.comparison === ComparisonOperator.Equals) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" = ?`);\n\t\t\t\t\t} else if (condition.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" <> ?`);\n\t\t\t\t\t} else if (condition.comparison === ComparisonOperator.GreaterThan) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" > ?`);\n\t\t\t\t\t} else if (condition.comparison === ComparisonOperator.LessThan) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" < ?`);\n\t\t\t\t\t} else if (condition.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" >= ?`);\n\t\t\t\t\t} else if (condition.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\t\t\t\tconds.push(`\"${condition.property}\" <= ?`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst operator = (conditions as IComparatorGroup).logicalOperator ?? LogicalOperator.And;\n\t\t\t\tconditionQuery = `${conds.join(` ${operator} `)}`;\n\t\t\t}\n\n\t\t\tif (conditionQuery.length > 0) {\n\t\t\t\tfinalConditionQuery += ` AND (${conditionQuery})`;\n\t\t\t}\n\n\t\t\tsql += ` WHERE ${finalConditionQuery}`;\n\n\t\t\tconnection = await this.openConnection();\n\n\t\t\t// TODO: Only supported one sort property at the moment. This code would need to be revised in a follow-up\n\t\t\tif (Is.array(sortProperties) && sortProperties.length >= 1) {\n\t\t\t\tconst sortKey = sortProperties[0].property ?? this._primaryKey.property;\n\t\t\t\tconst sortDir =\n\t\t\t\t\tsortProperties[0].sortDirection ??\n\t\t\t\t\tthis._entitySchema.properties?.find(e => e.property === sortKey)?.sortDirection;\n\n\t\t\t\tlet sqlSortDir = \"asc\";\n\t\t\t\tif (sortDir === SortDirection.Descending) {\n\t\t\t\t\tsqlSortDir = \"desc\";\n\t\t\t\t}\n\n\t\t\t\tsql += ` ORDER BY \"${String(sortKey)}\" ${sqlSortDir.toUpperCase()}`;\n\t\t\t\t// Disabling paging in order by situations\n\t\t\t\treturnSize = 0;\n\t\t\t}\n\n\t\t\tsql += \" ALLOW FILTERING\";\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: AbstractScyllaDBConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"sql\",\n\t\t\t\tdata: { sql }\n\t\t\t});\n\n\t\t\tconst result = await this.queryDB(connection, sql, params, cursor, returnSize);\n\n\t\t\tconst entities: Partial<T>[] = [];\n\n\t\t\tfor (const row of result.rows) {\n\t\t\t\tentities.push(this.convertRowToObject(this._entitySchema.properties, row));\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tentities,\n\t\t\t\tcursor: Is.stringValue(result.pageState) ? result.pageState : undefined\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\t\t\"findFailed\",\n\t\t\t\t{ table: this._fullTableName },\n\t\t\t\terror\n\t\t\t);\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Open a new database connection.\n\t * @param config The config for the connection.\n\t * @param skipKeySpace Don't include the keyspace in the connection.\n\t * @returns The new connection.\n\t * @internal\n\t */\n\tprotected async openConnection(skipKeySpace: boolean = false): Promise<Client> {\n\t\tconst client = new Client({\n\t\t\tcontactPoints: this._config.hosts,\n\t\t\tlocalDataCenter: this._config.localDataCenter,\n\t\t\tkeyspace: skipKeySpace ? undefined : this._config.keyspace,\n\t\t\tprotocolOptions: {\n\t\t\t\tport: this._config.port\n\t\t\t}\n\t\t});\n\t\tawait client.connect();\n\n\t\treturn client;\n\t}\n\n\t/**\n\t * Close database connection.\n\t * @param connection The connection to close.\n\t * @internal\n\t */\n\tprotected async closeConnection(connection?: Client): Promise<void> {\n\t\tif (!connection) {\n\t\t\treturn;\n\t\t}\n\t\treturn connection.shutdown();\n\t}\n\n\t/**\n\t * Query the database.\n\t * @param connection The connection to query.\n\t * @param sql The sql statement to execute.\n\t * @param params The params to use when executing the query.\n\t * @param state The state to use when it comes to pagination.\n\t * @returns The rows.\n\t * @internal\n\t */\n\tprotected async queryDB(\n\t\tconnection: Client,\n\t\tsql: string,\n\t\tparams: unknown[],\n\t\tpageState?: string,\n\t\tlimit?: number\n\t): Promise<CassandraTypes.ResultSet> {\n\t\treturn new Promise<CassandraTypes.ResultSet>((resolve, reject) => {\n\t\t\tconst rows: CassandraTypes.Row[] = [];\n\n\t\t\tconnection.eachRow(\n\t\t\t\tsql,\n\t\t\t\tparams,\n\t\t\t\t{\n\t\t\t\t\tprepare: true,\n\t\t\t\t\tautoPage: false,\n\t\t\t\t\tfetchSize: limit ?? AbstractScyllaDBConnector._DEFAULT_LIMIT,\n\t\t\t\t\tpageState\n\t\t\t\t},\n\t\t\t\t(n: number, row: CassandraTypes.Row) => {\n\t\t\t\t\trows.push(row);\n\t\t\t\t},\n\t\t\t\t(err: Error, res: CassandraTypes.ResultSet) => {\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tres.rows = rows;\n\t\t\t\t\tresolve(res);\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Execute on the database.\n\t * @param connection The connection to execute.\n\t * @param sql The sql statement to execute.\n\t * @internal\n\t */\n\tprotected async execute(\n\t\tconnection: Client,\n\t\tsql: string,\n\t\tparams?: unknown[]\n\t): Promise<CassandraTypes.ResultSet> {\n\t\treturn connection.execute(sql, params, { prepare: true });\n\t}\n\n\t/**\n\t * Create keyspace if it doesn't exist.\n\t * @param connection The connection to perform the query with.\n\t * @param keyspaceName The name of the keyspace to create.\n\t * @internal\n\t */\n\tprotected async createKeyspace(\n\t\tconnection: Client,\n\t\tkeyspaceName: string\n\t): Promise<CassandraTypes.ResultSet> {\n\t\treturn this.execute(\n\t\t\tconnection,\n\t\t\t`CREATE KEYSPACE IF NOT EXISTS \"${keyspaceName}\" WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1}`\n\t\t);\n\t}\n\n\t/**\n\t * Check if a keyspace exists.\n\t * @param connection The connection to perform the query with.\n\t * @param keyspaceName The name of the keyspace to check.\n\t * @returns True if the keyspace exists, false otherwise.\n\t * @internal\n\t */\n\tprotected async checkKeyspaceExists(connection: Client, keyspaceName: string): Promise<boolean> {\n\t\tconst result = await this.queryDB(\n\t\t\tconnection,\n\t\t\t\"SELECT keyspace_name FROM system_schema.keyspaces WHERE keyspace_name = ?\",\n\t\t\t[keyspaceName]\n\t\t);\n\n\t\treturn result.rowLength > 0;\n\t}\n\n\t/**\n\t * Check if a type exists.\n\t * @param connection The connection to perform the query with.\n\t * @param typeName The name of the type to check.\n\t * @returns True if the type exists, false otherwise.\n\t * @internal\n\t */\n\tprotected async checkTypeExists(connection: Client, typeName: string): Promise<boolean> {\n\t\tconst result = await this.queryDB(\n\t\t\tconnection,\n\t\t\t\"SELECT type_name FROM system_schema.types WHERE type_name = ?\",\n\t\t\t[typeName]\n\t\t);\n\n\t\treturn result.rowLength > 0;\n\t}\n\n\t/**\n\t * Check if a table exists.\n\t * @param connection The connection to perform the query with.\n\t * @param keyspaceName The name of the keyspace to check.\n\t * @param tableName The name of the table to check.\n\t * @returns True if the table exists, false otherwise.\n\t * @internal\n\t */\n\tprotected async checkTableExists(\n\t\tconnection: Client,\n\t\tkeyspaceName: string,\n\t\ttableName: string\n\t): Promise<boolean> {\n\t\tconst result = await this.queryDB(\n\t\t\tconnection,\n\t\t\t\"SELECT table_name FROM system_schema.tables WHERE keyspace_name = ? AND table_name = ?\",\n\t\t\t[keyspaceName, tableName]\n\t\t);\n\n\t\treturn result.rowLength > 0;\n\t}\n\n\t/**\n\t * Format a field from the DB.\n\t * @param value The value to convert to original form.\n\t * @param fieldDescriptor The descriptor for the field.\n\t * @returns The value as a property for the object.\n\t * @internal\n\t */\n\tprotected dbValueToProperty(value: unknown, fieldDescriptor: IEntitySchemaProperty<T>): unknown {\n\t\tif (\n\t\t\tIs.stringValue(fieldDescriptor.itemTypeRef) &&\n\t\t\t(fieldDescriptor.type === \"object\" || fieldDescriptor.type === \"array\")\n\t\t) {\n\t\t\tconst objSchema = EntitySchemaFactory.get(fieldDescriptor.itemTypeRef);\n\t\t\treturn this.convertRowToObject(objSchema.properties, value as { [id: string]: unknown });\n\t\t} else if (\n\t\t\t// If the field is json format\n\t\t\t(fieldDescriptor.type === \"string\" && fieldDescriptor.format === \"json\") ||\n\t\t\t// Or its and object or array without a type ref\n\t\t\t(!Is.stringValue(fieldDescriptor.itemTypeRef) &&\n\t\t\t\t(fieldDescriptor.type === \"object\" || fieldDescriptor.type === \"array\"))\n\t\t) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value as string);\n\t\t\t} catch {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"parseJSONFailed\", {\n\t\t\t\t\tname: fieldDescriptor.property,\n\t\t\t\t\tvalue\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (\n\t\t\tfieldDescriptor.type === \"string\" &&\n\t\t\t(fieldDescriptor.format === \"date-time\" || fieldDescriptor.format === \"date\") &&\n\t\t\tIs.date(value)\n\t\t) {\n\t\t\treturn Coerce.string(value);\n\t\t} else if (fieldDescriptor.type === \"object\") {\n\t\t\tif (\n\t\t\t\tvalue === \"null\" ||\n\t\t\t\tvalue === \"undefined\" ||\n\t\t\t\tvalue === \"\" ||\n\t\t\t\tvalue === null ||\n\t\t\t\tvalue === undefined\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else if (fieldDescriptor.format === \"uuid\") {\n\t\t\treturn (value as CassandraTypes.Uuid).toString();\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Format a value for the DB. As the driver takes care of conversion from Javascript\n\t * @param value The value to format.\n\t * @param fieldDescriptor The descriptor for the field\n\t * @returns The value after conversion.\n\t * @internal\n\t */\n\tprotected propertyToDbValue(value: unknown, fieldDescriptor?: IEntitySchemaProperty<T>): unknown {\n\t\tif (fieldDescriptor) {\n\t\t\t// If the field is json format\n\t\t\tif (\n\t\t\t\t(fieldDescriptor.type === \"string\" && fieldDescriptor.format === \"json\") ||\n\t\t\t\t// Or its and object or array without a type ref\n\t\t\t\t(!Is.stringValue(fieldDescriptor.itemTypeRef) &&\n\t\t\t\t\t(fieldDescriptor.type === \"object\" || fieldDescriptor.type === \"array\"))\n\t\t\t) {\n\t\t\t\treturn Is.empty(value) ? \"null\" : this.jsonWrap(value);\n\t\t\t} else if (fieldDescriptor.format === \"uuid\") {\n\t\t\t\tif (!Is.string(value)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn CassandraTypes.Uuid.fromString(value);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t}\n\n\t/**\n\t * Convert a row back to an object.\n\t * @param properties The optional properties to convert.\n\t * @param row The row to convert.\n\t * @returns The row as an object.\n\t * @internal\n\t */\n\tprotected convertRowToObject(\n\t\tproperties: IEntitySchemaProperty<T>[] | undefined,\n\t\trow: { [id: string]: unknown }\n\t): T {\n\t\tconst obj: { [id: string]: unknown } = {};\n\n\t\tfor (const field of properties ?? []) {\n\t\t\tconst value = row[field.property as string];\n\t\t\tif (!Is.empty(value)) {\n\t\t\t\tobj[field.property as string] = this.dbValueToProperty(value, field);\n\t\t\t}\n\t\t}\n\n\t\treturn ObjectHelper.removeEmptyProperties(obj as T, { removeNull: true });\n\t}\n\n\t/**\n\t * Wrap a string for DB format.\n\t * @param value The value to wrap.\n\t * @returns The wrapped string.\n\t * @internal\n\t */\n\tprotected stringWrap(value: string): string {\n\t\tif (value === undefined || value === null) {\n\t\t\treturn \"''\";\n\t\t}\n\n\t\treturn `'${value.replace(/'/g, \"''\")}'`;\n\t}\n\n\t/**\n\t * Wrap an object for json in DB format.\n\t * @param value The value to wrap.\n\t * @returns The wrapped string.\n\t * @internal\n\t */\n\tprotected jsonWrap(value: unknown): string {\n\t\tlet json = JSON.stringify(value);\n\n\t\tjson = json.replace(/[\\b\\0\\t\\n\\r\\u001A\\\\]/g, s => {\n\t\t\tswitch (s) {\n\t\t\t\tcase \"\\0\":\n\t\t\t\t\treturn String.raw`\\0`;\n\t\t\t\tcase \"\\n\":\n\t\t\t\t\treturn String.raw`\\n`;\n\t\t\t\tcase \"\\r\":\n\t\t\t\t\treturn String.raw`\\r`;\n\t\t\t\tcase \"\\b\":\n\t\t\t\t\treturn String.raw`\\b`;\n\t\t\t\tcase \"\\t\":\n\t\t\t\t\treturn String.raw`\\t`;\n\t\t\t\tcase \"\\u001A\":\n\t\t\t\t\treturn String.raw`\\Z`;\n\t\t\t\tdefault:\n\t\t\t\t\treturn `\\\\${s}`;\n\t\t\t}\n\t\t});\n\t\treturn json;\n\t}\n\n\t/**\n\t * Build the conditions for the query.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The SQL conditions and the values.\n\t * @internal\n\t */\n\tprotected buildConditions(conditions: { property: keyof T; value: unknown }[] | undefined): {\n\t\tsqlCondition: string;\n\t\tconditionValues: unknown[];\n\t} {\n\t\tconst conditionValues: unknown[] = [];\n\t\tconst sqlConditions: string[] = [];\n\n\t\tconst properties = (this._entitySchema.properties ?? []).concat([\n\t\t\t{\n\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY,\n\t\t\t\ttype: \"string\"\n\t\t\t} as IEntitySchemaProperty<T>\n\t\t]);\n\n\t\tif (Is.arrayValue(conditions)) {\n\t\t\tfor (const condition of conditions) {\n\t\t\t\tsqlConditions.push(`\"${condition.property as string}\"=?`);\n\t\t\t\tconst schemaProperty = properties.find(s => s.property === condition.property);\n\t\t\t\tconditionValues.push(this.propertyToDbValue(condition.value, schemaProperty));\n\t\t\t}\n\t\t}\n\t\treturn { sqlCondition: sqlConditions.join(\" AND \"), conditionValues };\n\t}\n}\n"]}
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
export * from "./models/IScyllaDBConfig.js";
|
|
4
|
+
export * from "./models/IScyllaDBTableConfig.js";
|
|
5
|
+
export * from "./models/IScyllaDBTableConnectorConstructorOptions.js";
|
|
6
|
+
export * from "./models/IScyllaDBViewConfig.js";
|
|
7
|
+
export * from "./models/IScyllaDBViewConnectorConstructorOptions.js";
|
|
8
|
+
export * from "./scyllaDBTableConnector.js";
|
|
9
|
+
export * from "./scyllaDBViewConnector.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,uDAAuD,CAAC;AACtE,cAAc,iCAAiC,CAAC;AAChD,cAAc,sDAAsD,CAAC;AACrE,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./models/IScyllaDBConfig.js\";\nexport * from \"./models/IScyllaDBTableConfig.js\";\nexport * from \"./models/IScyllaDBTableConnectorConstructorOptions.js\";\nexport * from \"./models/IScyllaDBViewConfig.js\";\nexport * from \"./models/IScyllaDBViewConnectorConstructorOptions.js\";\nexport * from \"./scyllaDBTableConnector.js\";\nexport * from \"./scyllaDBViewConnector.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IScyllaDBConfig.js","sourceRoot":"","sources":["../../../src/models/IScyllaDBConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * ScyllaDB Configuration.\n */\nexport interface IScyllaDBConfig {\n\t/**\n\t * The host to contact to.\n\t */\n\thosts: string[];\n\n\t/**\n\t * The local data center.\n\t */\n\tlocalDataCenter: string;\n\n\t/**\n\t * The keyspace to use.\n\t */\n\tkeyspace: string;\n\n\t/**\n\t * The port to connect to.\n\t * @default 9042\n\t */\n\tport?: number;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IScyllaDBTableConfig.js","sourceRoot":"","sources":["../../../src/models/IScyllaDBTableConfig.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IScyllaDBConfig } from \"./IScyllaDBConfig.js\";\n\n/**\n * Definition of MySQL DB configuration.\n */\nexport interface IScyllaDBTableConfig extends IScyllaDBConfig {\n\t/**\n\t * The name of the table for the storage.\n\t * @default To the camel case of the entity name.\n\t */\n\ttableName?: string;\n}\n"]}
|