@twin.org/entity-storage-connector-scylladb 0.0.3-next.24 → 0.0.3-next.26
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/README.md +1 -1
- package/dist/es/abstractScyllaDBConnector.js +1 -1
- package/dist/es/abstractScyllaDBConnector.js.map +1 -1
- package/dist/es/scyllaDBTableConnector.js.map +1 -1
- package/dist/types/scyllaDBTableConnector.d.ts +2 -2
- package/docs/changelog.md +32 -0
- package/docs/reference/classes/ScyllaDBTableConnector.md +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @twin.org/entity-storage-connector-scylladb
|
|
|
13
13
|
To perform testing of this component it may be necessary to launch a local instance to communicate with.
|
|
14
14
|
|
|
15
15
|
```shell
|
|
16
|
-
docker run -d --name twin-entity-storage-scylladb -p
|
|
16
|
+
docker run -d --name twin-entity-storage-scylladb -p 19500:9042 scylladb/scylla:5.4.9
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Examples
|
|
@@ -80,7 +80,7 @@ export class AbstractScyllaDBConnector {
|
|
|
80
80
|
Guards.arrayValue(AbstractScyllaDBConnector.CLASS_NAME, "options.config.hosts", options.config.hosts);
|
|
81
81
|
Guards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, "options.config.localDataCenter", options.config.localDataCenter);
|
|
82
82
|
Guards.stringValue(AbstractScyllaDBConnector.CLASS_NAME, "options.config.keyspace", options.config.keyspace);
|
|
83
|
-
this._logging = ComponentFactory.getIfExists(options.loggingComponentType
|
|
83
|
+
this._logging = ComponentFactory.getIfExists(options.loggingComponentType);
|
|
84
84
|
this._entitySchema = EntitySchemaFactory.get(options.entitySchema);
|
|
85
85
|
this._partitionContextIds = options.partitionContextIds;
|
|
86
86
|
this._primaryKey = EntitySchemaHelper.getPrimaryKey(this._entitySchema);
|
|
@@ -1 +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\ttype IValidationFailure,\n\tValidation\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 { EntityStorageHelper } from \"@twin.org/entity-storage-models\";\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\tprotected 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: IScyllaDBTableConfig;\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 _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 * Cached persistent client (keyspace-scoped). Reused across all operations on this\n\t * connector instance so the expensive cassandra-driver `connect()` only runs once.\n\t * Closed by `closePersistentClient()` which callers (e.g. `teardown()`) must invoke.\n\t * @internal\n\t */\n\tprivate _persistentClient: Client | undefined;\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 = options.config.tableName;\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.safeTableName(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\tEntityStorageHelper.validateSortProperties(this._entitySchema, sortProperties);\n\t\tEntityStorageHelper.validateProperties(this._entitySchema, properties);\n\n\t\tif (!Is.empty(limit)) {\n\t\t\tconst validationFailures: IValidationFailure[] = [];\n\t\t\tValidation.integer(nameof(limit), limit, validationFailures, undefined, { minValue: 1 });\n\t\t\tValidation.asValidationError(\n\t\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\t\t\"query\",\n\t\t\t\tvalidationFailures\n\t\t\t);\n\t\t}\n\n\t\t// CQL ORDER BY is only valid on clustering columns (isPrimary). Secondary-index\n\t\t// properties cannot be used; throw before reaching the try-catch so the error\n\t\t// surfaces directly to the caller without being wrapped as findFailed.\n\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\tfor (const sortProperty of sortProperties) {\n\t\t\t\tconst propertySchema = this._entitySchema.properties?.find(\n\t\t\t\t\tp => p.property === sortProperty.property\n\t\t\t\t);\n\t\t\t\tif (!propertySchema?.isPrimary) {\n\t\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"sortOnlyPrimaryKey\", {\n\t\t\t\t\t\tproperty: sortProperty.property\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Validates and throws for unsupported conditions before entering the try-catch\n\t\t// so that comparisonNotSupported errors surface directly to the caller.\n\t\tconst { whereClause, params, noResults } = this.buildCqlConditions(conditions, partitionKey);\n\n\t\tif (noResults) {\n\t\t\treturn { entities: [], cursor: undefined };\n\t\t}\n\n\t\ttry {\n\t\t\tconst returnSize = limit ?? AbstractScyllaDBConnector.DEFAULT_LIMIT;\n\t\t\tlet sql = `SELECT * FROM \"${this.safeTableName(this._fullTableName)}\"`;\n\n\t\t\tif (Is.array(properties)) {\n\t\t\t\tconst fields: string[] = [];\n\t\t\t\tfor (const property of properties) {\n\t\t\t\t\tfields.push(property.toString());\n\t\t\t\t}\n\t\t\t\tsql = sql.replace(\"*\", fields.join(\",\"));\n\t\t\t}\n\n\t\t\tsql += ` WHERE ${whereClause}`;\n\n\t\t\tif (Is.array(sortProperties) && sortProperties.length >= 1) {\n\t\t\t\tconst orderClauses = sortProperties.map(sp => {\n\t\t\t\t\tconst dir = sp.sortDirection === SortDirection.Descending ? \"DESC\" : \"ASC\";\n\t\t\t\t\treturn `\"${String(sp.property)}\" ${dir}`;\n\t\t\t\t});\n\t\t\t\tsql += ` ORDER BY ${orderClauses.join(\", \")}`;\n\t\t\t}\n\n\t\t\tconnection = await this.openConnection();\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\t// ScyllaDB may return a pageState even when the current page is the last one\n\t\t\t// (when rows.length == fetchSize). Peek at the next page to verify there are\n\t\t\t// actually more rows before surfacing the cursor to the caller.\n\t\t\tlet nextCursor: string | undefined;\n\t\t\tif (returnSize > 0 && result.rows.length >= returnSize && Is.stringValue(result.pageState)) {\n\t\t\t\tconst peek = await this.queryDB(connection, sql, params, result.pageState, 1);\n\t\t\t\tif (peek.rows.length > 0) {\n\t\t\t\t\tnextCursor = result.pageState;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tentities,\n\t\t\t\tcursor: nextCursor\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.safeTableName(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 * Count all the entities which match the conditions.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The total count of entities in the storage.\n\t */\n\tpublic async count(conditions?: EntityCondition<T>): Promise<number> {\n\t\tlet connection;\n\t\ttry {\n\t\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\t\tconst partitionKey = ContextIdHelper.combinedContextKey(\n\t\t\t\tcontextIds,\n\t\t\t\tthis._partitionContextIds\n\t\t\t);\n\n\t\t\tconst { whereClause, params, noResults } = this.buildCqlConditions(conditions, partitionKey);\n\n\t\t\tif (noResults) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tconst sql = `SELECT COUNT(*) FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${whereClause} ALLOW FILTERING`;\n\n\t\t\tconnection = await this.openConnection();\n\t\t\tconst result = await this.queryDB(connection, sql, params);\n\t\t\treturn Number(result.rows[0]?.get(\"count\") ?? 0);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"countFailed\", undefined, err);\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 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\t// Reuse the cached keyspace-scoped client when available (avoids repeated\n\t\t// cassandra-driver cluster-discovery on every operation).\n\t\tif (!skipKeySpace && this._persistentClient !== undefined) {\n\t\t\treturn this._persistentClient;\n\t\t}\n\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\tif (!skipKeySpace) {\n\t\t\tthis._persistentClient = client;\n\t\t}\n\n\t\treturn client;\n\t}\n\n\t/**\n\t * Close database connection.\n\t * When `connection` is the cached persistent client it is kept alive so it\n\t * can be reused by future operations; call `closePersistentClient()` to\n\t * explicitly shut it down (e.g. from `teardown()`).\n\t * @param connection The connection to close.\n\t * @returns Nothing.\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\tif (connection === this._persistentClient) {\n\t\t\t// Keep the persistent client alive for reuse.\n\t\t\treturn;\n\t\t}\n\t\treturn connection.shutdown();\n\t}\n\n\t/**\n\t * Shut down and clear the persistent client. Call this from `teardown()`\n\t * implementations to release the underlying TCP connection.\n\t * @internal\n\t */\n\tprotected async closePersistentClient(): Promise<void> {\n\t\tif (this._persistentClient !== undefined) {\n\t\t\tawait this._persistentClient.shutdown();\n\t\t\tthis._persistentClient = undefined;\n\t\t}\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 pageState The page state to use when it comes to pagination.\n\t * @param limit The maximum number of rows to return.\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 * @param params The optional params to use when executing the statement.\n\t * @returns The result set.\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 * @returns The result set.\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 * @throws GeneralError if parsing JSON fails.\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.\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 EntityStorageHelper.unPrepareEntity(obj as T, [AbstractScyllaDBConnector.PARTITION_KEY]);\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\t/**\n\t * Get a safe table name by replacing any non-alphanumeric characters.\n\t * @param name The name to sanitize.\n\t * @returns The safe table name.\n\t */\n\tprotected safeTableName(name: string): string {\n\t\treturn name.replace(/[^\\dA-Za-z]/g, \"\");\n\t}\n\n\t/**\n\t * Parse, validate, and build a CQL WHERE clause from an EntityCondition tree.\n\t * The partition key equality is always the first clause; user conditions follow.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @param partitionKey The partition key value to filter by.\n\t * @returns The complete WHERE clause (without the WHERE keyword) and bound params.\n\t * @throws GeneralError if OR conditions, dot-notation paths, null comparisons, NotEquals, or NotIncludes operators are used.\n\t * @internal\n\t */\n\tprivate buildCqlConditions(\n\t\tconditions: EntityCondition<T> | undefined,\n\t\tpartitionKey: string | undefined\n\t): { whereClause: string; params: unknown[]; noResults?: boolean } {\n\t\tlet conditionsList: EntityCondition<T>[] = [];\n\t\tif (conditions !== undefined) {\n\t\t\tif (\"conditions\" in conditions) {\n\t\t\t\tif ((conditions as IComparatorGroup).logicalOperator === LogicalOperator.Or) {\n\t\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"orConditionNotSupported\");\n\t\t\t\t}\n\t\t\t\tconditionsList = conditions.conditions;\n\t\t\t} else {\n\t\t\t\tconditionsList = [conditions];\n\t\t\t}\n\t\t}\n\n\t\tfor (const cond of conditionsList) {\n\t\t\tconst comparator = cond as IComparator;\n\t\t\tif (String(comparator.property).includes(\".\")) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\t\t\tproperty: comparator.property,\n\t\t\t\t\treason: \"dot-notation nested property paths are not supported in CQL\"\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (\n\t\t\t\t(comparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals) &&\n\t\t\t\t(comparator.value === null || comparator.value === undefined)\n\t\t\t) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\t\t\tproperty: comparator.property,\n\t\t\t\t\treason: \"null/undefined comparisons are not supported in CQL WHERE clauses\"\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"notEqualsNotSupported\", {\n\t\t\t\t\tproperty: comparator.property\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"notIncludesNotSupported\", {\n\t\t\t\t\tproperty: comparator.property\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst conds: string[] = [];\n\t\tconst params: unknown[] = [partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE];\n\n\t\tfor (const cond of conditionsList) {\n\t\t\tconst condition = cond as IComparator;\n\t\t\tconst descriptor = this._entitySchema.properties?.find(\n\t\t\t\tp => p.property === condition.property\n\t\t\t);\n\t\t\tif (\n\t\t\t\tcondition.comparison === ComparisonOperator.Includes ||\n\t\t\t\tcondition.comparison === ComparisonOperator.NotIncludes\n\t\t\t) {\n\t\t\t\tconst serialized = this.propertyToDbValue(condition.value, descriptor);\n\t\t\t\tconst propValue = `'%${Is.stringValue(serialized) ? serialized : \"\"}%'`;\n\t\t\t\tif (condition.comparison === ComparisonOperator.Includes) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" LIKE ${propValue}`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.NotIncludes) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" NOT LIKE ${propValue}`);\n\t\t\t\t}\n\t\t\t} else if (condition.comparison === ComparisonOperator.In) {\n\t\t\t\t// Guard must come first: Is.arrayValue([]) returns false for an empty array,\n\t\t\t\t// so an empty value would be wrapped as a single element below and bypass\n\t\t\t\t// the length check. Check Is.array (true for any array) before branching (#141).\n\t\t\t\tif (Is.array(condition.value) && condition.value.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\twhereClause: \"\",\n\t\t\t\t\t\tparams: [],\n\t\t\t\t\t\tnoResults: true\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tlet value: unknown[] = [];\n\t\t\t\tif (!Is.arrayValue(condition.value)) {\n\t\t\t\t\tvalue.push(this.propertyToDbValue(condition.value, descriptor));\n\t\t\t\t} else {\n\t\t\t\t\tvalue = condition.value.map(v => this.propertyToDbValue(v, descriptor));\n\t\t\t\t}\n\t\t\t\tparams.push(value);\n\t\t\t\tconds.push(`\"${condition.property}\" IN ?`);\n\t\t\t} else {\n\t\t\t\tconst propValue = this.propertyToDbValue(condition.value, descriptor);\n\t\t\t\tparams.push(propValue);\n\t\t\t\tif (condition.comparison === ComparisonOperator.Equals) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" = ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" != ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.GreaterThan) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" > ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.LessThan) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" < ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" >= ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" <= ?`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst operator =\n\t\t\t\"conditions\" in (conditions ?? {})\n\t\t\t\t? ((conditions as IComparatorGroup).logicalOperator ?? LogicalOperator.And)\n\t\t\t\t: LogicalOperator.And;\n\n\t\tlet whereClause = `\"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ?`;\n\t\tif (conds.length > 0) {\n\t\t\twhereClause += ` AND ${conds.join(` ${operator} `)}`;\n\t\t}\n\n\t\treturn { whereClause, params };\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"abstractScyllaDBConnector.js","sourceRoot":"","sources":["../../src/abstractScyllaDBConnector.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACN,MAAM,EACN,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,EAAE,EAEF,UAAU,EACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,aAAa,EAMb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,EAAE,KAAK,IAAI,cAAc,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAInE;;GAEG;AACH,MAAM,OAAgB,yBAAyB;IAC9C;;OAEG;IACI,MAAM,CAAU,UAAU,+BAAwD;IAEzF;;;OAGG;IACO,MAAM,CAAU,aAAa,GAAW,aAAa,CAAC;IAEhE;;;OAGG;IACO,MAAM,CAAU,mBAAmB,GAAW,MAAM,CAAC;IAE/D;;;OAGG;IACO,MAAM,CAAU,aAAa,GAAW,EAAE,CAAC;IAErD;;;OAGG;IACO,cAAc,CAAS;IAEjC;;;OAGG;IACgB,OAAO,CAAuB;IAEjD;;;OAGG;IACgB,QAAQ,CAAqB;IAEhD;;;OAGG;IACO,aAAa,CAAmB;IAE1C;;;OAGG;IACgB,oBAAoB,CAAY;IAEnD;;;OAGG;IACgB,WAAW,CAA2B;IAEzD;;;;;OAKG;IACK,iBAAiB,CAAqB;IAE9C;;;;;;;OAOG;IACH,YAAY,OAKX;QACA,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,UAAU,aAAmB,OAAO,CAAC,CAAC;QAC9E,MAAM,CAAC,WAAW,CACjB,yBAAyB,CAAC,UAAU,0BAEpC,OAAO,CAAC,YAAY,CACpB,CAAC;QACF,MAAM,CAAC,MAAM,CACZ,yBAAyB,CAAC,UAAU,oBAEpC,OAAO,CAAC,MAAM,CACd,CAAC;QACF,MAAM,CAAC,UAAU,CAChB,yBAAyB,CAAC,UAAU,0BAEpC,OAAO,CAAC,MAAM,CAAC,KAAK,CACpB,CAAC;QACF,MAAM,CAAC,WAAW,CACjB,yBAAyB,CAAC,UAAU,oCAEpC,OAAO,CAAC,MAAM,CAAC,eAAe,CAC9B,CAAC;QACF,MAAM,CAAC,WAAW,CACjB,yBAAyB,CAAC,UAAU,6BAEpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CACvB,CAAC;QAEF,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAE3E,IAAI,CAAC,aAAa,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,IAAI,CAAC,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAI,IAAI,CAAC,aAAa,CAAC,CAAC;QAE3E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;IAChD,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,yBAAyB,CAAC,UAAU,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,IAAI,CAAC,aAA8B,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,GAAG,CACf,EAAU,EACV,cAAwB,EACxB,UAAoD;QAEpD,MAAM,CAAC,WAAW,CAAC,yBAAyB,CAAC,UAAU,QAAc,EAAE,CAAC,CAAC;QAEzE,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,eAAe,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAE/F,IAAI,UAAU,CAAC;QACf,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,cAAc,IAAI,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC;YAEhE,UAAU,KAAK,EAAE,CAAC;YAClB,UAAU,CAAC,OAAO,CAAC;gBAClB,QAAQ,EAAE,yBAAyB,CAAC,aAAwB;gBAC5D,KAAK,EAAE,YAAY,IAAI,yBAAyB,CAAC,mBAAmB;aACpE,CAAC,CAAC;YACH,UAAU,CAAC,OAAO,CAAC;gBAClB,QAAQ,EAAE,UAAU;gBACpB,KAAK,EAAE,EAAE;aACT,CAAC,CAAC;YAEH,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;YAE3E,IAAI,GAAG,GAAG,kBAAkB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,YAAY,EAAE,CAAC;YAE7F,IAAI,cAAc,EAAE,CAAC;gBACpB,GAAG,IAAI,kBAAkB,CAAC;YAC3B,CAAC;YAED,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;gBACxB,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,yBAAyB,CAAC,UAAU;gBAC5C,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;gBACd,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,EAAE,GAAG,EAAE;aACb,CAAC,CAAC;YAEH,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAEzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,eAAe,CAAC,CAAC;YAEpE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/E,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,YAAY,CACrB,yBAAyB,CAAC,UAAU,EACpC,WAAW,EACX;gBACC,EAAE;aACF,EACD,KAAK,CACL,CAAC;QACH,CAAC;gBAAS,CAAC;YACV,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IACI,KAAK,CAAC,KAAK,CACjB,UAA+B,EAC/B,cAGG,EACH,UAAwB,EACxB,MAAe,EACf,KAAc;QAWd,IAAI,UAAU,CAAC;QAEf,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,eAAe,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAE/F,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;QAC/E,mBAAmB,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QAEvE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,kBAAkB,GAAyB,EAAE,CAAC;YACpD,UAAU,CAAC,OAAO,UAAgB,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;YACzF,UAAU,CAAC,iBAAiB,CAC3B,yBAAyB,CAAC,UAAU,EACpC,OAAO,EACP,kBAAkB,CAClB,CAAC;QACH,CAAC;QAED,gFAAgF;QAChF,8EAA8E;QAC9E,uEAAuE;QACvE,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACnC,KAAK,MAAM,YAAY,IAAI,cAAc,EAAE,CAAC;gBAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CACzD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC,QAAQ,CACzC,CAAC;gBACF,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC;oBAChC,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,oBAAoB,EAAE;wBAClF,QAAQ,EAAE,YAAY,CAAC,QAAQ;qBAC/B,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;QACF,CAAC;QAED,gFAAgF;QAChF,wEAAwE;QACxE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAE7F,IAAI,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,KAAK,IAAI,yBAAyB,CAAC,aAAa,CAAC;YACpE,IAAI,GAAG,GAAG,kBAAkB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;YAEvE,IAAI,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;oBACnC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAClC,CAAC;gBACD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1C,CAAC;YAED,GAAG,IAAI,UAAU,WAAW,EAAE,CAAC;YAE/B,IAAI,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC5D,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;oBAC5C,MAAM,GAAG,GAAG,EAAE,CAAC,aAAa,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;oBAC3E,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC1C,CAAC,CAAC,CAAC;gBACH,GAAG,IAAI,aAAa,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,CAAC;YAED,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAEzC,GAAG,IAAI,kBAAkB,CAAC;YAE1B,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;gBACxB,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,yBAAyB,CAAC,UAAU;gBAC5C,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;gBACd,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,EAAE,GAAG,EAAE;aACb,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;YAE/E,MAAM,QAAQ,GAAiB,EAAE,CAAC;YAElC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5E,CAAC;YAED,6EAA6E;YAC7E,6EAA6E;YAC7E,gEAAgE;YAChE,IAAI,UAA8B,CAAC;YACnC,IAAI,UAAU,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC5F,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBAC9E,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1B,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;gBAC/B,CAAC;YACF,CAAC;YAED,OAAO;gBACN,QAAQ;gBACR,MAAM,EAAE,UAAU;aAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,YAAY,CACrB,yBAAyB,CAAC,UAAU,EACpC,YAAY,EACZ,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,EAClD,KAAK,CACL,CAAC;QACH,CAAC;gBAAS,CAAC;YACV,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,KAAK,CAAC,UAA+B;QACjD,IAAI,UAAU,CAAC;QACf,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;YACxD,MAAM,YAAY,GAAG,eAAe,CAAC,kBAAkB,CACtD,UAAU,EACV,IAAI,CAAC,oBAAoB,CACzB,CAAC;YAEF,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YAE7F,IAAI,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,CAAC;YACV,CAAC;YAED,MAAM,GAAG,GAAG,yBAAyB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,WAAW,kBAAkB,CAAC;YAErH,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3D,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC7F,CAAC;gBAAS,CAAC;YACV,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACO,KAAK,CAAC,cAAc,CAAC,eAAwB,KAAK;QAC3D,0EAA0E;QAC1E,0DAA0D;QAC1D,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;YAC3D,OAAO,IAAI,CAAC,iBAAiB,CAAC;QAC/B,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;YACzB,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACjC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;YAC7C,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC1D,eAAe,EAAE;gBAChB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;aACvB;SACD,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QAEvB,IAAI,CAAC,YAAY,EAAE,CAAC;YACnB,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC;QACjC,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACO,KAAK,CAAC,eAAe,CAAC,UAAmB;QAClD,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO;QACR,CAAC;QACD,IAAI,UAAU,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3C,8CAA8C;YAC9C,OAAO;QACR,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACO,KAAK,CAAC,qBAAqB;QACpC,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;YACxC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;QACpC,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IACO,KAAK,CAAC,OAAO,CACtB,UAAkB,EAClB,GAAW,EACX,MAAiB,EACjB,SAAkB,EAClB,KAAc;QAEd,OAAO,IAAI,OAAO,CAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAChE,MAAM,IAAI,GAAyB,EAAE,CAAC;YAEtC,UAAU,CAAC,OAAO,CACjB,GAAG,EACH,MAAM,EACN;gBACC,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,KAAK;gBACf,SAAS,EAAE,KAAK,IAAI,yBAAyB,CAAC,aAAa;gBAC3D,SAAS;aACT,EACD,CAAC,CAAS,EAAE,GAAuB,EAAE,EAAE;gBACtC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC,EACD,CAAC,GAAU,EAAE,GAA6B,EAAE,EAAE;gBAC7C,IAAI,GAAG,EAAE,CAAC;oBACT,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO;gBACR,CAAC;gBACD,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CACD,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,OAAO,CACtB,UAAkB,EAClB,GAAW,EACX,MAAkB;QAElB,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,cAAc,CAC7B,UAAkB,EAClB,YAAoB;QAEpB,OAAO,IAAI,CAAC,OAAO,CAClB,UAAU,EACV,kCAAkC,YAAY,8EAA8E,CAC5H,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,mBAAmB,CAAC,UAAkB,EAAE,YAAoB;QAC3E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAChC,UAAU,EACV,2EAA2E,EAC3E,CAAC,YAAY,CAAC,CACd,CAAC;QAEF,OAAO,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,QAAgB;QACnE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAChC,UAAU,EACV,+DAA+D,EAC/D,CAAC,QAAQ,CAAC,CACV,CAAC;QAEF,OAAO,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,gBAAgB,CAC/B,UAAkB,EAClB,YAAoB,EACpB,SAAiB;QAEjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAChC,UAAU,EACV,wFAAwF,EACxF,CAAC,YAAY,EAAE,SAAS,CAAC,CACzB,CAAC;QAEF,OAAO,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACO,iBAAiB,CAAC,KAAc,EAAE,eAAyC;QACpF,IACC,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC;YAC3C,CAAC,eAAe,CAAC,IAAI,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,KAAK,OAAO,CAAC,EACtE,CAAC;YACF,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,UAAU,EAAE,KAAkC,CAAC,CAAC;QAC1F,CAAC;aAAM;QACN,8BAA8B;QAC9B,CAAC,eAAe,CAAC,IAAI,KAAK,QAAQ,IAAI,eAAe,CAAC,MAAM,KAAK,MAAM,CAAC;YACxE,gDAAgD;YAChD,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC;gBAC5C,CAAC,eAAe,CAAC,IAAI,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,EACxE,CAAC;YACF,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,KAAe,CAAC,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC;gBACR,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,iBAAiB,EAAE;oBAC/E,IAAI,EAAE,eAAe,CAAC,QAAQ;oBAC9B,KAAK;iBACL,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;aAAM,IACN,eAAe,CAAC,IAAI,KAAK,QAAQ;YACjC,CAAC,eAAe,CAAC,MAAM,KAAK,WAAW,IAAI,eAAe,CAAC,MAAM,KAAK,MAAM,CAAC;YAC7E,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EACb,CAAC;YACF,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,eAAe,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9C,IACC,KAAK,KAAK,MAAM;gBAChB,KAAK,KAAK,WAAW;gBACrB,KAAK,KAAK,EAAE;gBACZ,KAAK,KAAK,IAAI;gBACd,KAAK,KAAK,SAAS,EAClB,CAAC;gBACF,OAAO,IAAI,CAAC;YACb,CAAC;QACF,CAAC;aAAM,IAAI,eAAe,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC9C,OAAQ,KAA6B,CAAC,QAAQ,EAAE,CAAC;QAClD,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CAAC,KAAc,EAAE,eAA0C;QACrF,IAAI,eAAe,EAAE,CAAC;YACrB,8BAA8B;YAC9B,IACC,CAAC,eAAe,CAAC,IAAI,KAAK,QAAQ,IAAI,eAAe,CAAC,MAAM,KAAK,MAAM,CAAC;gBACxE,gDAAgD;gBAChD,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC;oBAC5C,CAAC,eAAe,CAAC,IAAI,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,EACxE,CAAC;gBACF,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACxD,CAAC;iBAAM,IAAI,eAAe,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC9C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;oBACvB,OAAO;gBACR,CAAC;gBACD,OAAO,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACO,kBAAkB,CAC3B,UAAkD,EAClD,GAA8B;QAE9B,MAAM,GAAG,GAA8B,EAAE,CAAC;QAE1C,KAAK,MAAM,KAAK,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,QAAkB,CAAC,CAAC;YAC5C,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,GAAG,CAAC,KAAK,CAAC,QAAkB,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACtE,CAAC;QACF,CAAC;QAED,OAAO,mBAAmB,CAAC,eAAe,CAAC,GAAQ,EAAE,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC,CAAC;IACjG,CAAC;IAED;;;;;OAKG;IACO,UAAU,CAAC,KAAa;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACO,QAAQ,CAAC,KAAc;QAChC,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAEjC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE;YAChD,QAAQ,CAAC,EAAE,CAAC;gBACX,KAAK,IAAI;oBACR,OAAO,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;gBACvB,KAAK,IAAI;oBACR,OAAO,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;gBACvB,KAAK,IAAI;oBACR,OAAO,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;gBACvB,KAAK,IAAI;oBACR,OAAO,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;gBACvB,KAAK,IAAI;oBACR,OAAO,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;gBACvB,KAAK,QAAQ;oBACZ,OAAO,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;gBACvB;oBACC,OAAO,KAAK,CAAC,EAAE,CAAC;YAClB,CAAC;QACF,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACO,eAAe,CAAC,UAA+D;QAIxF,MAAM,eAAe,GAAc,EAAE,CAAC;QACtC,MAAM,aAAa,GAAa,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YAC/D;gBACC,QAAQ,EAAE,yBAAyB,CAAC,aAAa;gBACjD,IAAI,EAAE,QAAQ;aACc;SAC7B,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACpC,aAAa,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAkB,KAAK,CAAC,CAAC;gBAC1D,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC/E,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;YAC/E,CAAC;QACF,CAAC;QACD,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IACvE,CAAC;IAED;;;;OAIG;IACO,aAAa,CAAC,IAAY;QACnC,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;;OAQG;IACK,kBAAkB,CACzB,UAA0C,EAC1C,YAAgC;QAEhC,IAAI,cAAc,GAAyB,EAAE,CAAC;QAC9C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,YAAY,IAAI,UAAU,EAAE,CAAC;gBAChC,IAAK,UAA+B,CAAC,eAAe,KAAK,eAAe,CAAC,EAAE,EAAE,CAAC;oBAC7E,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,yBAAyB,CAAC,CAAC;gBACzF,CAAC;gBACD,cAAc,GAAG,UAAU,CAAC,UAAU,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACP,cAAc,GAAG,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,IAAmB,CAAC;YACvC,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,wBAAwB,EAAE;oBACtF,QAAQ,EAAE,UAAU,CAAC,QAAQ;oBAC7B,MAAM,EAAE,6DAA6D;iBACrE,CAAC,CAAC;YACJ,CAAC;YACD,IACC,CAAC,UAAU,CAAC,UAAU,KAAK,kBAAkB,CAAC,MAAM;gBACnD,UAAU,CAAC,UAAU,KAAK,kBAAkB,CAAC,SAAS,CAAC;gBACxD,CAAC,UAAU,CAAC,KAAK,KAAK,IAAI,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,CAAC,EAC5D,CAAC;gBACF,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,wBAAwB,EAAE;oBACtF,QAAQ,EAAE,UAAU,CAAC,QAAQ;oBAC7B,MAAM,EAAE,mEAAmE;iBAC3E,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,UAAU,CAAC,UAAU,KAAK,kBAAkB,CAAC,SAAS,EAAE,CAAC;gBAC5D,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,uBAAuB,EAAE;oBACrF,QAAQ,EAAE,UAAU,CAAC,QAAQ;iBAC7B,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,UAAU,CAAC,UAAU,KAAK,kBAAkB,CAAC,WAAW,EAAE,CAAC;gBAC9D,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,UAAU,EAAE,yBAAyB,EAAE;oBACvF,QAAQ,EAAE,UAAU,CAAC,QAAQ;iBAC7B,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAc,CAAC,YAAY,IAAI,yBAAyB,CAAC,mBAAmB,CAAC,CAAC;QAE1F,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,IAAmB,CAAC;YACtC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CACrD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,CACtC,CAAC;YACF,IACC,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,QAAQ;gBACpD,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,WAAW,EACtD,CAAC;gBACF,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACvE,MAAM,SAAS,GAAG,KAAK,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;gBACxE,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,QAAQ,EAAE,CAAC;oBAC1D,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,UAAU,SAAS,EAAE,CAAC,CAAC;gBACzD,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,WAAW,EAAE,CAAC;oBACpE,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,cAAc,SAAS,EAAE,CAAC,CAAC;gBAC7D,CAAC;YACF,CAAC;iBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,EAAE,EAAE,CAAC;gBAC3D,6EAA6E;gBAC7E,0EAA0E;gBAC1E,iFAAiF;gBACjF,IAAI,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/D,OAAO;wBACN,WAAW,EAAE,EAAE;wBACf,MAAM,EAAE,EAAE;wBACV,SAAS,EAAE,IAAI;qBACf,CAAC;gBACH,CAAC;gBACD,IAAI,KAAK,GAAc,EAAE,CAAC;gBAC1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACP,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;gBACzE,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,QAAQ,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACP,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvB,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBACxD,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,OAAO,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,SAAS,EAAE,CAAC;oBAClE,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,QAAQ,CAAC,CAAC;gBAC5C,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,WAAW,EAAE,CAAC;oBACpE,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,OAAO,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,QAAQ,EAAE,CAAC;oBACjE,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,OAAO,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;oBAC3E,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,QAAQ,CAAC,CAAC;gBAC5C,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,eAAe,EAAE,CAAC;oBACxE,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,QAAQ,CAAC,CAAC;gBAC5C,CAAC;YACF,CAAC;QACF,CAAC;QAED,MAAM,QAAQ,GACb,YAAY,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;YACjC,CAAC,CAAC,CAAE,UAA+B,CAAC,eAAe,IAAI,eAAe,CAAC,GAAG,CAAC;YAC3E,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC;QAExB,IAAI,WAAW,GAAG,IAAI,yBAAyB,CAAC,aAAa,OAAO,CAAC;QACrE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,WAAW,IAAI,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACtD,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAChC,CAAC","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\ttype IValidationFailure,\n\tValidation\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 { EntityStorageHelper } from \"@twin.org/entity-storage-models\";\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\tprotected 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: IScyllaDBTableConfig;\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 _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 * Cached persistent client (keyspace-scoped). Reused across all operations on this\n\t * connector instance so the expensive cassandra-driver `connect()` only runs once.\n\t * Closed by `closePersistentClient()` which callers (e.g. `teardown()`) must invoke.\n\t * @internal\n\t */\n\tprivate _persistentClient: Client | undefined;\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);\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 = options.config.tableName;\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.safeTableName(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\tEntityStorageHelper.validateSortProperties(this._entitySchema, sortProperties);\n\t\tEntityStorageHelper.validateProperties(this._entitySchema, properties);\n\n\t\tif (!Is.empty(limit)) {\n\t\t\tconst validationFailures: IValidationFailure[] = [];\n\t\t\tValidation.integer(nameof(limit), limit, validationFailures, undefined, { minValue: 1 });\n\t\t\tValidation.asValidationError(\n\t\t\t\tAbstractScyllaDBConnector.CLASS_NAME,\n\t\t\t\t\"query\",\n\t\t\t\tvalidationFailures\n\t\t\t);\n\t\t}\n\n\t\t// CQL ORDER BY is only valid on clustering columns (isPrimary). Secondary-index\n\t\t// properties cannot be used; throw before reaching the try-catch so the error\n\t\t// surfaces directly to the caller without being wrapped as findFailed.\n\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\tfor (const sortProperty of sortProperties) {\n\t\t\t\tconst propertySchema = this._entitySchema.properties?.find(\n\t\t\t\t\tp => p.property === sortProperty.property\n\t\t\t\t);\n\t\t\t\tif (!propertySchema?.isPrimary) {\n\t\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"sortOnlyPrimaryKey\", {\n\t\t\t\t\t\tproperty: sortProperty.property\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Validates and throws for unsupported conditions before entering the try-catch\n\t\t// so that comparisonNotSupported errors surface directly to the caller.\n\t\tconst { whereClause, params, noResults } = this.buildCqlConditions(conditions, partitionKey);\n\n\t\tif (noResults) {\n\t\t\treturn { entities: [], cursor: undefined };\n\t\t}\n\n\t\ttry {\n\t\t\tconst returnSize = limit ?? AbstractScyllaDBConnector.DEFAULT_LIMIT;\n\t\t\tlet sql = `SELECT * FROM \"${this.safeTableName(this._fullTableName)}\"`;\n\n\t\t\tif (Is.array(properties)) {\n\t\t\t\tconst fields: string[] = [];\n\t\t\t\tfor (const property of properties) {\n\t\t\t\t\tfields.push(property.toString());\n\t\t\t\t}\n\t\t\t\tsql = sql.replace(\"*\", fields.join(\",\"));\n\t\t\t}\n\n\t\t\tsql += ` WHERE ${whereClause}`;\n\n\t\t\tif (Is.array(sortProperties) && sortProperties.length >= 1) {\n\t\t\t\tconst orderClauses = sortProperties.map(sp => {\n\t\t\t\t\tconst dir = sp.sortDirection === SortDirection.Descending ? \"DESC\" : \"ASC\";\n\t\t\t\t\treturn `\"${String(sp.property)}\" ${dir}`;\n\t\t\t\t});\n\t\t\t\tsql += ` ORDER BY ${orderClauses.join(\", \")}`;\n\t\t\t}\n\n\t\t\tconnection = await this.openConnection();\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\t// ScyllaDB may return a pageState even when the current page is the last one\n\t\t\t// (when rows.length == fetchSize). Peek at the next page to verify there are\n\t\t\t// actually more rows before surfacing the cursor to the caller.\n\t\t\tlet nextCursor: string | undefined;\n\t\t\tif (returnSize > 0 && result.rows.length >= returnSize && Is.stringValue(result.pageState)) {\n\t\t\t\tconst peek = await this.queryDB(connection, sql, params, result.pageState, 1);\n\t\t\t\tif (peek.rows.length > 0) {\n\t\t\t\t\tnextCursor = result.pageState;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tentities,\n\t\t\t\tcursor: nextCursor\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.safeTableName(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 * Count all the entities which match the conditions.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The total count of entities in the storage.\n\t */\n\tpublic async count(conditions?: EntityCondition<T>): Promise<number> {\n\t\tlet connection;\n\t\ttry {\n\t\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\t\tconst partitionKey = ContextIdHelper.combinedContextKey(\n\t\t\t\tcontextIds,\n\t\t\t\tthis._partitionContextIds\n\t\t\t);\n\n\t\t\tconst { whereClause, params, noResults } = this.buildCqlConditions(conditions, partitionKey);\n\n\t\t\tif (noResults) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tconst sql = `SELECT COUNT(*) FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${whereClause} ALLOW FILTERING`;\n\n\t\t\tconnection = await this.openConnection();\n\t\t\tconst result = await this.queryDB(connection, sql, params);\n\t\t\treturn Number(result.rows[0]?.get(\"count\") ?? 0);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"countFailed\", undefined, err);\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 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\t// Reuse the cached keyspace-scoped client when available (avoids repeated\n\t\t// cassandra-driver cluster-discovery on every operation).\n\t\tif (!skipKeySpace && this._persistentClient !== undefined) {\n\t\t\treturn this._persistentClient;\n\t\t}\n\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\tif (!skipKeySpace) {\n\t\t\tthis._persistentClient = client;\n\t\t}\n\n\t\treturn client;\n\t}\n\n\t/**\n\t * Close database connection.\n\t * When `connection` is the cached persistent client it is kept alive so it\n\t * can be reused by future operations; call `closePersistentClient()` to\n\t * explicitly shut it down (e.g. from `teardown()`).\n\t * @param connection The connection to close.\n\t * @returns Nothing.\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\tif (connection === this._persistentClient) {\n\t\t\t// Keep the persistent client alive for reuse.\n\t\t\treturn;\n\t\t}\n\t\treturn connection.shutdown();\n\t}\n\n\t/**\n\t * Shut down and clear the persistent client. Call this from `teardown()`\n\t * implementations to release the underlying TCP connection.\n\t * @internal\n\t */\n\tprotected async closePersistentClient(): Promise<void> {\n\t\tif (this._persistentClient !== undefined) {\n\t\t\tawait this._persistentClient.shutdown();\n\t\t\tthis._persistentClient = undefined;\n\t\t}\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 pageState The page state to use when it comes to pagination.\n\t * @param limit The maximum number of rows to return.\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 * @param params The optional params to use when executing the statement.\n\t * @returns The result set.\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 * @returns The result set.\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 * @throws GeneralError if parsing JSON fails.\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.\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 EntityStorageHelper.unPrepareEntity(obj as T, [AbstractScyllaDBConnector.PARTITION_KEY]);\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\t/**\n\t * Get a safe table name by replacing any non-alphanumeric characters.\n\t * @param name The name to sanitize.\n\t * @returns The safe table name.\n\t */\n\tprotected safeTableName(name: string): string {\n\t\treturn name.replace(/[^\\dA-Za-z]/g, \"\");\n\t}\n\n\t/**\n\t * Parse, validate, and build a CQL WHERE clause from an EntityCondition tree.\n\t * The partition key equality is always the first clause; user conditions follow.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @param partitionKey The partition key value to filter by.\n\t * @returns The complete WHERE clause (without the WHERE keyword) and bound params.\n\t * @throws GeneralError if OR conditions, dot-notation paths, null comparisons, NotEquals, or NotIncludes operators are used.\n\t * @internal\n\t */\n\tprivate buildCqlConditions(\n\t\tconditions: EntityCondition<T> | undefined,\n\t\tpartitionKey: string | undefined\n\t): { whereClause: string; params: unknown[]; noResults?: boolean } {\n\t\tlet conditionsList: EntityCondition<T>[] = [];\n\t\tif (conditions !== undefined) {\n\t\t\tif (\"conditions\" in conditions) {\n\t\t\t\tif ((conditions as IComparatorGroup).logicalOperator === LogicalOperator.Or) {\n\t\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"orConditionNotSupported\");\n\t\t\t\t}\n\t\t\t\tconditionsList = conditions.conditions;\n\t\t\t} else {\n\t\t\t\tconditionsList = [conditions];\n\t\t\t}\n\t\t}\n\n\t\tfor (const cond of conditionsList) {\n\t\t\tconst comparator = cond as IComparator;\n\t\t\tif (String(comparator.property).includes(\".\")) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\t\t\tproperty: comparator.property,\n\t\t\t\t\treason: \"dot-notation nested property paths are not supported in CQL\"\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (\n\t\t\t\t(comparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals) &&\n\t\t\t\t(comparator.value === null || comparator.value === undefined)\n\t\t\t) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\t\t\tproperty: comparator.property,\n\t\t\t\t\treason: \"null/undefined comparisons are not supported in CQL WHERE clauses\"\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"notEqualsNotSupported\", {\n\t\t\t\t\tproperty: comparator.property\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\t\tthrow new GeneralError(AbstractScyllaDBConnector.CLASS_NAME, \"notIncludesNotSupported\", {\n\t\t\t\t\tproperty: comparator.property\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst conds: string[] = [];\n\t\tconst params: unknown[] = [partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE];\n\n\t\tfor (const cond of conditionsList) {\n\t\t\tconst condition = cond as IComparator;\n\t\t\tconst descriptor = this._entitySchema.properties?.find(\n\t\t\t\tp => p.property === condition.property\n\t\t\t);\n\t\t\tif (\n\t\t\t\tcondition.comparison === ComparisonOperator.Includes ||\n\t\t\t\tcondition.comparison === ComparisonOperator.NotIncludes\n\t\t\t) {\n\t\t\t\tconst serialized = this.propertyToDbValue(condition.value, descriptor);\n\t\t\t\tconst propValue = `'%${Is.stringValue(serialized) ? serialized : \"\"}%'`;\n\t\t\t\tif (condition.comparison === ComparisonOperator.Includes) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" LIKE ${propValue}`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.NotIncludes) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" NOT LIKE ${propValue}`);\n\t\t\t\t}\n\t\t\t} else if (condition.comparison === ComparisonOperator.In) {\n\t\t\t\t// Guard must come first: Is.arrayValue([]) returns false for an empty array,\n\t\t\t\t// so an empty value would be wrapped as a single element below and bypass\n\t\t\t\t// the length check. Check Is.array (true for any array) before branching (#141).\n\t\t\t\tif (Is.array(condition.value) && condition.value.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\twhereClause: \"\",\n\t\t\t\t\t\tparams: [],\n\t\t\t\t\t\tnoResults: true\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tlet value: unknown[] = [];\n\t\t\t\tif (!Is.arrayValue(condition.value)) {\n\t\t\t\t\tvalue.push(this.propertyToDbValue(condition.value, descriptor));\n\t\t\t\t} else {\n\t\t\t\t\tvalue = condition.value.map(v => this.propertyToDbValue(v, descriptor));\n\t\t\t\t}\n\t\t\t\tparams.push(value);\n\t\t\t\tconds.push(`\"${condition.property}\" IN ?`);\n\t\t\t} else {\n\t\t\t\tconst propValue = this.propertyToDbValue(condition.value, descriptor);\n\t\t\t\tparams.push(propValue);\n\t\t\t\tif (condition.comparison === ComparisonOperator.Equals) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" = ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" != ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.GreaterThan) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" > ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.LessThan) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" < ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" >= ?`);\n\t\t\t\t} else if (condition.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\t\t\tconds.push(`\"${condition.property}\" <= ?`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst operator =\n\t\t\t\"conditions\" in (conditions ?? {})\n\t\t\t\t? ((conditions as IComparatorGroup).logicalOperator ?? LogicalOperator.And)\n\t\t\t\t: LogicalOperator.And;\n\n\t\tlet whereClause = `\"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ?`;\n\t\tif (conds.length > 0) {\n\t\t\twhereClause += ` AND ${conds.join(` ${operator} `)}`;\n\t\t}\n\n\t\treturn { whereClause, params };\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scyllaDBTableConnector.js","sourceRoot":"","sources":["../../src/scyllaDBTableConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGeneralError,\n\tGuards,\n\tHealthStatus,\n\tIs,\n\ttype IError,\n\ttype IHealth\n} from \"@twin.org/core\";\nimport {\n\tEntitySchemaFactory,\n\tEntitySchemaPropertyType,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty\n} from \"@twin.org/entity\";\nimport {\n\tEntityStorageHelper,\n\ttype IEntityStorageMigrationConnector,\n\ttype IMigrationOptions\n} from \"@twin.org/entity-storage-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { AbstractScyllaDBConnector } from \"./abstractScyllaDBConnector.js\";\nimport type { IScyllaDBTableConnectorConstructorOptions } from \"./models/IScyllaDBTableConnectorConstructorOptions.js\";\n\n/**\n * Store entities using ScyllaDB.\n */\nexport class ScyllaDBTableConnector<T = unknown>\n\textends AbstractScyllaDBConnector<T>\n\timplements IEntityStorageMigrationConnector<T>\n{\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ScyllaDBTableConnector>();\n\n\t/**\n\t * The name for the schema.\n\t * @internal\n\t */\n\tprivate readonly _entitySchemaName: string;\n\n\t/**\n\t * Create a new instance of ScyllaDBTableConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IScyllaDBTableConnectorConstructorOptions) {\n\t\tsuper(options);\n\t\tthis._entitySchemaName = options.entitySchema;\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 ScyllaDBTableConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the health of the component.\n\t * @returns The health of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\t\t\tawait this.queryDB(\n\t\t\t\tconnection,\n\t\t\t\t`SELECT * FROM \"${this.safeTableName(this._fullTableName)}\" LIMIT 1`,\n\t\t\t\t[]\n\t\t\t);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t}\n\t\t\t];\n\t\t} catch {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tmessage: \"connectionFailed\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t}\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 * Bootstrap the component by creating and initializing any resources it needs.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the bootstrapping process was successful.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\ttry {\n\t\t\tlet dbConnection = await this.openConnection(true);\n\n\t\t\tconst exists = await this.checkKeyspaceExists(dbConnection, this._config.keyspace);\n\n\t\t\tif (exists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"keyspaceExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tkeyspace: this._config.keyspace\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"keyspaceCreating\",\n\t\t\t\t\tdata: { keyspace: this._config.keyspace }\n\t\t\t\t});\n\t\t\t\tawait this.createKeyspace(dbConnection, this._config.keyspace);\n\t\t\t}\n\n\t\t\t// Connection has to be closed and now open a new one with our keyspace\n\t\t\tawait this.closeConnection(dbConnection);\n\t\t\tdbConnection = await this.openConnection();\n\n\t\t\t// Need to find structured properties (declared as type: object)\n\t\t\tconst structuredProperties = this._entitySchema.properties?.filter(\n\t\t\t\tproperty =>\n\t\t\t\t\t(property.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\tproperty.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\tIs.stringValue(property.itemTypeRef)\n\t\t\t);\n\n\t\t\t// Needs to support objects that may have itemRef other objects (to be done)\n\t\t\tif (Is.array(structuredProperties)) {\n\t\t\t\tfor (const strProperty of structuredProperties) {\n\t\t\t\t\tconst subTypeSchemaRef = strProperty.itemTypeRef;\n\t\t\t\t\tif (Is.stringValue(subTypeSchemaRef)) {\n\t\t\t\t\t\tif (!(await this.checkTypeExists(dbConnection, subTypeSchemaRef))) {\n\t\t\t\t\t\t\tconst objSchema = EntitySchemaFactory.get(subTypeSchemaRef);\n\t\t\t\t\t\t\tconst typeFields: string[] = [];\n\t\t\t\t\t\t\tfor (const field of objSchema.properties ?? []) {\n\t\t\t\t\t\t\t\ttypeFields.push(`\"${String(field.property)}\" ${this.toDbField(field)}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst sql = `CREATE TYPE IF NOT EXISTS \"${subTypeSchemaRef}\" (${typeFields.join(\",\")})`;\n\n\t\t\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\t\t\tmessage: \"typeCreating\",\n\t\t\t\t\t\t\t\tdata: { typeName: subTypeSchemaRef }\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait this.execute(dbConnection, sql);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst tableExists = await this.checkTableExists(\n\t\t\t\tdbConnection,\n\t\t\t\tthis._config.keyspace,\n\t\t\t\tthis.safeTableName(this._fullTableName)\n\t\t\t);\n\n\t\t\tif (tableExists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\ttable: this.safeTableName(this._fullTableName)\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst sql = `CREATE TABLE IF NOT EXISTS \"${this.safeTableName(this._fullTableName)}\" (${this.buildSchemaColumns(this._entitySchema)})`;\n\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreating\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t});\n\n\t\t\t\tawait this.execute(dbConnection, sql);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceInUseException\")) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableExists\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreateFailed\",\n\t\t\t\t\terror: err as IError,\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set an entity.\n\t * @param entity The entity to set.\n\t * @param conditions The optional conditions to match for the entities.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(ScyllaDBTableConnector.CLASS_NAME, nameof(entity), entity);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst normalizedEntity = EntityStorageHelper.prepareEntity(\n\t\t\tentity,\n\t\t\tthis._entitySchema,\n\t\t\tpartitionKey\n\t\t\t\t? [{ property: AbstractScyllaDBConnector.PARTITION_KEY, value: partitionKey }]\n\t\t\t\t: undefined,\n\t\t\t{ nullBehavior: \"omit\" }\n\t\t);\n\n\t\tlet connection;\n\t\tconst id = normalizedEntity[this._primaryKey?.property] as string;\n\t\ttry {\n\t\t\tconst propValues: unknown[] = [];\n\t\t\tconst updateValues: string[] = [];\n\n\t\t\tconst finalConditions: { property: keyof T; value: unknown }[] = [];\n\n\t\t\tfinalConditions.push({\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\n\t\t\tfor (const propDesc of this._entitySchema.properties ?? []) {\n\t\t\t\tif (!propDesc.isPrimary && !propDesc.isSecondary) {\n\t\t\t\t\tconst val = this.propertyToDbValue(normalizedEntity[propDesc.property], propDesc);\n\t\t\t\t\tif (val !== null && val !== undefined) {\n\t\t\t\t\t\tpropValues.push(val);\n\t\t\t\t\t\tupdateValues.push(`\"${String(propDesc.property)}\"=?`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfinalConditions.push({\n\t\t\t\t\t\tproperty: propDesc.property,\n\t\t\t\t\t\tvalue: this.propertyToDbValue(normalizedEntity[propDesc.property], propDesc)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfinalConditions.push(...conditions);\n\t\t\t}\n\n\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(finalConditions);\n\n\t\t\tlet sql: string;\n\t\t\tlet execParams: unknown[];\n\t\t\tif (updateValues.length > 0 || Is.arrayValue(conditions)) {\n\t\t\t\tpropValues.push(...conditionValues);\n\t\t\t\tsql = `UPDATE \"${this.safeTableName(this._fullTableName)}\" SET ${updateValues.join(\",\")} WHERE ${sqlCondition}`;\n\t\t\t\texecParams = propValues;\n\t\t\t} else {\n\t\t\t\t// No non-null data columns and no extra conditions — INSERT writes a row marker\n\t\t\t\t// so the entity remains visible in SELECT even when all data fields are null.\n\t\t\t\tconst cols = finalConditions.map(c => `\"${String(c.property)}\"`).join(\",\");\n\t\t\t\tconst placeholders = finalConditions.map(() => \"?\").join(\",\");\n\t\t\t\tsql = `INSERT INTO \"${this.safeTableName(this._fullTableName)}\" (${cols}) VALUES (${placeholders})`;\n\t\t\t\texecParams = conditionValues;\n\t\t\t}\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: ScyllaDBTableConnector.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\tawait this.execute(connection, sql, execParams);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"setFailed\",\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 * Set multiple entities in a batch.\n\t * @param entities The entities to set.\n\t * @returns Nothing.\n\t */\n\tpublic async setBatch(entities: T[]): Promise<void> {\n\t\tGuards.arrayValue(ScyllaDBTableConnector.CLASS_NAME, nameof(entities), entities);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst normalizedEntities = entities.map(entity =>\n\t\t\tEntityStorageHelper.prepareEntity(\n\t\t\t\tentity,\n\t\t\t\tthis._entitySchema,\n\t\t\t\tpartitionKey\n\t\t\t\t\t? [{ property: AbstractScyllaDBConnector.PARTITION_KEY, value: partitionKey }]\n\t\t\t\t\t: undefined,\n\t\t\t\t{ nullBehavior: \"omit\" }\n\t\t\t)\n\t\t);\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\n\t\t\t// Delete existing rows first so that a change in the clustering key (secondary\n\t\t\t// field) does not leave a stale row behind. Two separate batches are used to\n\t\t\t// ensure the deletes commit before the upserts, avoiding same-timestamp conflicts.\n\t\t\tconst deleteQueries: { query: string; params: unknown[] }[] = [];\n\t\t\tconst upsertQueries: { query: string; params: unknown[] }[] = [];\n\n\t\t\tfor (const entity of normalizedEntities) {\n\t\t\t\tconst id = entity[this._primaryKey.property] as string;\n\t\t\t\tconst pk = partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE;\n\n\t\t\t\tdeleteQueries.push({\n\t\t\t\t\tquery: `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE \"${AbstractScyllaDBConnector.PARTITION_KEY}\"=? AND \"${String(this._primaryKey.property)}\"=?`,\n\t\t\t\t\tparams: [pk, id]\n\t\t\t\t});\n\n\t\t\t\tconst propValues: unknown[] = [];\n\t\t\t\tconst updateValues: string[] = [];\n\t\t\t\tconst finalConditions: { property: keyof T; value: unknown }[] = [];\n\n\t\t\t\tfinalConditions.push({\n\t\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\t\tvalue: pk\n\t\t\t\t});\n\n\t\t\t\tfor (const propDesc of this._entitySchema.properties ?? []) {\n\t\t\t\t\tif (!propDesc.isPrimary && !propDesc.isSecondary) {\n\t\t\t\t\t\tconst val = this.propertyToDbValue(entity[propDesc.property], propDesc);\n\t\t\t\t\t\tif (val !== null && val !== undefined) {\n\t\t\t\t\t\t\tpropValues.push(val);\n\t\t\t\t\t\t\tupdateValues.push(`\"${String(propDesc.property)}\"=?`);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfinalConditions.push({\n\t\t\t\t\t\t\tproperty: propDesc.property,\n\t\t\t\t\t\t\tvalue: this.propertyToDbValue(entity[propDesc.property], propDesc)\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(finalConditions);\n\n\t\t\t\tlet sql: string;\n\t\t\t\tlet queryParams: unknown[];\n\t\t\t\tif (updateValues.length > 0) {\n\t\t\t\t\tpropValues.push(...conditionValues);\n\t\t\t\t\tsql = `UPDATE \"${this.safeTableName(this._fullTableName)}\" SET ${updateValues.join(\",\")} WHERE ${sqlCondition}`;\n\t\t\t\t\tqueryParams = propValues;\n\t\t\t\t} else {\n\t\t\t\t\t// No non-null data columns — INSERT writes a row marker so the entity\n\t\t\t\t\t// remains visible in SELECT even when all data fields are null.\n\t\t\t\t\tconst cols = finalConditions.map(c => `\"${String(c.property)}\"`).join(\",\");\n\t\t\t\t\tconst placeholders = finalConditions.map(() => \"?\").join(\",\");\n\t\t\t\t\tsql = `INSERT INTO \"${this.safeTableName(this._fullTableName)}\" (${cols}) VALUES (${placeholders})`;\n\t\t\t\t\tqueryParams = conditionValues;\n\t\t\t\t}\n\t\t\t\tupsertQueries.push({ query: sql, params: queryParams });\n\t\t\t}\n\n\t\t\tawait connection.batch(deleteQueries, { prepare: true });\n\t\t\tawait connection.batch(upsertQueries, { prepare: true });\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(ScyllaDBTableConnector.CLASS_NAME, \"setBatchFailed\", undefined, err);\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Remove all entities from the storage.\n\t * @param partitionKey The optional partition key.\n\t */\n\tpublic async empty(partitionKey?: string): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst resolvedPartitionKey =\n\t\t\tpartitionKey ??\n\t\t\tContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds) ??\n\t\t\tAbstractScyllaDBConnector.PARTITION_KEY_VALUE;\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\n\t\t\tconst result = await this.queryDB(\n\t\t\t\tconnection,\n\t\t\t\t`SELECT * FROM \"${this.safeTableName(this._fullTableName)}\" WHERE \"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ? ALLOW FILTERING`,\n\t\t\t\t[resolvedPartitionKey],\n\t\t\t\tundefined,\n\t\t\t\t0\n\t\t\t);\n\n\t\t\tif (result.rows.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst queries: { query: string; params: unknown[] }[] = [];\n\n\t\t\tfor (const row of result.rows) {\n\t\t\t\tconst conditions: { property: keyof T; value: unknown }[] = [\n\t\t\t\t\t{\n\t\t\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\t\t\tvalue: resolvedPartitionKey\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t\tfor (const prop of this._entitySchema.properties ?? []) {\n\t\t\t\t\tif (prop.isPrimary || prop.isSecondary) {\n\t\t\t\t\t\tconditions.push({ property: prop.property, value: row[prop.property as string] });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\t\t\t\tqueries.push({\n\t\t\t\t\tquery: `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${sqlCondition}`,\n\t\t\t\t\tparams: conditionValues\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait connection.batch(queries, { prepare: true });\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(ScyllaDBTableConnector.CLASS_NAME, \"emptyFailed\", undefined, err);\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the entity.\n\t * @param id The id of the entity to remove.\n\t * @param conditions The optional conditions to match for the entities.\n\t */\n\tpublic async remove(\n\t\tid: string,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<void> {\n\t\tGuards.stringValue(ScyllaDBTableConnector.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\n\t\ttry {\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({ property: this._primaryKey?.property, value: id });\n\n\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\n\t\t\tconst sql = `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${sqlCondition}`;\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: ScyllaDBTableConnector.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\tawait this.execute(connection, sql, conditionValues);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"removeFailed\",\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 * Remove multiple entities.\n\t * @param ids The ids of the entities to remove.\n\t */\n\tpublic async removeBatch(ids: string[]): Promise<void> {\n\t\tGuards.arrayValue(ScyllaDBTableConnector.CLASS_NAME, nameof(ids), ids);\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\tconnection = await this.openConnection();\n\t\t\tconst queries: { query: string; params: unknown[] }[] = [];\n\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst conditions: { property: keyof T; value: unknown }[] = [\n\t\t\t\t\t{\n\t\t\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\t\t\tvalue: partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE\n\t\t\t\t\t},\n\t\t\t\t\t{ property: this._primaryKey.property, value: id }\n\t\t\t\t];\n\t\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\t\t\t\tqueries.push({\n\t\t\t\t\tquery: `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${sqlCondition}`,\n\t\t\t\t\tparams: conditionValues\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait connection.batch(queries, { prepare: true });\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"removeBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\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 * Teardown the entity storage by dropping the table.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the teardown process was successful.\n\t */\n\tpublic async teardown(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tawait nodeLogging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"tableDropping\",\n\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t});\n\n\t\tlet connection;\n\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\t\t\tawait connection.execute(`DROP TABLE IF EXISTS \"${this.safeTableName(this._fullTableName)}\"`);\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableDropped\",\n\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t});\n\n\t\t\t// Drop UDTs referenced by this schema so they are recreated with the\n\t\t\t// current schema on the next bootstrap (table must be gone first).\n\t\t\tconst structuredProperties = this._entitySchema.properties?.filter(\n\t\t\t\tproperty =>\n\t\t\t\t\t(property.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\tproperty.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\tIs.stringValue(property.itemTypeRef)\n\t\t\t);\n\t\t\tif (Is.array(structuredProperties)) {\n\t\t\t\tfor (const prop of structuredProperties) {\n\t\t\t\t\tif (Is.stringValue(prop.itemTypeRef)) {\n\t\t\t\t\t\tawait connection.execute(`DROP TYPE IF EXISTS \"${prop.itemTypeRef}\"`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"teardownFailed\",\n\t\t\t\terror: BaseError.fromError(err)\n\t\t\t});\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t\tawait this.closePersistentClient();\n\t\t}\n\t}\n\n\t/**\n\t * Get all the distinct partition context ids from the storage.\n\t * @returns An array of context id objects, one per unique partition.\n\t */\n\tpublic async getPartitionContextIds(): Promise<IContextIds[]> {\n\t\tif (!Is.arrayValue(this._partitionContextIds)) {\n\t\t\treturn [];\n\t\t}\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\t\t\tconst result = await this.queryDB(\n\t\t\t\tconnection,\n\t\t\t\t`SELECT \"${AbstractScyllaDBConnector.PARTITION_KEY}\" FROM \"${this.safeTableName(this._fullTableName)}\" ALLOW FILTERING`,\n\t\t\t\t[],\n\t\t\t\tundefined,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst seen = new Set<string>();\n\t\t\tconst contextIds: IContextIds[] = [];\n\t\t\tfor (const row of result.rows) {\n\t\t\t\tconst id = row[AbstractScyllaDBConnector.PARTITION_KEY] as string;\n\t\t\t\tif (Is.stringValue(id) && !seen.has(id)) {\n\t\t\t\t\tseen.add(id);\n\t\t\t\t\tcontextIds.push(ContextIdHelper.shortSplit(this._partitionContextIds ?? [], id));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn contextIds;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"getPartitionContextIdsFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\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 * Create a new target connector for the migration.\n\t * @param entitySchemaName The entity schema name to use for the target connector.\n\t * @returns A new connector configured with a migration table name.\n\t */\n\tpublic async createTargetConnector<U>(\n\t\tentitySchemaName: string\n\t): Promise<ScyllaDBTableConnector<U>> {\n\t\t// We create a new table for the migration with a unique name to avoid conflicts with the existing table\n\t\t// This table will be swapped with the existing table once the migration is finalized.\n\t\tconst migrationTableName = `${this._config.tableName}Migration${Date.now()}`;\n\n\t\treturn new ScyllaDBTableConnector<U>({\n\t\t\tentitySchema: entitySchemaName,\n\t\t\tconfig: {\n\t\t\t\t...this._config,\n\t\t\t\ttableName: migrationTableName\n\t\t\t},\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by pointing a new connector at the migration table.\n\t * @param targetConnector The connector pointing to the migration table.\n\t * @param options The optional migration options.\n\t * @param loggingComponentType The node logging component type.\n\t * @returns A connector pointing to the migration table (now the live table).\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: ScyllaDBTableConnector<U>,\n\t\toptions?: IMigrationOptions<T, U>,\n\t\tloggingComponentType?: string\n\t): Promise<ScyllaDBTableConnector<U>> {\n\t\t// There is no rename operation in ScyllaDB, so we have to create a new table with the original name and copy the data over\n\n\t\t// Teardown the existing table with the original name to free up the name for the new table\n\t\tawait this.teardown(loggingComponentType);\n\n\t\tconst finalConnector = new ScyllaDBTableConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\n\t\tif (await finalConnector.bootstrap(loggingComponentType)) {\n\t\t\t// Since there is no rename, we need to copy the data from the migration table to the new table\n\t\t\tconst partitions = await targetConnector.getPartitionContextIds();\n\t\t\tconst batchSize = options?.batchSize ?? ScyllaDBTableConnector.DEFAULT_LIMIT;\n\t\t\tawait this.bulkCopy(targetConnector, finalConnector, partitions, batchSize);\n\n\t\t\tawait targetConnector.teardown(loggingComponentType);\n\t\t\treturn finalConnector;\n\t\t}\n\n\t\tthrow new GeneralError(\n\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\"finalizeMigrationFailedBootstrap\",\n\t\t\tundefined\n\t\t);\n\t}\n\n\t/**\n\t * Clean up the migration by tearing down the migration table.\n\t * @param targetConnector The connector pointing to the migration table.\n\t * @param options The optional migration options.\n\t * @param loggingComponentType The node logging component type.\n\t */\n\tpublic async cleanupMigration<U>(\n\t\ttargetConnector?: ScyllaDBTableConnector<U>,\n\t\toptions?: IMigrationOptions<T, U>,\n\t\tloggingComponentType?: string\n\t): Promise<void> {\n\t\t// If something failed the only thing to cleanup is the migration table\n\t\tawait targetConnector?.teardown?.(loggingComponentType);\n\t}\n\n\t/**\n\t * Copy all entities from sourceConnector to destConnector, paging through each partition.\n\t * @param sourceConnector The connector to read entities from.\n\t * @param destConnector The connector to write entities to.\n\t * @param partitions The partition list returned by getPartitionContextIds.\n\t * @param batchSize The number of entities to read per page.\n\t * @internal\n\t */\n\tprivate async bulkCopy<U>(\n\t\tsourceConnector: ScyllaDBTableConnector<U>,\n\t\tdestConnector: ScyllaDBTableConnector<U>,\n\t\tpartitions: IContextIds[],\n\t\tbatchSize: number\n\t): Promise<void> {\n\t\tlet partitionList: IContextIds[];\n\t\tif (Is.arrayValue(partitions)) {\n\t\t\tpartitionList = partitions;\n\t\t} else if (Is.arrayValue(sourceConnector._partitionContextIds)) {\n\t\t\tpartitionList = [];\n\t\t} else {\n\t\t\tpartitionList = [{}];\n\t\t}\n\n\t\tconst sourceColumns = [\n\t\t\tAbstractScyllaDBConnector.PARTITION_KEY,\n\t\t\t...(sourceConnector._entitySchema.properties?.map(p => p.property as string) ?? [])\n\t\t];\n\t\tconst insertSql = `INSERT INTO \"${destConnector.safeTableName(destConnector._fullTableName)}\" (${sourceColumns.map(c => `\"${c}\"`).join(\", \")}) VALUES (${sourceColumns.map(() => \"?\").join(\", \")})`;\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await sourceConnector.openConnection();\n\t\t\tfor (let i = 0; i < partitionList.length; i++) {\n\t\t\t\tconst partitionKey =\n\t\t\t\t\tContextIdHelper.combinedContextKey(\n\t\t\t\t\t\tpartitionList[i],\n\t\t\t\t\t\tsourceConnector._partitionContextIds\n\t\t\t\t\t) ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE;\n\n\t\t\t\tlet pageState: string | undefined;\n\t\t\t\tdo {\n\t\t\t\t\tconst result = await sourceConnector.queryDB(\n\t\t\t\t\t\tconnection,\n\t\t\t\t\t\t`SELECT * FROM \"${sourceConnector.safeTableName(sourceConnector._fullTableName)}\" WHERE \"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ? ALLOW FILTERING`,\n\t\t\t\t\t\t[partitionKey],\n\t\t\t\t\t\tpageState,\n\t\t\t\t\t\tbatchSize\n\t\t\t\t\t);\n\n\t\t\t\t\tpageState = Is.stringValue(result.pageState) ? result.pageState : undefined;\n\n\t\t\t\t\tif (Is.arrayValue(result.rows)) {\n\t\t\t\t\t\tawait connection.batch(\n\t\t\t\t\t\t\tresult.rows.map((row: { [key: string]: unknown }) => ({\n\t\t\t\t\t\t\t\tquery: insertSql,\n\t\t\t\t\t\t\t\tparams: sourceColumns.map(col => row[col])\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t{ prepare: true }\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} while (Is.stringValue(pageState));\n\t\t\t}\n\t\t} finally {\n\t\t\tawait sourceConnector.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Transform a logical description of a field into a DB field.\n\t * @param logicalField The logical field description.\n\t * @returns The DB type.\n\t * @throws GeneralException if no mapping found.\n\t * @internal\n\t */\n\tprivate toDbField(logicalField: IEntitySchemaProperty<T>): string {\n\t\tlet dbType: string;\n\n\t\tswitch (logicalField.type) {\n\t\t\tcase \"string\":\n\t\t\t\tdbType = \"TEXT\";\n\t\t\t\tswitch (logicalField.format) {\n\t\t\t\t\tcase \"uuid\":\n\t\t\t\t\t\tdbType = \"UUID\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"date\":\n\t\t\t\t\tcase \"date-time\":\n\t\t\t\t\t\tdbType = \"TIMESTAMP\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"number\":\n\t\t\t\tdbType = \"DOUBLE\";\n\t\t\t\tswitch (logicalField.format) {\n\t\t\t\t\tcase \"float\":\n\t\t\t\t\t\tdbType = \"FLOAT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"double\":\n\t\t\t\t\t\tdbType = \"DOUBLE\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"integer\":\n\t\t\t\tdbType = \"INT\";\n\t\t\t\tswitch (logicalField.format) {\n\t\t\t\t\tcase \"int8\":\n\t\t\t\t\tcase \"uint8\":\n\t\t\t\t\t\tdbType = \"TINYINT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"int16\":\n\t\t\t\t\tcase \"uint16\":\n\t\t\t\t\t\tdbType = \"SMALLINT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"int32\":\n\t\t\t\t\tcase \"uint32\":\n\t\t\t\t\t\tdbType = \"INT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"int64\":\n\t\t\t\t\tcase \"uint64\":\n\t\t\t\t\t\tdbType = \"BIGINT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"boolean\":\n\t\t\t\tdbType = \"BOOLEAN\";\n\t\t\t\tbreak;\n\t\t\tcase \"object\":\n\t\t\t\tif (Is.stringValue(logicalField.itemTypeRef)) {\n\t\t\t\t\tdbType = `frozen<\"${logicalField.itemTypeRef}\">`;\n\t\t\t\t} else {\n\t\t\t\t\t// Item type is unknown object, store as TEXT\n\t\t\t\t\t// so that it can be JSON serialized\n\t\t\t\t\tdbType = \"TEXT\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"array\":\n\t\t\t\tif (Is.stringValue(logicalField.itemTypeRef)) {\n\t\t\t\t\tif (Is.stringValue(logicalField.itemType)) {\n\t\t\t\t\t\tdbType = `SET<${this.toDbField({\n\t\t\t\t\t\t\tproperty: logicalField.property,\n\t\t\t\t\t\t\ttype: logicalField.itemType\n\t\t\t\t\t\t})}>`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdbType = `SET<frozen<\"${logicalField.itemTypeRef}\">>`;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Item type is unknown object, store as TEXT\n\t\t\t\t\t// so that it can be JSON serialized\n\t\t\t\t\tdbType = \"TEXT\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn dbType;\n\t}\n\n\t/**\n\t * Build the CQL column definitions string for a CREATE TABLE statement.\n\t * @param schema The entity schema to build DDL from.\n\t * @returns The column definitions string (without the outer parentheses).\n\t * @internal\n\t */\n\tprivate buildSchemaColumns(schema: IEntitySchema<T>): string {\n\t\tconst fields: string[] = [];\n\t\tconst clusteringKeys: string[] = [];\n\n\t\t// partitionId is always the sole partition key so that WHERE \"partitionId\" = ?\n\t\t// allows ORDER BY on the subsequent clustering keys.\n\t\tfields.push(`\"${AbstractScyllaDBConnector.PARTITION_KEY}\" TEXT`);\n\n\t\tfor (const field of schema.properties ?? []) {\n\t\t\tfields.push(`\"${String(field.property)}\" ${this.toDbField(field)}`);\n\t\t\tif (field.isPrimary || field.isSecondary) {\n\t\t\t\tclusteringKeys.push(`\"${field.property as string}\"`);\n\t\t\t}\n\t\t}\n\n\t\tif (clusteringKeys.length > 0) {\n\t\t\tfields.push(\n\t\t\t\t`PRIMARY KEY (\"${AbstractScyllaDBConnector.PARTITION_KEY}\", ${clusteringKeys.join(\", \")})`\n\t\t\t);\n\t\t} else {\n\t\t\tfields.push(`PRIMARY KEY (\"${AbstractScyllaDBConnector.PARTITION_KEY}\")`);\n\t\t}\n\n\t\treturn fields.join(\", \");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scyllaDBTableConnector.js","sourceRoot":"","sources":["../../src/scyllaDBTableConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGeneralError,\n\tGuards,\n\tHealthStatus,\n\tIs,\n\ttype IError,\n\ttype IHealth\n} from \"@twin.org/core\";\nimport {\n\tEntitySchemaFactory,\n\tEntitySchemaPropertyType,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty\n} from \"@twin.org/entity\";\nimport {\n\tEntityStorageHelper,\n\ttype IEntityStorageMigrationConnector,\n\ttype IMigrationOptions\n} from \"@twin.org/entity-storage-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { AbstractScyllaDBConnector } from \"./abstractScyllaDBConnector.js\";\nimport type { IScyllaDBTableConnectorConstructorOptions } from \"./models/IScyllaDBTableConnectorConstructorOptions.js\";\n\n/**\n * Store entities using ScyllaDB.\n */\nexport class ScyllaDBTableConnector<T = unknown>\n\textends AbstractScyllaDBConnector<T>\n\timplements IEntityStorageMigrationConnector<T>\n{\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ScyllaDBTableConnector>();\n\n\t/**\n\t * The name for the schema.\n\t * @internal\n\t */\n\tprivate readonly _entitySchemaName: string;\n\n\t/**\n\t * Create a new instance of ScyllaDBTableConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IScyllaDBTableConnectorConstructorOptions) {\n\t\tsuper(options);\n\t\tthis._entitySchemaName = options.entitySchema;\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 ScyllaDBTableConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the health of the component.\n\t * @returns The health of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\t\t\tawait this.queryDB(\n\t\t\t\tconnection,\n\t\t\t\t`SELECT * FROM \"${this.safeTableName(this._fullTableName)}\" LIMIT 1`,\n\t\t\t\t[]\n\t\t\t);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t}\n\t\t\t];\n\t\t} catch {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tmessage: \"connectionFailed\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t}\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 * Bootstrap the component by creating and initializing any resources it needs.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the bootstrapping process was successful.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\ttry {\n\t\t\tlet dbConnection = await this.openConnection(true);\n\n\t\t\tconst exists = await this.checkKeyspaceExists(dbConnection, this._config.keyspace);\n\n\t\t\tif (exists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"keyspaceExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tkeyspace: this._config.keyspace\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"keyspaceCreating\",\n\t\t\t\t\tdata: { keyspace: this._config.keyspace }\n\t\t\t\t});\n\t\t\t\tawait this.createKeyspace(dbConnection, this._config.keyspace);\n\t\t\t}\n\n\t\t\t// Connection has to be closed and now open a new one with our keyspace\n\t\t\tawait this.closeConnection(dbConnection);\n\t\t\tdbConnection = await this.openConnection();\n\n\t\t\t// Need to find structured properties (declared as type: object)\n\t\t\tconst structuredProperties = this._entitySchema.properties?.filter(\n\t\t\t\tproperty =>\n\t\t\t\t\t(property.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\tproperty.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\tIs.stringValue(property.itemTypeRef)\n\t\t\t);\n\n\t\t\t// Needs to support objects that may have itemRef other objects (to be done)\n\t\t\tif (Is.array(structuredProperties)) {\n\t\t\t\tfor (const strProperty of structuredProperties) {\n\t\t\t\t\tconst subTypeSchemaRef = strProperty.itemTypeRef;\n\t\t\t\t\tif (Is.stringValue(subTypeSchemaRef)) {\n\t\t\t\t\t\tif (!(await this.checkTypeExists(dbConnection, subTypeSchemaRef))) {\n\t\t\t\t\t\t\tconst objSchema = EntitySchemaFactory.get(subTypeSchemaRef);\n\t\t\t\t\t\t\tconst typeFields: string[] = [];\n\t\t\t\t\t\t\tfor (const field of objSchema.properties ?? []) {\n\t\t\t\t\t\t\t\ttypeFields.push(`\"${String(field.property)}\" ${this.toDbField(field)}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst sql = `CREATE TYPE IF NOT EXISTS \"${subTypeSchemaRef}\" (${typeFields.join(\",\")})`;\n\n\t\t\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\t\t\tmessage: \"typeCreating\",\n\t\t\t\t\t\t\t\tdata: { typeName: subTypeSchemaRef }\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait this.execute(dbConnection, sql);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst tableExists = await this.checkTableExists(\n\t\t\t\tdbConnection,\n\t\t\t\tthis._config.keyspace,\n\t\t\t\tthis.safeTableName(this._fullTableName)\n\t\t\t);\n\n\t\t\tif (tableExists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\ttable: this.safeTableName(this._fullTableName)\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst sql = `CREATE TABLE IF NOT EXISTS \"${this.safeTableName(this._fullTableName)}\" (${this.buildSchemaColumns(this._entitySchema)})`;\n\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreating\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t});\n\n\t\t\t\tawait this.execute(dbConnection, sql);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceInUseException\")) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableExists\",\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreateFailed\",\n\t\t\t\t\terror: err as IError,\n\t\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set an entity.\n\t * @param entity The entity to set.\n\t * @param conditions The optional conditions to match for the entities.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(ScyllaDBTableConnector.CLASS_NAME, nameof(entity), entity);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst normalizedEntity = EntityStorageHelper.prepareEntity(\n\t\t\tentity,\n\t\t\tthis._entitySchema,\n\t\t\tpartitionKey\n\t\t\t\t? [{ property: AbstractScyllaDBConnector.PARTITION_KEY, value: partitionKey }]\n\t\t\t\t: undefined,\n\t\t\t{ nullBehavior: \"omit\" }\n\t\t);\n\n\t\tlet connection;\n\t\tconst id = normalizedEntity[this._primaryKey?.property] as string;\n\t\ttry {\n\t\t\tconst propValues: unknown[] = [];\n\t\t\tconst updateValues: string[] = [];\n\n\t\t\tconst finalConditions: { property: keyof T; value: unknown }[] = [];\n\n\t\t\tfinalConditions.push({\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\n\t\t\tfor (const propDesc of this._entitySchema.properties ?? []) {\n\t\t\t\tif (!propDesc.isPrimary && !propDesc.isSecondary) {\n\t\t\t\t\tconst val = this.propertyToDbValue(normalizedEntity[propDesc.property], propDesc);\n\t\t\t\t\tif (val !== null && val !== undefined) {\n\t\t\t\t\t\tpropValues.push(val);\n\t\t\t\t\t\tupdateValues.push(`\"${String(propDesc.property)}\"=?`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfinalConditions.push({\n\t\t\t\t\t\tproperty: propDesc.property,\n\t\t\t\t\t\tvalue: this.propertyToDbValue(normalizedEntity[propDesc.property], propDesc)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfinalConditions.push(...conditions);\n\t\t\t}\n\n\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(finalConditions);\n\n\t\t\tlet sql: string;\n\t\t\tlet execParams: unknown[];\n\t\t\tif (updateValues.length > 0 || Is.arrayValue(conditions)) {\n\t\t\t\tpropValues.push(...conditionValues);\n\t\t\t\tsql = `UPDATE \"${this.safeTableName(this._fullTableName)}\" SET ${updateValues.join(\",\")} WHERE ${sqlCondition}`;\n\t\t\t\texecParams = propValues;\n\t\t\t} else {\n\t\t\t\t// No non-null data columns and no extra conditions — INSERT writes a row marker\n\t\t\t\t// so the entity remains visible in SELECT even when all data fields are null.\n\t\t\t\tconst cols = finalConditions.map(c => `\"${String(c.property)}\"`).join(\",\");\n\t\t\t\tconst placeholders = finalConditions.map(() => \"?\").join(\",\");\n\t\t\t\tsql = `INSERT INTO \"${this.safeTableName(this._fullTableName)}\" (${cols}) VALUES (${placeholders})`;\n\t\t\t\texecParams = conditionValues;\n\t\t\t}\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: ScyllaDBTableConnector.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\tawait this.execute(connection, sql, execParams);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"setFailed\",\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 * Set multiple entities in a batch.\n\t * @param entities The entities to set.\n\t * @returns Nothing.\n\t */\n\tpublic async setBatch(entities: T[]): Promise<void> {\n\t\tGuards.arrayValue(ScyllaDBTableConnector.CLASS_NAME, nameof(entities), entities);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst normalizedEntities = entities.map(entity =>\n\t\t\tEntityStorageHelper.prepareEntity(\n\t\t\t\tentity,\n\t\t\t\tthis._entitySchema,\n\t\t\t\tpartitionKey\n\t\t\t\t\t? [{ property: AbstractScyllaDBConnector.PARTITION_KEY, value: partitionKey }]\n\t\t\t\t\t: undefined,\n\t\t\t\t{ nullBehavior: \"omit\" }\n\t\t\t)\n\t\t);\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\n\t\t\t// Delete existing rows first so that a change in the clustering key (secondary\n\t\t\t// field) does not leave a stale row behind. Two separate batches are used to\n\t\t\t// ensure the deletes commit before the upserts, avoiding same-timestamp conflicts.\n\t\t\tconst deleteQueries: { query: string; params: unknown[] }[] = [];\n\t\t\tconst upsertQueries: { query: string; params: unknown[] }[] = [];\n\n\t\t\tfor (const entity of normalizedEntities) {\n\t\t\t\tconst id = entity[this._primaryKey.property] as string;\n\t\t\t\tconst pk = partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE;\n\n\t\t\t\tdeleteQueries.push({\n\t\t\t\t\tquery: `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE \"${AbstractScyllaDBConnector.PARTITION_KEY}\"=? AND \"${String(this._primaryKey.property)}\"=?`,\n\t\t\t\t\tparams: [pk, id]\n\t\t\t\t});\n\n\t\t\t\tconst propValues: unknown[] = [];\n\t\t\t\tconst updateValues: string[] = [];\n\t\t\t\tconst finalConditions: { property: keyof T; value: unknown }[] = [];\n\n\t\t\t\tfinalConditions.push({\n\t\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\t\tvalue: pk\n\t\t\t\t});\n\n\t\t\t\tfor (const propDesc of this._entitySchema.properties ?? []) {\n\t\t\t\t\tif (!propDesc.isPrimary && !propDesc.isSecondary) {\n\t\t\t\t\t\tconst val = this.propertyToDbValue(entity[propDesc.property], propDesc);\n\t\t\t\t\t\tif (val !== null && val !== undefined) {\n\t\t\t\t\t\t\tpropValues.push(val);\n\t\t\t\t\t\t\tupdateValues.push(`\"${String(propDesc.property)}\"=?`);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfinalConditions.push({\n\t\t\t\t\t\t\tproperty: propDesc.property,\n\t\t\t\t\t\t\tvalue: this.propertyToDbValue(entity[propDesc.property], propDesc)\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(finalConditions);\n\n\t\t\t\tlet sql: string;\n\t\t\t\tlet queryParams: unknown[];\n\t\t\t\tif (updateValues.length > 0) {\n\t\t\t\t\tpropValues.push(...conditionValues);\n\t\t\t\t\tsql = `UPDATE \"${this.safeTableName(this._fullTableName)}\" SET ${updateValues.join(\",\")} WHERE ${sqlCondition}`;\n\t\t\t\t\tqueryParams = propValues;\n\t\t\t\t} else {\n\t\t\t\t\t// No non-null data columns — INSERT writes a row marker so the entity\n\t\t\t\t\t// remains visible in SELECT even when all data fields are null.\n\t\t\t\t\tconst cols = finalConditions.map(c => `\"${String(c.property)}\"`).join(\",\");\n\t\t\t\t\tconst placeholders = finalConditions.map(() => \"?\").join(\",\");\n\t\t\t\t\tsql = `INSERT INTO \"${this.safeTableName(this._fullTableName)}\" (${cols}) VALUES (${placeholders})`;\n\t\t\t\t\tqueryParams = conditionValues;\n\t\t\t\t}\n\t\t\t\tupsertQueries.push({ query: sql, params: queryParams });\n\t\t\t}\n\n\t\t\tawait connection.batch(deleteQueries, { prepare: true });\n\t\t\tawait connection.batch(upsertQueries, { prepare: true });\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(ScyllaDBTableConnector.CLASS_NAME, \"setBatchFailed\", undefined, err);\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Remove all entities from the storage.\n\t * @param partitionKey The optional partition key.\n\t */\n\tpublic async empty(partitionKey?: string): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst resolvedPartitionKey =\n\t\t\tpartitionKey ??\n\t\t\tContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds) ??\n\t\t\tAbstractScyllaDBConnector.PARTITION_KEY_VALUE;\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\n\t\t\tconst result = await this.queryDB(\n\t\t\t\tconnection,\n\t\t\t\t`SELECT * FROM \"${this.safeTableName(this._fullTableName)}\" WHERE \"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ? ALLOW FILTERING`,\n\t\t\t\t[resolvedPartitionKey],\n\t\t\t\tundefined,\n\t\t\t\t0\n\t\t\t);\n\n\t\t\tif (result.rows.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst queries: { query: string; params: unknown[] }[] = [];\n\n\t\t\tfor (const row of result.rows) {\n\t\t\t\tconst conditions: { property: keyof T; value: unknown }[] = [\n\t\t\t\t\t{\n\t\t\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\t\t\tvalue: resolvedPartitionKey\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t\tfor (const prop of this._entitySchema.properties ?? []) {\n\t\t\t\t\tif (prop.isPrimary || prop.isSecondary) {\n\t\t\t\t\t\tconditions.push({ property: prop.property, value: row[prop.property as string] });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\t\t\t\tqueries.push({\n\t\t\t\t\tquery: `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${sqlCondition}`,\n\t\t\t\t\tparams: conditionValues\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait connection.batch(queries, { prepare: true });\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(ScyllaDBTableConnector.CLASS_NAME, \"emptyFailed\", undefined, err);\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the entity.\n\t * @param id The id of the entity to remove.\n\t * @param conditions The optional conditions to match for the entities.\n\t */\n\tpublic async remove(\n\t\tid: string,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<void> {\n\t\tGuards.stringValue(ScyllaDBTableConnector.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\n\t\ttry {\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({ property: this._primaryKey?.property, value: id });\n\n\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\n\t\t\tconst sql = `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${sqlCondition}`;\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: ScyllaDBTableConnector.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\tawait this.execute(connection, sql, conditionValues);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"removeFailed\",\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 * Remove multiple entities.\n\t * @param ids The ids of the entities to remove.\n\t */\n\tpublic async removeBatch(ids: string[]): Promise<void> {\n\t\tGuards.arrayValue(ScyllaDBTableConnector.CLASS_NAME, nameof(ids), ids);\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\tconnection = await this.openConnection();\n\t\t\tconst queries: { query: string; params: unknown[] }[] = [];\n\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst conditions: { property: keyof T; value: unknown }[] = [\n\t\t\t\t\t{\n\t\t\t\t\t\tproperty: AbstractScyllaDBConnector.PARTITION_KEY as keyof T,\n\t\t\t\t\t\tvalue: partitionKey ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE\n\t\t\t\t\t},\n\t\t\t\t\t{ property: this._primaryKey.property, value: id }\n\t\t\t\t];\n\t\t\t\tconst { sqlCondition, conditionValues } = this.buildConditions(conditions);\n\t\t\t\tqueries.push({\n\t\t\t\t\tquery: `DELETE FROM \"${this.safeTableName(this._fullTableName)}\" WHERE ${sqlCondition}`,\n\t\t\t\t\tparams: conditionValues\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait connection.batch(queries, { prepare: true });\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"removeBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\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 * Teardown the entity storage by dropping the table.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the teardown process was successful.\n\t */\n\tpublic async teardown(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tawait nodeLogging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"tableDropping\",\n\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t});\n\n\t\tlet connection;\n\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\t\t\tawait connection.execute(`DROP TABLE IF EXISTS \"${this.safeTableName(this._fullTableName)}\"`);\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableDropped\",\n\t\t\t\tdata: { table: this.safeTableName(this._fullTableName) }\n\t\t\t});\n\n\t\t\t// Drop UDTs referenced by this schema so they are recreated with the\n\t\t\t// current schema on the next bootstrap (table must be gone first).\n\t\t\tconst structuredProperties = this._entitySchema.properties?.filter(\n\t\t\t\tproperty =>\n\t\t\t\t\t(property.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\tproperty.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\tIs.stringValue(property.itemTypeRef)\n\t\t\t);\n\t\t\tif (Is.array(structuredProperties)) {\n\t\t\t\tfor (const prop of structuredProperties) {\n\t\t\t\t\tif (Is.stringValue(prop.itemTypeRef)) {\n\t\t\t\t\t\tawait connection.execute(`DROP TYPE IF EXISTS \"${prop.itemTypeRef}\"`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: ScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"teardownFailed\",\n\t\t\t\terror: BaseError.fromError(err)\n\t\t\t});\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tawait this.closeConnection(connection);\n\t\t\tawait this.closePersistentClient();\n\t\t}\n\t}\n\n\t/**\n\t * Get all the distinct partition context ids from the storage.\n\t * @returns An array of context id objects, one per unique partition.\n\t */\n\tpublic async getPartitionContextIds(): Promise<IContextIds[]> {\n\t\tif (!Is.arrayValue(this._partitionContextIds)) {\n\t\t\treturn [];\n\t\t}\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await this.openConnection();\n\t\t\tconst result = await this.queryDB(\n\t\t\t\tconnection,\n\t\t\t\t`SELECT \"${AbstractScyllaDBConnector.PARTITION_KEY}\" FROM \"${this.safeTableName(this._fullTableName)}\" ALLOW FILTERING`,\n\t\t\t\t[],\n\t\t\t\tundefined,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst seen = new Set<string>();\n\t\t\tconst contextIds: IContextIds[] = [];\n\t\t\tfor (const row of result.rows) {\n\t\t\t\tconst id = row[AbstractScyllaDBConnector.PARTITION_KEY] as string;\n\t\t\t\tif (Is.stringValue(id) && !seen.has(id)) {\n\t\t\t\t\tseen.add(id);\n\t\t\t\t\tcontextIds.push(ContextIdHelper.shortSplit(this._partitionContextIds ?? [], id));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn contextIds;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\t\"getPartitionContextIdsFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\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 * Create a new target connector for the migration.\n\t * @param entitySchemaName The entity schema name to use for the target connector.\n\t * @returns A new connector configured with a migration table name.\n\t */\n\tpublic async createTargetConnector<U>(\n\t\tentitySchemaName: string\n\t): Promise<ScyllaDBTableConnector<U>> {\n\t\t// We create a new table for the migration with a unique name to avoid conflicts with the existing table\n\t\t// This table will be swapped with the existing table once the migration is finalized.\n\t\tconst migrationTableName = `${this._config.tableName}Migration${Date.now()}`;\n\n\t\treturn new ScyllaDBTableConnector<U>({\n\t\t\tentitySchema: entitySchemaName,\n\t\t\tconfig: {\n\t\t\t\t...this._config,\n\t\t\t\ttableName: migrationTableName\n\t\t\t},\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by pointing a new connector at the migration table.\n\t * @param targetConnector The connector pointing to the migration table.\n\t * @param options The optional migration options.\n\t * @param loggingComponentType The node logging component type.\n\t * @returns A connector pointing to the migration table (now the live table).\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: ScyllaDBTableConnector<U>,\n\t\toptions?: IMigrationOptions,\n\t\tloggingComponentType?: string\n\t): Promise<ScyllaDBTableConnector<U>> {\n\t\t// There is no rename operation in ScyllaDB, so we have to create a new table with the original name and copy the data over\n\n\t\t// Teardown the existing table with the original name to free up the name for the new table\n\t\tawait this.teardown(loggingComponentType);\n\n\t\tconst finalConnector = new ScyllaDBTableConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\n\t\tif (await finalConnector.bootstrap(loggingComponentType)) {\n\t\t\t// Since there is no rename, we need to copy the data from the migration table to the new table\n\t\t\tconst partitions = await targetConnector.getPartitionContextIds();\n\t\t\tconst batchSize = options?.batchSize ?? ScyllaDBTableConnector.DEFAULT_LIMIT;\n\t\t\tawait this.bulkCopy(targetConnector, finalConnector, partitions, batchSize);\n\n\t\t\tawait targetConnector.teardown(loggingComponentType);\n\t\t\treturn finalConnector;\n\t\t}\n\n\t\tthrow new GeneralError(\n\t\t\tScyllaDBTableConnector.CLASS_NAME,\n\t\t\t\"finalizeMigrationFailedBootstrap\",\n\t\t\tundefined\n\t\t);\n\t}\n\n\t/**\n\t * Clean up the migration by tearing down the migration table.\n\t * @param targetConnector The connector pointing to the migration table.\n\t * @param options The optional migration options.\n\t * @param loggingComponentType The node logging component type.\n\t */\n\tpublic async cleanupMigration<U>(\n\t\ttargetConnector?: ScyllaDBTableConnector<U>,\n\t\toptions?: IMigrationOptions,\n\t\tloggingComponentType?: string\n\t): Promise<void> {\n\t\t// If something failed the only thing to cleanup is the migration table\n\t\tawait targetConnector?.teardown?.(loggingComponentType);\n\t}\n\n\t/**\n\t * Copy all entities from sourceConnector to destConnector, paging through each partition.\n\t * @param sourceConnector The connector to read entities from.\n\t * @param destConnector The connector to write entities to.\n\t * @param partitions The partition list returned by getPartitionContextIds.\n\t * @param batchSize The number of entities to read per page.\n\t * @internal\n\t */\n\tprivate async bulkCopy<U>(\n\t\tsourceConnector: ScyllaDBTableConnector<U>,\n\t\tdestConnector: ScyllaDBTableConnector<U>,\n\t\tpartitions: IContextIds[],\n\t\tbatchSize: number\n\t): Promise<void> {\n\t\tlet partitionList: IContextIds[];\n\t\tif (Is.arrayValue(partitions)) {\n\t\t\tpartitionList = partitions;\n\t\t} else if (Is.arrayValue(sourceConnector._partitionContextIds)) {\n\t\t\tpartitionList = [];\n\t\t} else {\n\t\t\tpartitionList = [{}];\n\t\t}\n\n\t\tconst sourceColumns = [\n\t\t\tAbstractScyllaDBConnector.PARTITION_KEY,\n\t\t\t...(sourceConnector._entitySchema.properties?.map(p => p.property as string) ?? [])\n\t\t];\n\t\tconst insertSql = `INSERT INTO \"${destConnector.safeTableName(destConnector._fullTableName)}\" (${sourceColumns.map(c => `\"${c}\"`).join(\", \")}) VALUES (${sourceColumns.map(() => \"?\").join(\", \")})`;\n\n\t\tlet connection;\n\t\ttry {\n\t\t\tconnection = await sourceConnector.openConnection();\n\t\t\tfor (let i = 0; i < partitionList.length; i++) {\n\t\t\t\tconst partitionKey =\n\t\t\t\t\tContextIdHelper.combinedContextKey(\n\t\t\t\t\t\tpartitionList[i],\n\t\t\t\t\t\tsourceConnector._partitionContextIds\n\t\t\t\t\t) ?? AbstractScyllaDBConnector.PARTITION_KEY_VALUE;\n\n\t\t\t\tlet pageState: string | undefined;\n\t\t\t\tdo {\n\t\t\t\t\tconst result = await sourceConnector.queryDB(\n\t\t\t\t\t\tconnection,\n\t\t\t\t\t\t`SELECT * FROM \"${sourceConnector.safeTableName(sourceConnector._fullTableName)}\" WHERE \"${AbstractScyllaDBConnector.PARTITION_KEY}\" = ? ALLOW FILTERING`,\n\t\t\t\t\t\t[partitionKey],\n\t\t\t\t\t\tpageState,\n\t\t\t\t\t\tbatchSize\n\t\t\t\t\t);\n\n\t\t\t\t\tpageState = Is.stringValue(result.pageState) ? result.pageState : undefined;\n\n\t\t\t\t\tif (Is.arrayValue(result.rows)) {\n\t\t\t\t\t\tawait connection.batch(\n\t\t\t\t\t\t\tresult.rows.map((row: { [key: string]: unknown }) => ({\n\t\t\t\t\t\t\t\tquery: insertSql,\n\t\t\t\t\t\t\t\tparams: sourceColumns.map(col => row[col])\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t{ prepare: true }\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} while (Is.stringValue(pageState));\n\t\t\t}\n\t\t} finally {\n\t\t\tawait sourceConnector.closeConnection(connection);\n\t\t}\n\t}\n\n\t/**\n\t * Transform a logical description of a field into a DB field.\n\t * @param logicalField The logical field description.\n\t * @returns The DB type.\n\t * @throws GeneralException if no mapping found.\n\t * @internal\n\t */\n\tprivate toDbField(logicalField: IEntitySchemaProperty<T>): string {\n\t\tlet dbType: string;\n\n\t\tswitch (logicalField.type) {\n\t\t\tcase \"string\":\n\t\t\t\tdbType = \"TEXT\";\n\t\t\t\tswitch (logicalField.format) {\n\t\t\t\t\tcase \"uuid\":\n\t\t\t\t\t\tdbType = \"UUID\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"date\":\n\t\t\t\t\tcase \"date-time\":\n\t\t\t\t\t\tdbType = \"TIMESTAMP\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"number\":\n\t\t\t\tdbType = \"DOUBLE\";\n\t\t\t\tswitch (logicalField.format) {\n\t\t\t\t\tcase \"float\":\n\t\t\t\t\t\tdbType = \"FLOAT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"double\":\n\t\t\t\t\t\tdbType = \"DOUBLE\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"integer\":\n\t\t\t\tdbType = \"INT\";\n\t\t\t\tswitch (logicalField.format) {\n\t\t\t\t\tcase \"int8\":\n\t\t\t\t\tcase \"uint8\":\n\t\t\t\t\t\tdbType = \"TINYINT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"int16\":\n\t\t\t\t\tcase \"uint16\":\n\t\t\t\t\t\tdbType = \"SMALLINT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"int32\":\n\t\t\t\t\tcase \"uint32\":\n\t\t\t\t\t\tdbType = \"INT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"int64\":\n\t\t\t\t\tcase \"uint64\":\n\t\t\t\t\t\tdbType = \"BIGINT\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"boolean\":\n\t\t\t\tdbType = \"BOOLEAN\";\n\t\t\t\tbreak;\n\t\t\tcase \"object\":\n\t\t\t\tif (Is.stringValue(logicalField.itemTypeRef)) {\n\t\t\t\t\tdbType = `frozen<\"${logicalField.itemTypeRef}\">`;\n\t\t\t\t} else {\n\t\t\t\t\t// Item type is unknown object, store as TEXT\n\t\t\t\t\t// so that it can be JSON serialized\n\t\t\t\t\tdbType = \"TEXT\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"array\":\n\t\t\t\tif (Is.stringValue(logicalField.itemTypeRef)) {\n\t\t\t\t\tif (Is.stringValue(logicalField.itemType)) {\n\t\t\t\t\t\tdbType = `SET<${this.toDbField({\n\t\t\t\t\t\t\tproperty: logicalField.property,\n\t\t\t\t\t\t\ttype: logicalField.itemType\n\t\t\t\t\t\t})}>`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdbType = `SET<frozen<\"${logicalField.itemTypeRef}\">>`;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Item type is unknown object, store as TEXT\n\t\t\t\t\t// so that it can be JSON serialized\n\t\t\t\t\tdbType = \"TEXT\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn dbType;\n\t}\n\n\t/**\n\t * Build the CQL column definitions string for a CREATE TABLE statement.\n\t * @param schema The entity schema to build DDL from.\n\t * @returns The column definitions string (without the outer parentheses).\n\t * @internal\n\t */\n\tprivate buildSchemaColumns(schema: IEntitySchema<T>): string {\n\t\tconst fields: string[] = [];\n\t\tconst clusteringKeys: string[] = [];\n\n\t\t// partitionId is always the sole partition key so that WHERE \"partitionId\" = ?\n\t\t// allows ORDER BY on the subsequent clustering keys.\n\t\tfields.push(`\"${AbstractScyllaDBConnector.PARTITION_KEY}\" TEXT`);\n\n\t\tfor (const field of schema.properties ?? []) {\n\t\t\tfields.push(`\"${String(field.property)}\" ${this.toDbField(field)}`);\n\t\t\tif (field.isPrimary || field.isSecondary) {\n\t\t\t\tclusteringKeys.push(`\"${field.property as string}\"`);\n\t\t\t}\n\t\t}\n\n\t\tif (clusteringKeys.length > 0) {\n\t\t\tfields.push(\n\t\t\t\t`PRIMARY KEY (\"${AbstractScyllaDBConnector.PARTITION_KEY}\", ${clusteringKeys.join(\", \")})`\n\t\t\t);\n\t\t} else {\n\t\t\tfields.push(`PRIMARY KEY (\"${AbstractScyllaDBConnector.PARTITION_KEY}\")`);\n\t\t}\n\n\t\treturn fields.join(\", \");\n\t}\n}\n"]}
|
|
@@ -90,12 +90,12 @@ export declare class ScyllaDBTableConnector<T = unknown> extends AbstractScyllaD
|
|
|
90
90
|
* @param loggingComponentType The node logging component type.
|
|
91
91
|
* @returns A connector pointing to the migration table (now the live table).
|
|
92
92
|
*/
|
|
93
|
-
finalizeMigration<U>(targetConnector: ScyllaDBTableConnector<U>, options?: IMigrationOptions
|
|
93
|
+
finalizeMigration<U>(targetConnector: ScyllaDBTableConnector<U>, options?: IMigrationOptions, loggingComponentType?: string): Promise<ScyllaDBTableConnector<U>>;
|
|
94
94
|
/**
|
|
95
95
|
* Clean up the migration by tearing down the migration table.
|
|
96
96
|
* @param targetConnector The connector pointing to the migration table.
|
|
97
97
|
* @param options The optional migration options.
|
|
98
98
|
* @param loggingComponentType The node logging component type.
|
|
99
99
|
*/
|
|
100
|
-
cleanupMigration<U>(targetConnector?: ScyllaDBTableConnector<U>, options?: IMigrationOptions
|
|
100
|
+
cleanupMigration<U>(targetConnector?: ScyllaDBTableConnector<U>, options?: IMigrationOptions, loggingComponentType?: string): Promise<void>;
|
|
101
101
|
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.26](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-scylladb-v0.0.3-next.25...entity-storage-connector-scylladb-v0.0.3-next.26) (2026-06-11)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* remove default loggers ([7c8c7b1](https://github.com/iotaledger/twin-entity-storage/commit/7c8c7b132c23e95abd465c0ca3bad5ec8d95f91e))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/entity-storage-models bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @twin.org/entity-storage-connector-memory bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
18
|
+
|
|
19
|
+
## [0.0.3-next.25](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-scylladb-v0.0.3-next.24...entity-storage-connector-scylladb-v0.0.3-next.25) (2026-06-09)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* migration progress ([#121](https://github.com/iotaledger/twin-entity-storage/issues/121)) ([d032162](https://github.com/iotaledger/twin-entity-storage/commit/d032162768b6b7d4ccca7e39b80f8bc3ba46440e))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Dependencies
|
|
28
|
+
|
|
29
|
+
* The following workspace dependencies were updated
|
|
30
|
+
* dependencies
|
|
31
|
+
* @twin.org/entity-storage-models bumped from 0.0.3-next.24 to 0.0.3-next.25
|
|
32
|
+
* devDependencies
|
|
33
|
+
* @twin.org/entity-storage-connector-memory bumped from 0.0.3-next.24 to 0.0.3-next.25
|
|
34
|
+
|
|
3
35
|
## [0.0.3-next.24](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-scylladb-v0.0.3-next.23...entity-storage-connector-scylladb-v0.0.3-next.24) (2026-06-08)
|
|
4
36
|
|
|
5
37
|
|
|
@@ -527,7 +527,7 @@ The connector pointing to the migration table.
|
|
|
527
527
|
|
|
528
528
|
##### options?
|
|
529
529
|
|
|
530
|
-
`IMigrationOptions
|
|
530
|
+
`IMigrationOptions`
|
|
531
531
|
|
|
532
532
|
The optional migration options.
|
|
533
533
|
|
|
@@ -571,7 +571,7 @@ The connector pointing to the migration table.
|
|
|
571
571
|
|
|
572
572
|
##### options?
|
|
573
573
|
|
|
574
|
-
`IMigrationOptions
|
|
574
|
+
`IMigrationOptions`
|
|
575
575
|
|
|
576
576
|
The optional migration options.
|
|
577
577
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/entity-storage-connector-scylladb",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.26",
|
|
4
4
|
"description": "ScyllaDB connector for distributed, high-throughput persistence.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@twin.org/context": "next",
|
|
18
18
|
"@twin.org/core": "next",
|
|
19
19
|
"@twin.org/entity": "next",
|
|
20
|
-
"@twin.org/entity-storage-models": "0.0.3-next.
|
|
20
|
+
"@twin.org/entity-storage-models": "0.0.3-next.26",
|
|
21
21
|
"@twin.org/logging-models": "next",
|
|
22
22
|
"@twin.org/nameof": "next",
|
|
23
23
|
"cassandra-driver": "4.9.0"
|