@twin.org/entity-storage-connector-postgresql 0.10.1-next.5 → 0.10.1-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/postgreSqlEntityStorageConnector.js +461 -26
- package/dist/es/postgreSqlEntityStorageConnector.js.map +1 -1
- package/dist/types/postgreSqlEntityStorageConnector.d.ts +22 -1
- package/docs/changelog.md +32 -0
- package/docs/reference/classes/PostgreSqlEntityStorageConnector.md +50 -0
- package/locales/en.json +2 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgreSqlEntityStorageConnector.js","sourceRoot":"","sources":["../../src/postgreSqlEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHealthCategory,\n\tHealthStatus,\n\ttype IHealth,\n\ttype IHealthProviderComponent\n} from \"@twin.org/api-models\";\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tCoerce,\n\tComponentFactory,\n\tConflictError,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tMutex,\n\ttype IValidationFailure,\n\tObjectHelper,\n\tRandomHelper,\n\tValidation\n} from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\ttype EntityCondition,\n\tEntitySchemaFactory,\n\tEntitySchemaHelper,\n\tEntitySchemaPropertyType,\n\ttype IComparator,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty,\n\tLogicalOperator,\n\tSortDirection\n} from \"@twin.org/entity\";\nimport {\n\tConnectionHelper,\n\tEntityStorageHelper,\n\tIndexHelper,\n\tMigrationHelper,\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 postgres, { type ParameterOrJSON } from \"postgres\";\nimport type { IPostgreSqlEntityStorageConnectorConfig } from \"./models/IPostgreSqlEntityStorageConnectorConfig.js\";\nimport type { IPostgreSqlEntityStorageConnectorConstructorOptions } from \"./models/IPostgreSqlEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations using ql.\n */\nexport class PostgreSqlEntityStorageConnector<T = unknown>\n\timplements IEntityStorageMigrationConnector<T>, IHealthProviderComponent\n{\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<PostgreSqlEntityStorageConnector>();\n\n\t/**\n\t * Limit the number of entities when finding.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_LIMIT: number = 40;\n\n\t/**\n\t * Partition id field name.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY: string = \"partitionId\";\n\n\t/**\n\t * Partition id field value.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY_VALUE: string = \"root\";\n\n\t/**\n\t * Maximum length of the partition id column. The column leads the primary key and every\n\t * index, so it is bounded rather than stored as unconstrained text.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY_MAX_LENGTH: number = 255;\n\n\t/**\n\t * Maximum number of rows per INSERT statement in setBatch.\n\t * @internal\n\t */\n\tprivate static readonly _BATCH_CHUNK_SIZE: number = 1000;\n\n\t/**\n\t * PostgreSQL's maximum identifier length in characters; longer names are silently truncated.\n\t * @internal\n\t */\n\tprivate static readonly _MAX_IDENTIFIER_LENGTH: number = 63;\n\n\t/**\n\t * The largest length which can be expressed as VARCHAR(N), anything above this is stored as TEXT.\n\t * @internal\n\t */\n\tprivate static readonly _MAX_VARCHAR_LENGTH: number = 10485760;\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 * The schema for the entity.\n\t * @internal\n\t */\n\tprivate readonly _entitySchema: IEntitySchema<T>;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprivate readonly _partitionContextIds?: string[];\n\n\t/**\n\t * The primary key property.\n\t * @internal\n\t */\n\tprivate readonly _primaryKeyProperty: IEntitySchemaProperty<T>;\n\n\t/**\n\t * The name of the version property, if any.\n\t * @internal\n\t */\n\tprivate readonly _versionKey?: string;\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: IPostgreSqlEntityStorageConnectorConfig;\n\n\t/**\n\t * Milliseconds to wait for optimistic-lock mutexes before throwing.\n\t * @internal\n\t */\n\tprivate readonly _mutexTimeoutMs?: number;\n\n\t/**\n\t * Unique identifier for this connector instance, used to track references in SharedStore.\n\t * @internal\n\t */\n\tprivate readonly _instanceId: string;\n\n\t/**\n\t * Create a new instance of PostgreSqlEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IPostgreSqlEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<IPostgreSqlEntityStorageConnectorConfig>(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.host),\n\t\t\toptions.config.host\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.user),\n\t\t\toptions.config.user\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.password),\n\t\t\toptions.config.password\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.database),\n\t\t\toptions.config.database\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.tableName),\n\t\t\toptions.config.tableName\n\t\t);\n\n\t\tif (!Is.empty(options.config.pool?.connectTimeout)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.connectTimeout),\n\t\t\t\toptions.config.pool?.connectTimeout\n\t\t\t);\n\t\t}\n\n\t\tif (!Is.empty(options.config.pool?.idleTimeout)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.idleTimeout),\n\t\t\t\toptions.config.pool?.idleTimeout\n\t\t\t);\n\t\t}\n\n\t\tif (!Is.empty(options.config.pool?.max)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.max),\n\t\t\t\toptions.config.pool?.max\n\t\t\t);\n\t\t}\n\n\t\tif (!Is.empty(options.config.pool?.maxLifetime)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.maxLifetime),\n\t\t\t\toptions.config.pool?.maxLifetime\n\t\t\t);\n\t\t}\n\n\t\tthis._entitySchemaName = options.entitySchema;\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\t\tthis._primaryKeyProperty = EntitySchemaHelper.getPrimaryKey(this._entitySchema);\n\t\tthis._versionKey = EntitySchemaHelper.findVersionProperty(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._mutexTimeoutMs = Coerce.integer(options.config.mutexTimeoutMs);\n\t\tthis._instanceId = RandomHelper.generateUuidV7(\"compact\");\n\t}\n\n\t/**\n\t * Initialize the PostgreSql environment.\n\t * @param nodeLoggingComponentType Optional type of the logging component.\n\t * @returns A promise that resolves to a boolean indicating success.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tlet dbConnection: postgres.Sql;\n\t\ttry {\n\t\t\tconst adminClient = postgres(this.createConnectionConfig(false));\n\t\t\ttry {\n\t\t\t\tconst databaseExists = await this.databaseExists(adminClient);\n\t\t\t\tif (!databaseExists) {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"databaseCreating\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tawait adminClient.unsafe(`CREATE DATABASE \"${this._config.database}\";`);\n\t\t\t\t\tawait this.waitForDatabaseExists(adminClient);\n\t\t\t\t} else {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"databaseExists\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait adminClient.end();\n\t\t\t}\n\n\t\t\tdbConnection = await this.getClient();\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"databaseCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tconst tableExists = await this.tableExists();\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: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst createTableQuery = `CREATE TABLE \"${this._config.tableName}\" (${this.mapPostgreSqlProperties(this._entitySchema)})`;\n\t\t\t\tawait dbConnection.unsafe(createTableQuery);\n\t\t\t\tawait this.waitForTableExists();\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: PostgreSqlEntityStorageConnector.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\ttableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst indexes = await this.readIndexes(dbConnection);\n\n\t\t\tfor (const prop of this._entitySchema.properties ?? []) {\n\t\t\t\tif (\n\t\t\t\t\t(prop.isSecondary === true || !Is.empty(prop.sortDirection)) &&\n\t\t\t\t\tprop.type !== EntitySchemaPropertyType.Object &&\n\t\t\t\t\tprop.type !== EntitySchemaPropertyType.Array\n\t\t\t\t) {\n\t\t\t\t\tawait this.ensureIndex(dbConnection, indexes, prop, nodeLogging);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst indexGroups = EntitySchemaHelper.getIndexGroups(this._entitySchema);\n\t\t\tfor (const indexProperties of Object.values(indexGroups)) {\n\t\t\t\tawait this.ensureCompositeIndex(dbConnection, indexes, indexProperties);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\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 PostgreSqlEntityStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\ttry {\n\t\t\tconst sql = await this.getClient();\n\t\t\tawait sql`SELECT 1 FROM ${sql(this._config.tableName)} LIMIT 0`;\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { tableName: this._config.tableName }\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: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\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: { tableName: this._config.tableName }\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\t}\n\n\t/**\n\t * The component needs to be stopped when the node is closed.\n\t * @returns Nothing.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tawait ConnectionHelper.closeClient<postgres.Sql>(\n\t\t\t\"postgreSqlConnections\",\n\t\t\tthis.createClientId(),\n\t\t\tthis._instanceId,\n\t\t\tthis._mutexTimeoutMs,\n\t\t\tasync sql => sql.end()\n\t\t);\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 from PostgreSql.\n\t * @param id The id of the entity to get, or the index value if secondaryIndex is set.\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(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\n\t\t\tconst whereClauses: string[] = [];\n\t\t\tconst values: unknown[] = [];\n\n\t\t\twhereClauses.push(`\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $1`);\n\t\t\tvalues.push(partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE);\n\n\t\t\tif (secondaryIndex) {\n\t\t\t\twhereClauses.push(`\"${String(secondaryIndex)}\" = $2`);\n\t\t\t\tvalues.push(id);\n\t\t\t} else {\n\t\t\t\twhereClauses.push(`\"${this._primaryKeyProperty.property as string}\" = $2`);\n\t\t\t\tvalues.push(id);\n\t\t\t}\n\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfor (const condition of conditions) {\n\t\t\t\t\twhereClauses.push(`\"${String(condition.property)}\" = $${values.length + 1}`);\n\t\t\t\t\tvalues.push(condition.value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst query = `SELECT * FROM \"${this._config.tableName}\" WHERE ${whereClauses.join(\" AND \")} LIMIT 1`;\n\n\t\t\tconst rows = await dbConnection.unsafe(query, values as postgres.ParameterOrJSON<never>[]);\n\n\t\t\tif (Is.array(rows) && rows.length === 1) {\n\t\t\t\tif (this._entitySchema.properties) {\n\t\t\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\t\t\tconst row = rows[0] as unknown as { [key: string]: unknown };\n\t\t\t\t\t\tlet propColumn = prop.property as string;\n\t\t\t\t\t\tpropColumn = propColumn.toLowerCase();\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(prop.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\t\t\tprop.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\t\t\tIs.string(row[propColumn])\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tvalue = JSON.parse((rows[0] as { [key: string]: unknown })[propColumn] as string);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// If JSON.parse fails, keep the value as string\n\t\t\t\t\t\t\t\t// This handles cases where plain text was stored in Object/Array fields\n\t\t\t\t\t\t\t\tvalue = (rows[0] as { [key: string]: unknown })[propColumn];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete (rows[0] as { [key: string]: unknown })[propColumn];\n\t\t\t\t\t\t\t(rows[0] as { [key: string]: unknown })[prop.property as string] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (row[propColumn] === null) {\n\t\t\t\t\t\t\t(rows[0] as { [key: string]: unknown })[prop.property as string] = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn EntityStorageHelper.unPrepareEntity<T>(rows[0] as T, [\n\t\t\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY\n\t\t\t\t]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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\terr\n\t\t\t);\n\t\t}\n\t\treturn undefined;\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 * @returns The id of the entity.\n\t * @throws ConflictError when the entity exists but the supplied conditions or version do not match the stored state.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst submittedVersion = Is.stringValue(this._versionKey)\n\t\t\t? Coerce.integer(ObjectHelper.propertyGet(entity, this._versionKey))\n\t\t\t: undefined;\n\t\tconst hasVersionCheck =\n\t\t\t!Is.empty(this._versionKey) && !Is.empty(submittedVersion) && submittedVersion > 0;\n\n\t\tconst prepared = EntityStorageHelper.prepareEntity(\n\t\t\tentity,\n\t\t\tthis._entitySchema,\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\tvalue: partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t}\n\t\t\t],\n\t\t\t{ nullBehavior: \"nullify\" }\n\t\t);\n\n\t\tconst id = prepared[this._primaryKeyProperty.property] as unknown as string;\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tif (hasVersionCheck) {\n\t\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\t\tconst currentEntity = await this.get(id);\n\t\t\t\t\tif (!Is.empty(currentEntity) && !this.verifyConditions(conditions, currentEntity)) {\n\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\tid\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tObjectHelper.propertySet(prepared, this._versionKey, submittedVersion + 1);\n\t\t\t} else if (this._versionKey || Is.arrayValue(conditions)) {\n\t\t\t\tconst currentEntity = await this.get(id);\n\t\t\t\tif (!Is.empty(currentEntity)) {\n\t\t\t\t\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, currentEntity)) {\n\t\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\tconst storedVersion =\n\t\t\t\t\t\tCoerce.integer(\n\t\t\t\t\t\t\t!Is.empty(currentEntity)\n\t\t\t\t\t\t\t\t? ObjectHelper.propertyGet(currentEntity, this._versionKey)\n\t\t\t\t\t\t\t\t: 0\n\t\t\t\t\t\t) ?? 0;\n\t\t\t\t\tObjectHelper.propertySet(prepared, this._versionKey, storedVersion + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst props = [...(this._entitySchema.properties ?? [])];\n\t\t\tprops.unshift({\n\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY as keyof T,\n\t\t\t\ttype: EntitySchemaPropertyType.String\n\t\t\t});\n\n\t\t\tconst keys: string[] = [];\n\t\t\tconst values: unknown[] = [];\n\n\t\t\tfor (const prop of props) {\n\t\t\t\tkeys.push(prop.property as string);\n\t\t\t\tconst val = prepared[prop.property];\n\t\t\t\tvalues.push(val ?? null);\n\t\t\t}\n\n\t\t\tlet sql = `INSERT INTO \"${this._config.tableName}\"`;\n\t\t\tsql += ` (${keys.map(key => `\"${key}\"`).join(\", \")})`;\n\t\t\tsql += ` VALUES (${values.map((value, i) => `$${i + 1}`).join(\", \")})`;\n\t\t\tsql += ` ON CONFLICT (\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\", \"${this._primaryKeyProperty.property as string}\")`;\n\n\t\t\tif (hasVersionCheck) {\n\t\t\t\tsql += ` DO UPDATE SET ${keys.map(key => `\"${key}\" = EXCLUDED.\"${key}\"`).join(\", \")}`;\n\t\t\t\tsql += ` WHERE \"${this._config.tableName}\".\"${this._versionKey}\" = $${values.length + 1}`;\n\t\t\t\tvalues.push(submittedVersion);\n\t\t\t} else {\n\t\t\t\tsql += ` DO UPDATE SET ${keys.map(key => `\"${key}\" = EXCLUDED.\"${key}\"`).join(\", \")};`;\n\t\t\t}\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst result = await dbConnection.unsafe(sql, values as ParameterOrJSON<never>[]);\n\n\t\t\tif (hasVersionCheck && result.count === 0) {\n\t\t\t\tthrow new ConflictError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"optimisticLockFailed\",\n\t\t\t\t\tid\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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\terr\n\t\t\t);\n\t\t} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\n\t\t\t}\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(PostgreSqlEntityStorageConnector.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 preparedEntities = entities.map(entity =>\n\t\t\tEntityStorageHelper.prepareEntity(\n\t\t\t\tentity,\n\t\t\t\tthis._entitySchema,\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\tvalue: partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t{ nullBehavior: \"nullify\" }\n\t\t\t)\n\t\t);\n\n\t\ttry {\n\t\t\tconst props = [...(this._entitySchema.properties ?? [])];\n\t\t\tprops.unshift({\n\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY as keyof T,\n\t\t\t\ttype: EntitySchemaPropertyType.String\n\t\t\t});\n\t\t\tconst keys = props.map(p => p.property as string);\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst chunkSize = PostgreSqlEntityStorageConnector._BATCH_CHUNK_SIZE;\n\n\t\t\tfor (let offset = 0; offset < preparedEntities.length; offset += chunkSize) {\n\t\t\t\tconst chunk = preparedEntities.slice(offset, offset + chunkSize);\n\t\t\t\tconst allValues: unknown[] = [];\n\t\t\t\tconst rowPlaceholders: string[] = [];\n\n\t\t\t\tfor (const prepared of chunk) {\n\t\t\t\t\tconst rowValues: string[] = [];\n\t\t\t\t\tfor (const prop of props) {\n\t\t\t\t\t\tconst val = prepared[prop.property];\n\t\t\t\t\t\tallValues.push(Is.empty(val) ? null : val);\n\t\t\t\t\t\trowValues.push(`$${allValues.length}`);\n\t\t\t\t\t}\n\t\t\t\t\trowPlaceholders.push(`(${rowValues.join(\", \")})`);\n\t\t\t\t}\n\n\t\t\t\tlet sql = `INSERT INTO \"${this._config.tableName}\"`;\n\t\t\t\tsql += ` (${keys.map(key => `\"${key}\"`).join(\", \")})`;\n\t\t\t\tsql += ` VALUES ${rowPlaceholders.join(\", \")}`;\n\t\t\t\tsql += ` ON CONFLICT (\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\", \"${this._primaryKeyProperty.property as string}\")`;\n\t\t\t\tsql += ` DO UPDATE SET ${keys.map(key => `\"${key}\" = EXCLUDED.\"${key}\"`).join(\", \")};`;\n\n\t\t\t\tawait dbConnection.unsafe(sql, allValues as ParameterOrJSON<never>[]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"setBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Empty all the entities.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst sql = `DELETE FROM \"${this._config.tableName}\" WHERE \"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $1`;\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tawait dbConnection.unsafe(sql, [\n\t\t\t\tpartitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t]);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"emptyFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\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 * @returns Nothing.\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(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\n\t\t\tconst itemData = await this.get(id);\n\t\t\tif (!Is.empty(itemData)) {\n\t\t\t\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData)) {\n\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\tid\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst values: unknown[] = [];\n\t\t\t\tconst whereClauses: string[] = [];\n\n\t\t\t\twhereClauses.push(\n\t\t\t\t\t`\"${this._primaryKeyProperty.property as string}\" = $${values.length + 1}`\n\t\t\t\t);\n\t\t\t\tvalues.push(id);\n\n\t\t\t\twhereClauses.push(\n\t\t\t\t\t`\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $${values.length + 1}`\n\t\t\t\t);\n\t\t\t\tvalues.push(partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE);\n\n\t\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\t\twhereClauses.push(\n\t\t\t\t\t\t...conditions.map(condition => {\n\t\t\t\t\t\t\tvalues.push(condition.value);\n\t\t\t\t\t\t\treturn `\"${String(condition.property)}\" = $${values.length}`;\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst query = `DELETE FROM \"${this._config.tableName}\" WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t\tawait dbConnection.unsafe(query, values as postgres.ParameterOrJSON<never>[]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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\terr\n\t\t\t);\n\t\t} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove multiple entities by their primary key IDs.\n\t * @param ids The ids of the entities to remove.\n\t * @returns Nothing.\n\t */\n\tpublic async removeBatch(ids: string[]): Promise<void> {\n\t\tGuards.arrayValue(PostgreSqlEntityStorageConnector.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\ttry {\n\t\t\tconst sql = `DELETE FROM \"${this._config.tableName}\" WHERE \"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $1 AND \"${this._primaryKeyProperty.property as string}\" = ANY($2)`;\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tawait dbConnection.unsafe(sql, [\n\t\t\t\tpartitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\tids\n\t\t\t] as ParameterOrJSON<never>[]);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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}\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: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"tableDropping\",\n\t\t\tdata: { tableName: this._config.tableName }\n\t\t});\n\n\t\ttry {\n\t\t\tconst tableExists = await this.tableExists();\n\t\t\tif (tableExists) {\n\t\t\t\tconst dbConnection = await this.getClient();\n\t\t\t\tawait dbConnection.unsafe(`DROP TABLE \"${this._config.tableName}\";`);\n\t\t\t\tawait this.waitForTableNotExists();\n\t\t\t}\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableDropped\",\n\t\t\t\tdata: { tableName: this._config.tableName }\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: PostgreSqlEntityStorageConnector.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}\n\t}\n\n\t/**\n\t * Get the connector implementation version.\n\t * @returns The connector implementation version.\n\t */\n\tpublic connectorVersion(): number {\n\t\treturn 1;\n\t}\n\n\t/**\n\t * Get all the distinct partition context ids from the storage.\n\t * @param loggingComponentType The optional component type to use for logging skipped partition ids.\n\t * @returns An array of context id objects, one per unique partition.\n\t */\n\tpublic async getPartitionContextIds(\n\t\tloggingComponentType?: string\n\t): Promise<IContextIds[] | undefined> {\n\t\tif (!Is.arrayValue(this._partitionContextIds)) {\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst rows = await dbConnection.unsafe(\n\t\t\t\t`SELECT DISTINCT \"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" FROM \"${this._config.tableName}\"`\n\t\t\t);\n\t\t\tconst partitionIds = (rows as { [key: string]: string }[])\n\t\t\t\t.map(row => row[PostgreSqlEntityStorageConnector._PARTITION_KEY])\n\t\t\t\t.filter((id): id is string => Is.stringValue(id));\n\t\t\tconst contextIds: IContextIds[] = [];\n\t\t\tconst skipped: string[] = [];\n\t\t\tfor (const partitionId of partitionIds) {\n\t\t\t\tconst split = EntityStorageHelper.tryShortSplit(\n\t\t\t\t\tthis._partitionContextIds ?? [],\n\t\t\t\t\tpartitionId\n\t\t\t\t);\n\t\t\t\tif (Is.undefined(split)) {\n\t\t\t\t\tskipped.push(partitionId);\n\t\t\t\t} else {\n\t\t\t\t\tcontextIds.push(split);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Is.arrayValue(skipped)) {\n\t\t\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(loggingComponentType);\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"warn\",\n\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"partitionIdsSkipped\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\texpected: this._partitionContextIds?.length,\n\t\t\t\t\t\tpartitionIds: skipped.join(\", \")\n\t\t\t\t\t}\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\tPostgreSqlEntityStorageConnector.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}\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<PostgreSqlEntityStorageConnector<U>> {\n\t\treturn new PostgreSqlEntityStorageConnector<U>({\n\t\t\tentitySchema: entitySchemaName,\n\t\t\tconfig: {\n\t\t\t\t...this._config,\n\t\t\t\ttableName: MigrationHelper.generateTargetName(\n\t\t\t\t\tthis._config.tableName,\n\t\t\t\t\tPostgreSqlEntityStorageConnector._MAX_IDENTIFIER_LENGTH\n\t\t\t\t)\n\t\t\t},\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by renaming the migration table to the original table name.\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 final (renamed) table.\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: PostgreSqlEntityStorageConnector<U>,\n\t\toptions?: IMigrationOptions,\n\t\tloggingComponentType?: string\n\t): Promise<PostgreSqlEntityStorageConnector<U>> {\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 dbConnection = await targetConnector.getClient();\n\t\tawait dbConnection.unsafe(\n\t\t\t`ALTER TABLE \"${targetConnector._config.tableName}\" RENAME TO \"${this._config.tableName}\"`\n\t\t);\n\t\tconst finalConnector = new PostgreSqlEntityStorageConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t\tif (await finalConnector.bootstrap(loggingComponentType)) {\n\t\t\tawait targetConnector.stop();\n\t\t\treturn finalConnector;\n\t\t}\n\t\tthrow new GeneralError(\n\t\t\tPostgreSqlEntityStorageConnector.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?: PostgreSqlEntityStorageConnector<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 * 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?: { property: keyof T; sortDirection: SortDirection }[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ entities: Partial<T>[]; cursor?: string }> {\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\t\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\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\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"query\",\n\t\t\t\tvalidationFailures\n\t\t\t);\n\t\t}\n\n\t\tlet sql = \"\";\n\t\ttry {\n\t\t\tconst returnSize = limit ?? PostgreSqlEntityStorageConnector._DEFAULT_LIMIT;\n\n\t\t\tconst pkPropName = String(this._primaryKeyProperty.property);\n\n\t\t\tconst sortsByPK =\n\t\t\t\tIs.array(sortProperties) && sortProperties.some(s => String(s.property) === pkPropName);\n\n\t\t\tconst keySetCols: { prop: string; asc: boolean }[] = [];\n\t\t\tif (Is.array(sortProperties)) {\n\t\t\t\tfor (const s of sortProperties) {\n\t\t\t\t\tkeySetCols.push({\n\t\t\t\t\t\tprop: String(s.property),\n\t\t\t\t\t\tasc: s.sortDirection === SortDirection.Ascending\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!sortsByPK) {\n\t\t\t\tkeySetCols.push({ prop: pkPropName, asc: true });\n\t\t\t}\n\n\t\t\tconst requestedProps = properties ? new Set(properties.map(p => String(p))) : undefined;\n\t\t\tconst internallyAdded = new Set<string>();\n\n\t\t\tlet selectClause: string;\n\t\t\tif (requestedProps) {\n\t\t\t\tconst selectSet = new Set(requestedProps);\n\t\t\t\tfor (const col of keySetCols) {\n\t\t\t\t\tif (!selectSet.has(col.prop)) {\n\t\t\t\t\t\tselectSet.add(col.prop);\n\t\t\t\t\t\tinternallyAdded.add(col.prop);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tselectClause = [...selectSet].map(p => `\"${p}\"`).join(\", \");\n\t\t\t} else {\n\t\t\t\tselectClause = \"*\";\n\t\t\t}\n\n\t\t\tconst orderByClause = `ORDER BY ${keySetCols.map(c => `\"${c.prop}\" ${c.asc ? \"ASC\" : \"DESC\"}`).join(\", \")}`;\n\n\t\t\tconst { whereClauses, values } = this.buildWhereClause(conditions, partitionKey);\n\n\t\t\tif (Is.stringBase64(cursor)) {\n\t\t\t\tconst parsedCursor = ObjectHelper.fromBytes<{ i: string; sv?: unknown[] }>(\n\t\t\t\t\tConverter.base64ToBytes(cursor)\n\t\t\t\t);\n\t\t\t\tconst lastValues: unknown[] = [...(parsedCursor.sv ?? []), parsedCursor.i];\n\t\t\t\tconst orParts: string[] = [];\n\t\t\t\tfor (let i = 0; i < keySetCols.length; i++) {\n\t\t\t\t\tconst parts: string[] = [];\n\t\t\t\t\tfor (let j = 0; j < i; j++) {\n\t\t\t\t\t\tvalues.push(lastValues[j] as ParameterOrJSON<never>);\n\t\t\t\t\t\tparts.push(`\"${keySetCols[j].prop}\" = $${values.length}`);\n\t\t\t\t\t}\n\t\t\t\t\tconst op = keySetCols[i].asc ? \">\" : \"<\";\n\t\t\t\t\tvalues.push(lastValues[i] as ParameterOrJSON<never>);\n\t\t\t\t\tparts.push(`\"${keySetCols[i].prop}\" ${op} $${values.length}`);\n\t\t\t\t\torParts.push(parts.length === 1 ? parts[0] : `(${parts.join(\" AND \")})`);\n\t\t\t\t}\n\t\t\t\twhereClauses.push(`(${orParts.join(\" OR \")})`);\n\t\t\t}\n\n\t\t\tsql = `SELECT ${selectClause} FROM \"${this._config.tableName}\"`;\n\t\t\tif (whereClauses.length > 0) {\n\t\t\t\tsql += ` WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t}\n\t\t\tsql += ` ${orderByClause} LIMIT ${returnSize + 1}`;\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst rows = await dbConnection.unsafe(sql, values);\n\n\t\t\tif (this._entitySchema.properties) {\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\t\t\tlet propColumn = prop.property as string;\n\t\t\t\t\t\tpropColumn = propColumn.toLowerCase();\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(prop.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\t\t\tprop.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\t\t\tIs.string(row[propColumn])\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tvalue = JSON.parse(row[propColumn] as string);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// If JSON.parse fails, keep the value as string\n\t\t\t\t\t\t\t\t// This handles cases where plain text was stored in Object/Array fields\n\t\t\t\t\t\t\t\tvalue = row[propColumn];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete row[propColumn];\n\t\t\t\t\t\t\trow[prop.property as string] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (row[propColumn] === null) {\n\t\t\t\t\t\t\trow[prop.property as string] = undefined;\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 hasMore = Is.array(rows) && rows.length > returnSize;\n\t\t\tconst resultRows = hasMore ? rows.slice(0, returnSize) : rows;\n\t\t\tconst entities = resultRows as unknown as Partial<T>[];\n\n\t\t\tlet nextCursor: string | undefined;\n\t\t\tif (hasMore && entities.length > 0) {\n\t\t\t\tconst lastRow = entities[entities.length - 1];\n\t\t\t\tconst sortValues = keySetCols\n\t\t\t\t\t.slice(0, -1)\n\t\t\t\t\t.map(c => ObjectHelper.propertyGet(lastRow, c.prop));\n\t\t\t\tconst lastId = ObjectHelper.propertyGet<string>(lastRow, pkPropName);\n\t\t\t\tif (Is.stringValue(lastId)) {\n\t\t\t\t\tconst cursorData: { i: string; sv?: unknown[] } =\n\t\t\t\t\t\tsortValues.length > 0 ? { i: lastId, sv: sortValues } : { i: lastId };\n\t\t\t\t\tnextCursor = Converter.bytesToBase64(ObjectHelper.toBytes(cursorData));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < entities.length; i++) {\n\t\t\t\tentities[i] = EntityStorageHelper.unPrepareEntity(entities[i], [\n\t\t\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY\n\t\t\t\t]);\n\t\t\t\tfor (const col of internallyAdded) {\n\t\t\t\t\tObjectHelper.propertyDelete(entities[i], col);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { entities, cursor: nextCursor };\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryFailed\",\n\t\t\t\t{ sql },\n\t\t\t\terr\n\t\t\t);\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\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\n\n\t\tlet queryStr: string | undefined;\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\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 { whereClauses, values } = this.buildWhereClause(conditions, partitionKey);\n\n\t\t\tqueryStr = `SELECT COUNT(*) AS count FROM \"${this._config.tableName}\"`;\n\t\t\tif (whereClauses.length > 0) {\n\t\t\t\tqueryStr += ` WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t}\n\n\t\t\tconst result = await dbConnection.unsafe(queryStr, values);\n\t\t\treturn Number(result[0].count);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"countFailed\",\n\t\t\t\t{ sql: queryStr },\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Check if the database exists.\n\t * @param adminClient The server-level connection to use for the check.\n\t * @returns True if the database exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async databaseExists(adminClient: postgres.Sql): Promise<boolean> {\n\t\ttry {\n\t\t\tconst res = await adminClient.unsafe(\n\t\t\t\t\"SELECT datname FROM pg_catalog.pg_database WHERE datname = $1\",\n\t\t\t\t[this._config.database] as postgres.ParameterOrJSON<never>[]\n\t\t\t);\n\t\t\treturn res.length > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a database to exist.\n\t * @param adminClient The server-level connection to use for the check.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForDatabaseExists(adminClient: postgres.Sql): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst databaseExists = await this.databaseExists(adminClient);\n\t\t\tif (databaseExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Ensure the secondary index for a property exists, dropping a legacy-named index if present.\n\t * Every query is scoped to a single partition, so the index leads with the partition key and\n\t * the property follows it, letting one index serve both the partition filter and the sort.\n\t * @param dbConnection The connection to query with.\n\t * @param indexes The indexes already on the table, keyed by index name.\n\t * @param prop The indexed property.\n\t * @param nodeLogging Optional logging component.\n\t * @internal\n\t */\n\tprivate async ensureIndex(\n\t\tdbConnection: postgres.Sql,\n\t\tindexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } },\n\t\tprop: IEntitySchemaProperty<T>,\n\t\tnodeLogging?: ILoggingComponent\n\t): Promise<void> {\n\t\tconst columnName = String(prop.property);\n\t\tconst indexName = IndexHelper.generateName(this._config.tableName, columnName);\n\t\tconst keyColumns = [PostgreSqlEntityStorageConnector._PARTITION_KEY, columnName];\n\n\t\tif (!this.isIndexCovered(indexes, keyColumns)) {\n\t\t\t// An index of ours under the same name but with a different shape predates the partition\n\t\t\t// key leading the key columns, so it has to be replaced rather than left in place.\n\t\t\tif (!Is.empty(indexes[indexName])) {\n\t\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${indexName}\"`);\n\t\t\t}\n\n\t\t\tawait dbConnection.unsafe(\n\t\t\t\t`CREATE INDEX IF NOT EXISTS \"${indexName}\" ON \"${this._config.tableName}\" (\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\", \"${columnName}\")`\n\t\t\t);\n\t\t}\n\n\t\t// TODO: remove the legacy index handling once every installation has bootstrapped on a release that contains it\n\t\tconst legacyName = IndexHelper.generateLegacyName(\n\t\t\tthis._config.tableName,\n\t\t\tcolumnName,\n\t\t\tIndexHelper.DEFAULT_MAX_IDENTIFIER_LENGTH\n\t\t);\n\t\tconst legacyIndex = indexes[legacyName];\n\n\t\t// The connector's own legacy indexes were always non-unique and single-column, anything else is an operator's\n\t\tif (!Is.empty(legacyIndex) && legacyIndex.nonUnique && legacyIndex.columns.length === 1) {\n\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${legacyName}\"`);\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"legacyIndexDropped\",\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName,\n\t\t\t\t\tindexName: legacyName,\n\t\t\t\t\tnewIndexName: indexName\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Ensure the composite index for a schema index group exists.\n\t * A group needs at least two properties to form a composite index, otherwise it is skipped.\n\t * The partition key leads the index for the same reason it leads a single property index.\n\t * @param dbConnection The connection to query with.\n\t * @param indexes The indexes already on the table, keyed by index name.\n\t * @param indexProperties The properties in the group, ordered by their index position.\n\t * @internal\n\t */\n\tprivate async ensureCompositeIndex(\n\t\tdbConnection: postgres.Sql,\n\t\tindexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } },\n\t\tindexProperties: { property: IEntitySchemaProperty<T>; direction: SortDirection }[]\n\t): Promise<void> {\n\t\tconst indexName = IndexHelper.generateCompositeName(this._config.tableName, indexProperties);\n\t\tconst keyColumns = [\n\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t...indexProperties.map(indexProperty => String(indexProperty.property.property))\n\t\t];\n\n\t\tif (this.isIndexCovered(indexes, keyColumns)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// An index of ours under the same name but with a different shape predates the partition\n\t\t// key leading the key columns, so it has to be replaced rather than left in place.\n\t\tif (!Is.empty(indexes[indexName])) {\n\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${indexName}\"`);\n\t\t}\n\n\t\tconst indexCols = [\n\t\t\t`\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" ASC`,\n\t\t\t...indexProperties.map(\n\t\t\t\tindexProperty =>\n\t\t\t\t\t`\"${String(indexProperty.property.property)}\" ${indexProperty.direction === SortDirection.Descending ? \"DESC\" : \"ASC\"}`\n\t\t\t)\n\t\t].join(\", \");\n\n\t\tawait dbConnection.unsafe(\n\t\t\t`CREATE INDEX IF NOT EXISTS \"${indexName}\" ON \"${this._config.tableName}\" (${indexCols})`\n\t\t);\n\t}\n\n\t/**\n\t * Read the key columns of every usable index on the table, in key order.\n\t * @param dbConnection The connection to query with.\n\t * @returns The key columns and uniqueness of each index, keyed by index name.\n\t * @internal\n\t */\n\tprivate async readIndexes(\n\t\tdbConnection: postgres.Sql\n\t): Promise<{ [indexName: string]: { columns: string[]; nonUnique: boolean } }> {\n\t\tconst indexRows = await dbConnection.unsafe(\n\t\t\t`SELECT i.relname AS \"indexName\", a.attname AS \"columnName\", k.pos AS \"position\", ix.indisunique AS \"isUnique\"\n\t\t\tFROM pg_index ix\n\t\t\tJOIN pg_class t ON t.oid = ix.indrelid\n\t\t\tJOIN pg_namespace n ON n.oid = t.relnamespace\n\t\t\tJOIN pg_class i ON i.oid = ix.indexrelid\n\t\t\tJOIN pg_am am ON am.oid = i.relam\n\t\t\tJOIN LATERAL generate_series(0, ix.indnkeyatts - 1) AS k(pos) ON true\n\t\t\tJOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ix.indkey[k.pos]\n\t\t\tWHERE n.nspname = 'public'\n\t\t\t\tAND t.relname = $1\n\t\t\t\tAND ix.indisvalid\n\t\t\t\tAND ix.indisready\n\t\t\t\tAND ix.indpred IS NULL\n\t\t\t\tAND am.amname = 'btree'\n\t\t\tORDER BY i.relname, k.pos`,\n\t\t\t[this._config.tableName] as ParameterOrJSON<never>[]\n\t\t);\n\n\t\tconst indexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } } = {};\n\n\t\tfor (const row of indexRows) {\n\t\t\tconst indexName = ObjectHelper.propertyGet<string>(row, \"indexName\");\n\t\t\tconst columnName = ObjectHelper.propertyGet<string>(row, \"columnName\");\n\t\t\tconst position = Coerce.integer(ObjectHelper.propertyGet(row, \"position\"));\n\n\t\t\tif (Is.stringValue(indexName) && Is.stringValue(columnName) && Is.integer(position)) {\n\t\t\t\tindexes[indexName] ??= {\n\t\t\t\t\tcolumns: [],\n\t\t\t\t\tnonUnique: ObjectHelper.propertyGet(row, \"isUnique\") === false\n\t\t\t\t};\n\t\t\t\t// An expression key has no column to join to, leaving a hole which stops the\n\t\t\t\t// index from matching any key column list beyond that position.\n\t\t\t\tindexes[indexName].columns[position] = columnName;\n\t\t\t}\n\t\t}\n\n\t\treturn indexes;\n\t}\n\n\t/**\n\t * Check if any of the indexes already starts with the given key columns.\n\t * @param indexes The indexes on the table, keyed by index name.\n\t * @param keyColumns The leading key columns the index must have, in order.\n\t * @returns True if an index already leads with the key columns.\n\t * @internal\n\t */\n\tprivate isIndexCovered(\n\t\tindexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } },\n\t\tkeyColumns: string[]\n\t): boolean {\n\t\treturn Object.values(indexes).some(index =>\n\t\t\tkeyColumns.every((keyColumn, position) => index.columns[position] === keyColumn)\n\t\t);\n\t}\n\n\t/**\n\t * Check if the table exists.\n\t * @returns True if the table exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async tableExists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst res = await dbConnection.unsafe(\n\t\t\t\t\"SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1 LIMIT 1\",\n\t\t\t\t[this._config.tableName] as postgres.ParameterOrJSON<never>[]\n\t\t\t);\n\t\t\treturn res.length > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a table to exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForTableExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst tableExists = await this.tableExists();\n\t\t\tif (tableExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a table to not exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForTableNotExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst tableExists = await this.tableExists();\n\t\t\tif (!tableExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Retrieve (or lazily create) the shared postgres connection for this endpoint and database.\n\t * @returns The shared connection.\n\t * @internal\n\t */\n\tprivate async getClient(): Promise<postgres.Sql> {\n\t\treturn ConnectionHelper.openClient<postgres.Sql>(\n\t\t\t\"postgreSqlConnections\",\n\t\t\tthis.createClientId(),\n\t\t\tthis._instanceId,\n\t\t\tthis._mutexTimeoutMs,\n\t\t\tasync () => postgres(this.createConnectionConfig())\n\t\t);\n\t}\n\n\t/**\n\t * Build a stable cache key for the shared client based on connection parameters.\n\t * @returns The cache key.\n\t * @internal\n\t */\n\tprivate createClientId(): string {\n\t\treturn `${this._config.host}|${this._config.port ?? 5432}|${this._config.user}|${this._config.database}`;\n\t}\n\n\t/**\n\t * Create a new DB connection configuration.\n\t * @param includeDatabase Whether to include the database name in the options.\n\t * @returns The PostgreSql connection configuration.\n\t * @internal\n\t */\n\tprivate createConnectionConfig(\n\t\tincludeDatabase: boolean = true\n\t): postgres.Options<{ [key: string]: postgres.PostgresType }> {\n\t\tconst opts: { [key: string]: unknown } = {\n\t\t\thost: this._config.host,\n\t\t\tport: this._config.port ?? 5432,\n\t\t\tuser: this._config.user,\n\t\t\tpassword: this._config.password,\n\t\t\tmax: this._config?.pool?.max,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tidle_timeout: this._config?.pool?.idleTimeout,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tconnect_timeout: this._config?.pool?.connectTimeout,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tmax_lifetime: this._config?.pool?.maxLifetime,\n\t\t\t// The driver returns BIGINT (int64/uint64 properties) as a string, the schema expects a number.\n\t\t\ttypes: {\n\t\t\t\tbigint: {\n\t\t\t\t\tto: 20,\n\t\t\t\t\tfrom: [20],\n\t\t\t\t\tserialize: (value: number | bigint): string => value.toString(),\n\t\t\t\t\tparse: (value: string): number => Number(value)\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tif (includeDatabase) {\n\t\t\topts.database = this._config.database;\n\t\t}\n\t\treturn opts;\n\t}\n\n\t/**\n\t * Build where clause arrays for a query, combining partition key and optional conditions.\n\t * @param conditions The optional entity conditions to include.\n\t * @param partitionKey The partition key value.\n\t * @returns The where clauses and bound values.\n\t * @internal\n\t */\n\tprivate buildWhereClause(\n\t\tconditions: EntityCondition<T> | undefined,\n\t\tpartitionKey: string | undefined\n\t): { whereClauses: string[]; values: ParameterOrJSON<never>[] } {\n\t\tconst whereClauses: string[] = [];\n\t\tconst values: ParameterOrJSON<never>[] = [];\n\n\t\tconst finalConditions: EntityCondition<T> = {\n\t\t\tconditions: [],\n\t\t\tlogicalOperator: LogicalOperator.And\n\t\t};\n\n\t\tfinalConditions.conditions.push({\n\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\tvalue: partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t});\n\n\t\tif (!Is.empty(conditions)) {\n\t\t\tfinalConditions.conditions.push(conditions);\n\t\t}\n\n\t\tthis.buildQueryParameters(\"\", finalConditions, whereClauses, values, 1);\n\n\t\treturn { whereClauses, values };\n\t}\n\n\t/**\n\t * Create an SQL condition clause.\n\t * @param objectPath The path for the nested object.\n\t * @param condition The conditions to create the query from.\n\t * @param whereClauses The where clauses to use in the query.\n\t * @param values The values to use in the query.\n\t * @param valueIndex The current value index.\n\t * @internal\n\t */\n\tprivate buildQueryParameters(\n\t\tobjectPath: string,\n\t\tcondition: EntityCondition<T> | undefined,\n\t\twhereClauses: string[],\n\t\tvalues: unknown[],\n\t\tvalueIndex: number\n\t): void {\n\t\tif (Is.undefined(condition)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\tif (condition.conditions.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst joinConditions: string[] = condition.conditions.map(c => {\n\t\t\t\tconst subWhereClauses: string[] = [];\n\t\t\t\tconst subValues: unknown[] = [];\n\t\t\t\tthis.buildQueryParameters(objectPath, c, subWhereClauses, subValues, valueIndex);\n\t\t\t\tvalues.push(...subValues);\n\t\t\t\tvalueIndex += subValues.length;\n\t\t\t\treturn subWhereClauses.join(\" AND \");\n\t\t\t});\n\n\t\t\tconst logicalOperator = this.mapConditionalOperator(condition.logicalOperator);\n\t\t\tconst queryClause = joinConditions.filter(j => j.length > 0).join(` ${logicalOperator} `);\n\n\t\t\tif (queryClause.length > 0) {\n\t\t\t\twhereClauses.push(`(${queryClause})`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst schemaProp = this._entitySchema.properties?.find(p => p.property === condition.property);\n\t\tconst comparison = this.mapComparisonOperator(\n\t\t\tobjectPath,\n\t\t\tcondition,\n\t\t\tschemaProp?.type,\n\t\t\tvalues,\n\t\t\tvalueIndex\n\t\t);\n\t\twhereClauses.push(comparison);\n\t}\n\n\t/**\n\t * Map the framework comparison operators to those in MySQL.\n\t * @param objectPath The prefix to use for the condition.\n\t * @param comparator The operator to map.\n\t * @param type The type of the property.\n\t * @param values The values to use in the query.\n\t * @param valueIndex The current value index.\n\t * @returns The comparison expression.\n\t * @throws GeneralError if the comparison operator is not supported.\n\t * @internal\n\t */\n\tprivate mapComparisonOperator(\n\t\tobjectPath: string,\n\t\tcomparator: IComparator,\n\t\ttype: EntitySchemaPropertyType | undefined,\n\t\tvalues: unknown[],\n\t\tvalueIndex: number\n\t): string {\n\t\tlet prop = objectPath;\n\t\tif (prop.length > 0) {\n\t\t\tprop += \".\";\n\t\t}\n\n\t\tprop += comparator.property;\n\n\t\tif (comparator.comparison === ComparisonOperator.In) {\n\t\t\tconst inValues = Is.array(comparator.value) ? comparator.value : [comparator.value];\n\t\t\tif (inValues.length === 0) {\n\t\t\t\t// PostgreSQL rejects `IN ()` as a syntax error - short-circuit to a condition\n\t\t\t\t// that is always false so the query returns zero rows cleanly (#141).\n\t\t\t\treturn \"1 = 0\";\n\t\t\t}\n\t\t\tvalues.push(...inValues.map(val => this.propertyToDbValue(val, type)));\n\t\t\tconst placeholders = inValues.map((value, index) => `$${valueIndex + index}`).join(\", \");\n\t\t\treturn `\"${prop}\" IN (${placeholders})`;\n\t\t}\n\n\t\t// null/undefined must use IS NULL / IS NOT NULL - never a parameterised placeholder.\n\t\t// Passing undefined through propertyToDbValue() coerces it to NaN for number fields\n\t\t// (Number(undefined) === NaN), and null coerces to 0 (Number(null) === 0), both of\n\t\t// which produce semantically wrong or invalid SQL.\n\t\tif (comparator.value === null || comparator.value === undefined) {\n\t\t\tif (\n\t\t\t\tcomparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals\n\t\t\t) {\n\t\t\t\tconst nullCheck =\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.Equals ? \"IS NULL\" : \"IS NOT NULL\";\n\n\t\t\t\tif (comparator.property.split(\".\").length > 1) {\n\t\t\t\t\tconst rootProp = comparator.property.split(\".\")[0];\n\t\t\t\t\tconst nestedParts = comparator.property.split(\".\").slice(1);\n\t\t\t\t\tconst jsonPath = nestedParts\n\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->> '${p}'` : `-> '${p}'`))\n\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\tconst jsonTextExpr = `(\"${rootProp}\"::jsonb ${jsonPath})`;\n\t\t\t\t\treturn `${jsonTextExpr} ${nullCheck}`;\n\t\t\t\t}\n\t\t\t\treturn `\"${prop}\" ${nullCheck}`;\n\t\t\t}\n\t\t}\n\n\t\tconst dbValue = this.propertyToDbValue(comparator.value, type);\n\t\tvalues.push(dbValue);\n\n\t\tif (comparator.property.split(\".\").length > 1) {\n\t\t\tconst rootProp = comparator.property.split(\".\")[0];\n\t\t\tconst nestedParts = comparator.property.split(\".\").slice(1);\n\t\t\tconst rootSchema = this._entitySchema.properties?.find(p => p.property === rootProp);\n\t\t\tconst isArray = rootSchema?.type === EntitySchemaPropertyType.Array;\n\t\t\tconst jsonPath = nestedParts\n\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->> '${p}'` : `-> '${p}'`))\n\t\t\t\t.join(\"\");\n\t\t\tconst jsonTextExpr = `(\"${rootProp}\"::jsonb ${jsonPath})`;\n\n\t\t\tswitch (comparator.comparison) {\n\t\t\t\tcase ComparisonOperator.Includes: {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`%${String(comparator.value)}%`);\n\t\t\t\t\tif (isArray) {\n\t\t\t\t\t\tconst elemPath = nestedParts\n\t\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->>'${p}'` : `->'${p}'`))\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\t\treturn `EXISTS (SELECT 1 FROM jsonb_array_elements(\"${rootProp}\") elem WHERE elem${elemPath} LIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `${jsonTextExpr} LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tcase ComparisonOperator.NotIncludes: {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`%${String(comparator.value)}%`);\n\t\t\t\t\tif (isArray) {\n\t\t\t\t\t\tconst elemPath = nestedParts\n\t\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->>'${p}'` : `->'${p}'`))\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\t\treturn `NOT EXISTS (SELECT 1 FROM jsonb_array_elements(\"${rootProp}\") elem WHERE elem${elemPath} LIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `${jsonTextExpr} NOT LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tcase ComparisonOperator.StartsWith: {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`${this.escapeLike(String(comparator.value))}%`);\n\t\t\t\t\tif (isArray) {\n\t\t\t\t\t\tconst elemPath = nestedParts\n\t\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->>'${p}'` : `->'${p}'`))\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\t\treturn `EXISTS (SELECT 1 FROM jsonb_array_elements(\"${rootProp}\") elem WHERE elem${elemPath} LIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `${jsonTextExpr} LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tcase ComparisonOperator.NotEquals:\n\t\t\t\t\treturn `${jsonTextExpr} <> $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.GreaterThan:\n\t\t\t\t\treturn `${jsonTextExpr} > $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.LessThan:\n\t\t\t\t\treturn `${jsonTextExpr} < $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.GreaterThanOrEqual:\n\t\t\t\t\treturn `${jsonTextExpr} >= $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.LessThanOrEqual:\n\t\t\t\t\treturn `${jsonTextExpr} <= $${valueIndex}`;\n\t\t\t\tdefault:\n\t\t\t\t\treturn `${jsonTextExpr} = $${valueIndex}`;\n\t\t\t}\n\t\t}\n\n\t\tswitch (comparator.comparison) {\n\t\t\tcase ComparisonOperator.Equals:\n\t\t\t\tif (Is.object(comparator.value) || Is.array(comparator.value)) {\n\t\t\t\t\treturn `\"${prop}\" = $${valueIndex}::jsonb`;\n\t\t\t\t}\n\t\t\t\treturn `\"${prop}\" = $${valueIndex}`;\n\t\t\tcase ComparisonOperator.NotEquals:\n\t\t\t\tif (Is.object(comparator.value) || Is.array(comparator.value)) {\n\t\t\t\t\treturn `\"${prop}\" != $${valueIndex}::jsonb`;\n\t\t\t\t}\n\t\t\t\treturn `\"${prop}\" <> $${valueIndex}`;\n\t\t\tcase ComparisonOperator.GreaterThan:\n\t\t\t\treturn `\"${prop}\" > $${valueIndex}`;\n\t\t\tcase ComparisonOperator.LessThan:\n\t\t\t\treturn `\"${prop}\" < $${valueIndex}`;\n\t\t\tcase ComparisonOperator.GreaterThanOrEqual:\n\t\t\t\treturn `\"${prop}\" >= $${valueIndex}`;\n\t\t\tcase ComparisonOperator.LessThanOrEqual:\n\t\t\t\treturn `\"${prop}\" <= $${valueIndex}`;\n\t\t\tcase ComparisonOperator.Includes: {\n\t\t\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\t\t\treturn `\"${prop}\" LIKE '%' || $${valueIndex} || '%'`;\n\t\t\t\t}\n\t\t\t\tif (type === EntitySchemaPropertyType.Array || type === EntitySchemaPropertyType.Object) {\n\t\t\t\t\treturn `EXISTS (SELECT 1 FROM jsonb_array_elements(\"${prop}\") elem WHERE elem @> $${valueIndex}::jsonb)`;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase ComparisonOperator.NotIncludes: {\n\t\t\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\t\t\treturn `\"${prop}\" NOT LIKE '%' || $${valueIndex} || '%'`;\n\t\t\t\t}\n\t\t\t\tif (type === EntitySchemaPropertyType.Array || type === EntitySchemaPropertyType.Object) {\n\t\t\t\t\treturn `NOT EXISTS (SELECT 1 FROM jsonb_array_elements(\"${prop}\") elem WHERE elem @> $${valueIndex}::jsonb)`;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase ComparisonOperator.StartsWith: {\n\t\t\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`${this.escapeLike(String(comparator.value))}%`);\n\t\t\t\t\treturn `\"${prop}\" LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Escape the LIKE wildcard characters in a value so they match literally.\n\t * @param value The value to escape.\n\t * @returns The escaped value.\n\t * @internal\n\t */\n\tprivate escapeLike(value: string): string {\n\t\treturn value.replace(/[\\\\%_]/g, \"\\\\$&\");\n\t}\n\n\t/**\n\t * Format a value to insert into DB.\n\t * @param value The value to format.\n\t * @param type The type for the property.\n\t * @returns The value after conversion.\n\t * @internal\n\t */\n\tprivate propertyToDbValue(value: unknown, type?: EntitySchemaPropertyType): unknown {\n\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\treturn String(value);\n\t\t} else if (type === EntitySchemaPropertyType.Number) {\n\t\t\treturn Number(value);\n\t\t} else if (type === EntitySchemaPropertyType.Boolean) {\n\t\t\treturn Boolean(value);\n\t\t} else if (\n\t\t\ttype === EntitySchemaPropertyType.Object ||\n\t\t\ttype === EntitySchemaPropertyType.Array\n\t\t) {\n\t\t\treturn value;\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Map the framework conditional operators to those in MySQL.\n\t * @param operator The operator to map.\n\t * @returns The conditional operator.\n\t * @throws GeneralError if the conditional operator is not supported.\n\t * @internal\n\t */\n\tprivate mapConditionalOperator(operator?: LogicalOperator): string {\n\t\tif ((operator ?? LogicalOperator.And) === LogicalOperator.And) {\n\t\t\treturn \"AND\";\n\t\t} else if (operator === LogicalOperator.Or) {\n\t\t\treturn \"OR\";\n\t\t}\n\n\t\tthrow new GeneralError(PostgreSqlEntityStorageConnector.CLASS_NAME, \"conditionalNotSupported\", {\n\t\t\toperator\n\t\t});\n\t}\n\n\t/**\n\t * Verify the conditions for the entity.\n\t * @param conditions The conditions to verify.\n\t * @param obj The object to verify the conditions against.\n\t * @returns True if all conditions are met, false otherwise.\n\t * @internal\n\t */\n\tprivate verifyConditions(\n\t\tconditions: { property: keyof T; value: unknown }[],\n\t\tobj: { [key in keyof T]: unknown }\n\t): boolean {\n\t\treturn conditions.every(\n\t\t\tcondition => ObjectHelper.propertyGet(obj, condition.property as string) === condition.value\n\t\t);\n\t}\n\n\t/**\n\t * Build a mutex key for optimistic-locking critical sections.\n\t * @param partitionKey The resolved partition key.\n\t * @param id The entity id.\n\t * @returns The mutex key.\n\t * @internal\n\t */\n\tprivate buildOptimisticMutexKey(partitionKey: string | undefined, id: string): string {\n\t\treturn `${PostgreSqlEntityStorageConnector.CLASS_NAME}:optimistic:${this._config.tableName}:${partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE}:${id}`;\n\t}\n\n\t/**\n\t * Map entity schema properties to SQL properties.\n\t * @param entitySchema The schema of the entity.\n\t * @returns The SQL properties as a string.\n\t * @throws GeneralError if the entity properties do not exist.\n\t * @internal\n\t */\n\tprivate mapPostgreSqlProperties(entitySchema: IEntitySchema<T>): string {\n\t\tconst sqlTypeMap: { [key in EntitySchemaPropertyType]: string } = {\n\t\t\t[EntitySchemaPropertyType.String]: \"TEXT\",\n\t\t\t[EntitySchemaPropertyType.Number]: \"REAL\",\n\t\t\t[EntitySchemaPropertyType.Integer]: \"INTEGER\",\n\t\t\t[EntitySchemaPropertyType.Object]: \"JSONB\",\n\t\t\t[EntitySchemaPropertyType.Array]: \"JSONB\",\n\t\t\t[EntitySchemaPropertyType.Boolean]: \"BOOLEAN\"\n\t\t};\n\n\t\tif (!entitySchema.properties) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"entitySchemaPropertiesUndefined\"\n\t\t\t);\n\t\t}\n\n\t\tconst primaryKeys: string[] = [];\n\n\t\tconst props: IEntitySchemaProperty<T>[] = [...entitySchema.properties];\n\n\t\tprops.unshift({\n\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY as keyof T,\n\t\t\ttype: EntitySchemaPropertyType.String,\n\t\t\tmaxLength: PostgreSqlEntityStorageConnector._PARTITION_KEY_MAX_LENGTH,\n\t\t\toptional: false,\n\t\t\tisPrimary: true\n\t\t});\n\n\t\tconst columnDefinitions = props\n\t\t\t.map(prop => {\n\t\t\t\tlet sqlType = sqlTypeMap[prop.type] || \"TEXT\";\n\t\t\t\tif (prop.format) {\n\t\t\t\t\tswitch (prop.type) {\n\t\t\t\t\t\tcase EntitySchemaPropertyType.String:\n\t\t\t\t\t\t\tswitch (prop.format) {\n\t\t\t\t\t\t\t\tcase \"uuid\":\n\t\t\t\t\t\t\t\t\tsqlType = \"UUID\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EntitySchemaPropertyType.Number:\n\t\t\t\t\t\t\tswitch (prop.format) {\n\t\t\t\t\t\t\t\tcase \"float\":\n\t\t\t\t\t\t\t\t\tsqlType = \"REAL\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"double\":\n\t\t\t\t\t\t\t\t\tsqlType = \"DOUBLE PRECISION\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EntitySchemaPropertyType.Integer:\n\t\t\t\t\t\t\tswitch (prop.format) {\n\t\t\t\t\t\t\t\tcase \"int8\":\n\t\t\t\t\t\t\t\tcase \"uint8\":\n\t\t\t\t\t\t\t\t\tsqlType = \"SMALLINT\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"int16\":\n\t\t\t\t\t\t\t\t\tsqlType = \"SMALLINT\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"uint16\":\n\t\t\t\t\t\t\t\tcase \"int32\":\n\t\t\t\t\t\t\t\t\tsqlType = \"INTEGER\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"uint32\":\n\t\t\t\t\t\t\t\tcase \"int64\":\n\t\t\t\t\t\t\t\tcase \"uint64\":\n\t\t\t\t\t\t\t\t\tsqlType = \"BIGINT\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// An explicit maxLength always wins, otherwise a format default only applies when the\n\t\t\t\t// format did not already map to a dedicated column type such as UUID.\n\t\t\t\tconst formatMaxLength =\n\t\t\t\t\tsqlType === \"TEXT\" && Is.stringValue(prop.format)\n\t\t\t\t\t\t? EntitySchemaHelper.FORMAT_MAX_LENGTHS[prop.format]\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst maxLength = prop.maxLength ?? formatMaxLength;\n\n\t\t\t\tif (\n\t\t\t\t\tprop.type === EntitySchemaPropertyType.String &&\n\t\t\t\t\tIs.integer(maxLength) &&\n\t\t\t\t\tmaxLength > 0 &&\n\t\t\t\t\tmaxLength <= PostgreSqlEntityStorageConnector._MAX_VARCHAR_LENGTH\n\t\t\t\t) {\n\t\t\t\t\tsqlType = `VARCHAR(${maxLength})`;\n\t\t\t\t}\n\n\t\t\t\tconst columnName = String(prop.property);\n\t\t\t\tconst nullable = prop.optional ? \" NULL\" : \" NOT NULL\";\n\n\t\t\t\tif (prop.isPrimary) {\n\t\t\t\t\tprimaryKeys.push(columnName);\n\t\t\t\t}\n\n\t\t\t\treturn `\"${columnName}\" ${sqlType}${nullable}`;\n\t\t\t})\n\t\t\t.join(\", \");\n\n\t\tconst primaryKeyDefinition =\n\t\t\tprimaryKeys.length > 0 ? `, PRIMARY KEY (\"${primaryKeys.join('\", \"')}\")` : \"\";\n\t\treturn columnDefinitions + primaryKeyDefinition;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"postgreSqlEntityStorageConnector.js","sourceRoot":"","sources":["../../src/postgreSqlEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHealthCategory,\n\tHealthStatus,\n\ttype IHealth,\n\ttype IHealthProviderComponent\n} from \"@twin.org/api-models\";\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tCoerce,\n\tComponentFactory,\n\tConflictError,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tMutex,\n\ttype IValidationFailure,\n\tObjectHelper,\n\tRandomHelper,\n\tValidation\n} from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\ttype EntityCondition,\n\tEntitySchemaFactory,\n\tEntitySchemaHelper,\n\tEntitySchemaPropertyType,\n\ttype IComparator,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty,\n\tLogicalOperator,\n\tSortDirection\n} from \"@twin.org/entity\";\nimport {\n\tConnectionHelper,\n\tEntityStorageHelper,\n\ttype IEntityStorageConnector,\n\ttype IEntityStorageJoinOptions,\n\ttype IEntityStorageMigrationConnector,\n\ttype IMigrationOptions,\n\tIndexHelper,\n\tMigrationHelper\n} from \"@twin.org/entity-storage-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport postgres, { type ParameterOrJSON } from \"postgres\";\nimport type { IPostgreSqlEntityStorageConnectorConfig } from \"./models/IPostgreSqlEntityStorageConnectorConfig.js\";\nimport type { IPostgreSqlEntityStorageConnectorConstructorOptions } from \"./models/IPostgreSqlEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations using ql.\n */\nexport class PostgreSqlEntityStorageConnector<T = unknown>\n\timplements IEntityStorageMigrationConnector<T>, IHealthProviderComponent\n{\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<PostgreSqlEntityStorageConnector>();\n\n\t/**\n\t * Limit the number of entities when finding.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_LIMIT: number = 40;\n\n\t/**\n\t * Partition id field name.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY: string = \"partitionId\";\n\n\t/**\n\t * Partition id field value.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY_VALUE: string = \"root\";\n\n\t/**\n\t * Maximum length of the partition id column. The column leads the primary key and every\n\t * index, so it is bounded rather than stored as unconstrained text.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY_MAX_LENGTH: number = 255;\n\n\t/**\n\t * Maximum number of rows per INSERT statement in setBatch.\n\t * @internal\n\t */\n\tprivate static readonly _BATCH_CHUNK_SIZE: number = 1000;\n\n\t/**\n\t * The column the group ranking is emitted as when picking one row per group.\n\t * @internal\n\t */\n\tprivate static readonly _GROUP_RANK_COLUMN: string = \"__groupRank\";\n\n\t/**\n\t * PostgreSQL's maximum identifier length in characters; longer names are silently truncated.\n\t * @internal\n\t */\n\tprivate static readonly _MAX_IDENTIFIER_LENGTH: number = 63;\n\n\t/**\n\t * The largest length which can be expressed as VARCHAR(N), anything above this is stored as TEXT.\n\t * @internal\n\t */\n\tprivate static readonly _MAX_VARCHAR_LENGTH: number = 10485760;\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 * The schema for the entity.\n\t * @internal\n\t */\n\tprivate readonly _entitySchema: IEntitySchema<T>;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprivate readonly _partitionContextIds?: string[];\n\n\t/**\n\t * The primary key property.\n\t * @internal\n\t */\n\tprivate readonly _primaryKeyProperty: IEntitySchemaProperty<T>;\n\n\t/**\n\t * The name of the version property, if any.\n\t * @internal\n\t */\n\tprivate readonly _versionKey?: string;\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: IPostgreSqlEntityStorageConnectorConfig;\n\n\t/**\n\t * Milliseconds to wait for optimistic-lock mutexes before throwing.\n\t * @internal\n\t */\n\tprivate readonly _mutexTimeoutMs?: number;\n\n\t/**\n\t * Unique identifier for this connector instance, used to track references in SharedStore.\n\t * @internal\n\t */\n\tprivate readonly _instanceId: string;\n\n\t/**\n\t * Create a new instance of PostgreSqlEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IPostgreSqlEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<IPostgreSqlEntityStorageConnectorConfig>(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.host),\n\t\t\toptions.config.host\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.user),\n\t\t\toptions.config.user\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.password),\n\t\t\toptions.config.password\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.database),\n\t\t\toptions.config.database\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.tableName),\n\t\t\toptions.config.tableName\n\t\t);\n\n\t\tif (!Is.empty(options.config.pool?.connectTimeout)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.connectTimeout),\n\t\t\t\toptions.config.pool?.connectTimeout\n\t\t\t);\n\t\t}\n\n\t\tif (!Is.empty(options.config.pool?.idleTimeout)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.idleTimeout),\n\t\t\t\toptions.config.pool?.idleTimeout\n\t\t\t);\n\t\t}\n\n\t\tif (!Is.empty(options.config.pool?.max)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.max),\n\t\t\t\toptions.config.pool?.max\n\t\t\t);\n\t\t}\n\n\t\tif (!Is.empty(options.config.pool?.maxLifetime)) {\n\t\t\tGuards.integer(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.pool?.maxLifetime),\n\t\t\t\toptions.config.pool?.maxLifetime\n\t\t\t);\n\t\t}\n\n\t\tthis._entitySchemaName = options.entitySchema;\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\t\tthis._primaryKeyProperty = EntitySchemaHelper.getPrimaryKey(this._entitySchema);\n\t\tthis._versionKey = EntitySchemaHelper.findVersionProperty(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._mutexTimeoutMs = Coerce.integer(options.config.mutexTimeoutMs);\n\t\tthis._instanceId = RandomHelper.generateUuidV7(\"compact\");\n\t}\n\n\t/**\n\t * Initialize the PostgreSql environment.\n\t * @param nodeLoggingComponentType Optional type of the logging component.\n\t * @returns A promise that resolves to a boolean indicating success.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tlet dbConnection: postgres.Sql;\n\t\ttry {\n\t\t\tconst adminClient = postgres(this.createConnectionConfig(false));\n\t\t\ttry {\n\t\t\t\tconst databaseExists = await this.databaseExists(adminClient);\n\t\t\t\tif (!databaseExists) {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"databaseCreating\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tawait adminClient.unsafe(`CREATE DATABASE \"${this._config.database}\";`);\n\t\t\t\t\tawait this.waitForDatabaseExists(adminClient);\n\t\t\t\t} else {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"databaseExists\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait adminClient.end();\n\t\t\t}\n\n\t\t\tdbConnection = await this.getClient();\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"databaseCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tconst tableExists = await this.tableExists();\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: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst createTableQuery = `CREATE TABLE \"${this._config.tableName}\" (${this.mapPostgreSqlProperties(this._entitySchema)})`;\n\t\t\t\tawait dbConnection.unsafe(createTableQuery);\n\t\t\t\tawait this.waitForTableExists();\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: PostgreSqlEntityStorageConnector.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\ttableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst indexes = await this.readIndexes(dbConnection);\n\n\t\t\tfor (const prop of this._entitySchema.properties ?? []) {\n\t\t\t\tif (\n\t\t\t\t\t(prop.isSecondary === true || !Is.empty(prop.sortDirection)) &&\n\t\t\t\t\tprop.type !== EntitySchemaPropertyType.Object &&\n\t\t\t\t\tprop.type !== EntitySchemaPropertyType.Array\n\t\t\t\t) {\n\t\t\t\t\tawait this.ensureIndex(dbConnection, indexes, prop, nodeLogging);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst indexGroups = EntitySchemaHelper.getIndexGroups(this._entitySchema);\n\t\t\tfor (const indexProperties of Object.values(indexGroups)) {\n\t\t\t\tawait this.ensureCompositeIndex(dbConnection, indexes, indexProperties);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\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 PostgreSqlEntityStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\ttry {\n\t\t\tconst sql = await this.getClient();\n\t\t\tawait sql`SELECT 1 FROM ${sql(this._config.tableName)} LIMIT 0`;\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { tableName: this._config.tableName }\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: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\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: { tableName: this._config.tableName }\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\t}\n\n\t/**\n\t * The component needs to be stopped when the node is closed.\n\t * @returns Nothing.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tawait ConnectionHelper.closeClient<postgres.Sql>(\n\t\t\t\"postgreSqlConnections\",\n\t\t\tthis.createClientId(),\n\t\t\tthis._instanceId,\n\t\t\tthis._mutexTimeoutMs,\n\t\t\tasync sql => sql.end()\n\t\t);\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 from PostgreSql.\n\t * @param id The id of the entity to get, or the index value if secondaryIndex is set.\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(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\n\t\t\tconst whereClauses: string[] = [];\n\t\t\tconst values: unknown[] = [];\n\n\t\t\twhereClauses.push(`\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $1`);\n\t\t\tvalues.push(partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE);\n\n\t\t\tif (secondaryIndex) {\n\t\t\t\twhereClauses.push(`\"${String(secondaryIndex)}\" = $2`);\n\t\t\t\tvalues.push(id);\n\t\t\t} else {\n\t\t\t\twhereClauses.push(`\"${this._primaryKeyProperty.property as string}\" = $2`);\n\t\t\t\tvalues.push(id);\n\t\t\t}\n\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfor (const condition of conditions) {\n\t\t\t\t\twhereClauses.push(`\"${String(condition.property)}\" = $${values.length + 1}`);\n\t\t\t\t\tvalues.push(condition.value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst query = `SELECT * FROM \"${this._config.tableName}\" WHERE ${whereClauses.join(\" AND \")} LIMIT 1`;\n\n\t\t\tconst rows = await dbConnection.unsafe(query, values as postgres.ParameterOrJSON<never>[]);\n\n\t\t\tif (Is.array(rows) && rows.length === 1) {\n\t\t\t\tif (this._entitySchema.properties) {\n\t\t\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\t\t\tconst row = rows[0] as unknown as { [key: string]: unknown };\n\t\t\t\t\t\tlet propColumn = prop.property as string;\n\t\t\t\t\t\tpropColumn = propColumn.toLowerCase();\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(prop.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\t\t\tprop.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\t\t\tIs.string(row[propColumn])\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tvalue = JSON.parse((rows[0] as { [key: string]: unknown })[propColumn] as string);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// If JSON.parse fails, keep the value as string\n\t\t\t\t\t\t\t\t// This handles cases where plain text was stored in Object/Array fields\n\t\t\t\t\t\t\t\tvalue = (rows[0] as { [key: string]: unknown })[propColumn];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete (rows[0] as { [key: string]: unknown })[propColumn];\n\t\t\t\t\t\t\t(rows[0] as { [key: string]: unknown })[prop.property as string] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (row[propColumn] === null) {\n\t\t\t\t\t\t\t(rows[0] as { [key: string]: unknown })[prop.property as string] = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn EntityStorageHelper.unPrepareEntity<T>(rows[0] as T, [\n\t\t\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY\n\t\t\t\t]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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\terr\n\t\t\t);\n\t\t}\n\t\treturn undefined;\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 * @returns The id of the entity.\n\t * @throws ConflictError when the entity exists but the supplied conditions or version do not match the stored state.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst submittedVersion = Is.stringValue(this._versionKey)\n\t\t\t? Coerce.integer(ObjectHelper.propertyGet(entity, this._versionKey))\n\t\t\t: undefined;\n\t\tconst hasVersionCheck =\n\t\t\t!Is.empty(this._versionKey) && !Is.empty(submittedVersion) && submittedVersion > 0;\n\n\t\tconst prepared = EntityStorageHelper.prepareEntity(\n\t\t\tentity,\n\t\t\tthis._entitySchema,\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\tvalue: partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t}\n\t\t\t],\n\t\t\t{ nullBehavior: \"nullify\" }\n\t\t);\n\n\t\tconst id = prepared[this._primaryKeyProperty.property] as unknown as string;\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tif (hasVersionCheck) {\n\t\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\t\tconst currentEntity = await this.get(id);\n\t\t\t\t\tif (!Is.empty(currentEntity) && !this.verifyConditions(conditions, currentEntity)) {\n\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\tid\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tObjectHelper.propertySet(prepared, this._versionKey, submittedVersion + 1);\n\t\t\t} else if (this._versionKey || Is.arrayValue(conditions)) {\n\t\t\t\tconst currentEntity = await this.get(id);\n\t\t\t\tif (!Is.empty(currentEntity)) {\n\t\t\t\t\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, currentEntity)) {\n\t\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\tconst storedVersion =\n\t\t\t\t\t\tCoerce.integer(\n\t\t\t\t\t\t\t!Is.empty(currentEntity)\n\t\t\t\t\t\t\t\t? ObjectHelper.propertyGet(currentEntity, this._versionKey)\n\t\t\t\t\t\t\t\t: 0\n\t\t\t\t\t\t) ?? 0;\n\t\t\t\t\tObjectHelper.propertySet(prepared, this._versionKey, storedVersion + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst props = [...(this._entitySchema.properties ?? [])];\n\t\t\tprops.unshift({\n\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY as keyof T,\n\t\t\t\ttype: EntitySchemaPropertyType.String\n\t\t\t});\n\n\t\t\tconst keys: string[] = [];\n\t\t\tconst values: unknown[] = [];\n\n\t\t\tfor (const prop of props) {\n\t\t\t\tkeys.push(prop.property as string);\n\t\t\t\tconst val = prepared[prop.property];\n\t\t\t\tvalues.push(val ?? null);\n\t\t\t}\n\n\t\t\tlet sql = `INSERT INTO \"${this._config.tableName}\"`;\n\t\t\tsql += ` (${keys.map(key => `\"${key}\"`).join(\", \")})`;\n\t\t\tsql += ` VALUES (${values.map((value, i) => `$${i + 1}`).join(\", \")})`;\n\t\t\tsql += ` ON CONFLICT (\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\", \"${this._primaryKeyProperty.property as string}\")`;\n\n\t\t\tif (hasVersionCheck) {\n\t\t\t\tsql += ` DO UPDATE SET ${keys.map(key => `\"${key}\" = EXCLUDED.\"${key}\"`).join(\", \")}`;\n\t\t\t\tsql += ` WHERE \"${this._config.tableName}\".\"${this._versionKey}\" = $${values.length + 1}`;\n\t\t\t\tvalues.push(submittedVersion);\n\t\t\t} else {\n\t\t\t\tsql += ` DO UPDATE SET ${keys.map(key => `\"${key}\" = EXCLUDED.\"${key}\"`).join(\", \")};`;\n\t\t\t}\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst result = await dbConnection.unsafe(sql, values as ParameterOrJSON<never>[]);\n\n\t\t\tif (hasVersionCheck && result.count === 0) {\n\t\t\t\tthrow new ConflictError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"optimisticLockFailed\",\n\t\t\t\t\tid\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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\terr\n\t\t\t);\n\t\t} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\n\t\t\t}\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(PostgreSqlEntityStorageConnector.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 preparedEntities = entities.map(entity =>\n\t\t\tEntityStorageHelper.prepareEntity(\n\t\t\t\tentity,\n\t\t\t\tthis._entitySchema,\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\tvalue: partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t{ nullBehavior: \"nullify\" }\n\t\t\t)\n\t\t);\n\n\t\ttry {\n\t\t\tconst props = [...(this._entitySchema.properties ?? [])];\n\t\t\tprops.unshift({\n\t\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY as keyof T,\n\t\t\t\ttype: EntitySchemaPropertyType.String\n\t\t\t});\n\t\t\tconst keys = props.map(p => p.property as string);\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst chunkSize = PostgreSqlEntityStorageConnector._BATCH_CHUNK_SIZE;\n\n\t\t\tfor (let offset = 0; offset < preparedEntities.length; offset += chunkSize) {\n\t\t\t\tconst chunk = preparedEntities.slice(offset, offset + chunkSize);\n\t\t\t\tconst allValues: unknown[] = [];\n\t\t\t\tconst rowPlaceholders: string[] = [];\n\n\t\t\t\tfor (const prepared of chunk) {\n\t\t\t\t\tconst rowValues: string[] = [];\n\t\t\t\t\tfor (const prop of props) {\n\t\t\t\t\t\tconst val = prepared[prop.property];\n\t\t\t\t\t\tallValues.push(Is.empty(val) ? null : val);\n\t\t\t\t\t\trowValues.push(`$${allValues.length}`);\n\t\t\t\t\t}\n\t\t\t\t\trowPlaceholders.push(`(${rowValues.join(\", \")})`);\n\t\t\t\t}\n\n\t\t\t\tlet sql = `INSERT INTO \"${this._config.tableName}\"`;\n\t\t\t\tsql += ` (${keys.map(key => `\"${key}\"`).join(\", \")})`;\n\t\t\t\tsql += ` VALUES ${rowPlaceholders.join(\", \")}`;\n\t\t\t\tsql += ` ON CONFLICT (\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\", \"${this._primaryKeyProperty.property as string}\")`;\n\t\t\t\tsql += ` DO UPDATE SET ${keys.map(key => `\"${key}\" = EXCLUDED.\"${key}\"`).join(\", \")};`;\n\n\t\t\t\tawait dbConnection.unsafe(sql, allValues as ParameterOrJSON<never>[]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"setBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Empty all the entities.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst sql = `DELETE FROM \"${this._config.tableName}\" WHERE \"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $1`;\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tawait dbConnection.unsafe(sql, [\n\t\t\t\tpartitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t]);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"emptyFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\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 * @returns Nothing.\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(PostgreSqlEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\n\t\t\tconst itemData = await this.get(id);\n\t\t\tif (!Is.empty(itemData)) {\n\t\t\t\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData)) {\n\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\tid\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst values: unknown[] = [];\n\t\t\t\tconst whereClauses: string[] = [];\n\n\t\t\t\twhereClauses.push(\n\t\t\t\t\t`\"${this._primaryKeyProperty.property as string}\" = $${values.length + 1}`\n\t\t\t\t);\n\t\t\t\tvalues.push(id);\n\n\t\t\t\twhereClauses.push(\n\t\t\t\t\t`\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $${values.length + 1}`\n\t\t\t\t);\n\t\t\t\tvalues.push(partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE);\n\n\t\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\t\twhereClauses.push(\n\t\t\t\t\t\t...conditions.map(condition => {\n\t\t\t\t\t\t\tvalues.push(condition.value);\n\t\t\t\t\t\t\treturn `\"${String(condition.property)}\" = $${values.length}`;\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst query = `DELETE FROM \"${this._config.tableName}\" WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t\tawait dbConnection.unsafe(query, values as postgres.ParameterOrJSON<never>[]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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\terr\n\t\t\t);\n\t\t} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove multiple entities by their primary key IDs.\n\t * @param ids The ids of the entities to remove.\n\t * @returns Nothing.\n\t */\n\tpublic async removeBatch(ids: string[]): Promise<void> {\n\t\tGuards.arrayValue(PostgreSqlEntityStorageConnector.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\ttry {\n\t\t\tconst sql = `DELETE FROM \"${this._config.tableName}\" WHERE \"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" = $1 AND \"${this._primaryKeyProperty.property as string}\" = ANY($2)`;\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tawait dbConnection.unsafe(sql, [\n\t\t\t\tpartitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\tids\n\t\t\t] as ParameterOrJSON<never>[]);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.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}\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: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"tableDropping\",\n\t\t\tdata: { tableName: this._config.tableName }\n\t\t});\n\n\t\ttry {\n\t\t\tconst tableExists = await this.tableExists();\n\t\t\tif (tableExists) {\n\t\t\t\tconst dbConnection = await this.getClient();\n\t\t\t\tawait dbConnection.unsafe(`DROP TABLE \"${this._config.tableName}\";`);\n\t\t\t\tawait this.waitForTableNotExists();\n\t\t\t}\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableDropped\",\n\t\t\t\tdata: { tableName: this._config.tableName }\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: PostgreSqlEntityStorageConnector.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}\n\t}\n\n\t/**\n\t * Get the connector implementation version.\n\t * @returns The connector implementation version.\n\t */\n\tpublic connectorVersion(): number {\n\t\treturn 1;\n\t}\n\n\t/**\n\t * Get all the distinct partition context ids from the storage.\n\t * @param loggingComponentType The optional component type to use for logging skipped partition ids.\n\t * @returns An array of context id objects, one per unique partition.\n\t */\n\tpublic async getPartitionContextIds(\n\t\tloggingComponentType?: string\n\t): Promise<IContextIds[] | undefined> {\n\t\tif (!Is.arrayValue(this._partitionContextIds)) {\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst rows = await dbConnection.unsafe(\n\t\t\t\t`SELECT DISTINCT \"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" FROM \"${this._config.tableName}\"`\n\t\t\t);\n\t\t\tconst partitionIds = (rows as { [key: string]: string }[])\n\t\t\t\t.map(row => row[PostgreSqlEntityStorageConnector._PARTITION_KEY])\n\t\t\t\t.filter((id): id is string => Is.stringValue(id));\n\t\t\tconst contextIds: IContextIds[] = [];\n\t\t\tconst skipped: string[] = [];\n\t\t\tfor (const partitionId of partitionIds) {\n\t\t\t\tconst split = EntityStorageHelper.tryShortSplit(\n\t\t\t\t\tthis._partitionContextIds ?? [],\n\t\t\t\t\tpartitionId\n\t\t\t\t);\n\t\t\t\tif (Is.undefined(split)) {\n\t\t\t\t\tskipped.push(partitionId);\n\t\t\t\t} else {\n\t\t\t\t\tcontextIds.push(split);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Is.arrayValue(skipped)) {\n\t\t\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(loggingComponentType);\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"warn\",\n\t\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"partitionIdsSkipped\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\texpected: this._partitionContextIds?.length,\n\t\t\t\t\t\tpartitionIds: skipped.join(\", \")\n\t\t\t\t\t}\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\tPostgreSqlEntityStorageConnector.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}\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<PostgreSqlEntityStorageConnector<U>> {\n\t\treturn new PostgreSqlEntityStorageConnector<U>({\n\t\t\tentitySchema: entitySchemaName,\n\t\t\tconfig: {\n\t\t\t\t...this._config,\n\t\t\t\ttableName: MigrationHelper.generateTargetName(\n\t\t\t\t\tthis._config.tableName,\n\t\t\t\t\tPostgreSqlEntityStorageConnector._MAX_IDENTIFIER_LENGTH\n\t\t\t\t)\n\t\t\t},\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by renaming the migration table to the original table name.\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 final (renamed) table.\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: PostgreSqlEntityStorageConnector<U>,\n\t\toptions?: IMigrationOptions,\n\t\tloggingComponentType?: string\n\t): Promise<PostgreSqlEntityStorageConnector<U>> {\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 dbConnection = await targetConnector.getClient();\n\t\tawait dbConnection.unsafe(\n\t\t\t`ALTER TABLE \"${targetConnector._config.tableName}\" RENAME TO \"${this._config.tableName}\"`\n\t\t);\n\t\tconst finalConnector = new PostgreSqlEntityStorageConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t\tif (await finalConnector.bootstrap(loggingComponentType)) {\n\t\t\tawait targetConnector.stop();\n\t\t\treturn finalConnector;\n\t\t}\n\t\tthrow new GeneralError(\n\t\t\tPostgreSqlEntityStorageConnector.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?: PostgreSqlEntityStorageConnector<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 * 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?: { property: keyof T; sortDirection: SortDirection }[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ entities: Partial<T>[]; cursor?: string }> {\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\t\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\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\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"query\",\n\t\t\t\tvalidationFailures\n\t\t\t);\n\t\t}\n\n\t\tlet sql = \"\";\n\t\ttry {\n\t\t\tconst returnSize = limit ?? PostgreSqlEntityStorageConnector._DEFAULT_LIMIT;\n\n\t\t\tconst pkPropName = String(this._primaryKeyProperty.property);\n\n\t\t\tconst sortsByPK =\n\t\t\t\tIs.array(sortProperties) && sortProperties.some(s => String(s.property) === pkPropName);\n\n\t\t\tconst keySetCols: { prop: string; asc: boolean }[] = [];\n\t\t\tif (Is.array(sortProperties)) {\n\t\t\t\tfor (const s of sortProperties) {\n\t\t\t\t\tkeySetCols.push({\n\t\t\t\t\t\tprop: String(s.property),\n\t\t\t\t\t\tasc: s.sortDirection === SortDirection.Ascending\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!sortsByPK) {\n\t\t\t\tkeySetCols.push({ prop: pkPropName, asc: true });\n\t\t\t}\n\n\t\t\tconst requestedProps = properties ? new Set(properties.map(p => String(p))) : undefined;\n\t\t\tconst internallyAdded = new Set<string>();\n\n\t\t\tlet selectClause: string;\n\t\t\tif (requestedProps) {\n\t\t\t\tconst selectSet = new Set(requestedProps);\n\t\t\t\tfor (const col of keySetCols) {\n\t\t\t\t\tif (!selectSet.has(col.prop)) {\n\t\t\t\t\t\tselectSet.add(col.prop);\n\t\t\t\t\t\tinternallyAdded.add(col.prop);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tselectClause = [...selectSet].map(p => `\"${p}\"`).join(\", \");\n\t\t\t} else {\n\t\t\t\tselectClause = \"*\";\n\t\t\t}\n\n\t\t\tconst orderByClause = `ORDER BY ${keySetCols.map(c => `\"${c.prop}\" ${c.asc ? \"ASC\" : \"DESC\"}`).join(\", \")}`;\n\n\t\t\tconst { whereClauses, values } = this.buildWhereClause(conditions, partitionKey);\n\n\t\t\tif (Is.stringBase64(cursor)) {\n\t\t\t\tconst parsedCursor = ObjectHelper.fromBytes<{ i: string; sv?: unknown[] }>(\n\t\t\t\t\tConverter.base64ToBytes(cursor)\n\t\t\t\t);\n\t\t\t\tconst lastValues: unknown[] = [...(parsedCursor.sv ?? []), parsedCursor.i];\n\t\t\t\tconst orParts: string[] = [];\n\t\t\t\tfor (let i = 0; i < keySetCols.length; i++) {\n\t\t\t\t\tconst parts: string[] = [];\n\t\t\t\t\tfor (let j = 0; j < i; j++) {\n\t\t\t\t\t\tvalues.push(lastValues[j] as ParameterOrJSON<never>);\n\t\t\t\t\t\tparts.push(`\"${keySetCols[j].prop}\" = $${values.length}`);\n\t\t\t\t\t}\n\t\t\t\t\tconst op = keySetCols[i].asc ? \">\" : \"<\";\n\t\t\t\t\tvalues.push(lastValues[i] as ParameterOrJSON<never>);\n\t\t\t\t\tparts.push(`\"${keySetCols[i].prop}\" ${op} $${values.length}`);\n\t\t\t\t\torParts.push(parts.length === 1 ? parts[0] : `(${parts.join(\" AND \")})`);\n\t\t\t\t}\n\t\t\t\twhereClauses.push(`(${orParts.join(\" OR \")})`);\n\t\t\t}\n\n\t\t\tsql = `SELECT ${selectClause} FROM \"${this._config.tableName}\"`;\n\t\t\tif (whereClauses.length > 0) {\n\t\t\t\tsql += ` WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t}\n\t\t\tsql += ` ${orderByClause} LIMIT ${returnSize + 1}`;\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst rows = await dbConnection.unsafe(sql, values);\n\n\t\t\tif (this._entitySchema.properties) {\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\t\t\tlet propColumn = prop.property as string;\n\t\t\t\t\t\tpropColumn = propColumn.toLowerCase();\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(prop.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\t\t\t\tprop.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\t\t\t\tIs.string(row[propColumn])\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tvalue = JSON.parse(row[propColumn] as string);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// If JSON.parse fails, keep the value as string\n\t\t\t\t\t\t\t\t// This handles cases where plain text was stored in Object/Array fields\n\t\t\t\t\t\t\t\tvalue = row[propColumn];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete row[propColumn];\n\t\t\t\t\t\t\trow[prop.property as string] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (row[propColumn] === null) {\n\t\t\t\t\t\t\trow[prop.property as string] = undefined;\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 hasMore = Is.array(rows) && rows.length > returnSize;\n\t\t\tconst resultRows = hasMore ? rows.slice(0, returnSize) : rows;\n\t\t\tconst entities = resultRows as unknown as Partial<T>[];\n\n\t\t\tlet nextCursor: string | undefined;\n\t\t\tif (hasMore && entities.length > 0) {\n\t\t\t\tconst lastRow = entities[entities.length - 1];\n\t\t\t\tconst sortValues = keySetCols\n\t\t\t\t\t.slice(0, -1)\n\t\t\t\t\t.map(c => ObjectHelper.propertyGet(lastRow, c.prop));\n\t\t\t\tconst lastId = ObjectHelper.propertyGet<string>(lastRow, pkPropName);\n\t\t\t\tif (Is.stringValue(lastId)) {\n\t\t\t\t\tconst cursorData: { i: string; sv?: unknown[] } =\n\t\t\t\t\t\tsortValues.length > 0 ? { i: lastId, sv: sortValues } : { i: lastId };\n\t\t\t\t\tnextCursor = Converter.bytesToBase64(ObjectHelper.toBytes(cursorData));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < entities.length; i++) {\n\t\t\t\tentities[i] = EntityStorageHelper.unPrepareEntity(entities[i], [\n\t\t\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY\n\t\t\t\t]);\n\t\t\t\tfor (const col of internallyAdded) {\n\t\t\t\t\tObjectHelper.propertyDelete(entities[i], col);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { entities, cursor: nextCursor };\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryFailed\",\n\t\t\t\t{ sql },\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions, attaching to each one the entities from a\n\t * second storage connector whose join property matches. The join behaves like a left join by\n\t * default, a primary entity with no matches is still returned with an empty joined list, unless\n\t * joinRequired asks for an inner join and those entities are left out altogether. Both connectors\n\t * must be PostgreSQL connectors reading from the same database so the work can be done in a\n\t * single statement.\n\t * @param joinConnector The connector holding the entities to join to.\n\t * @param joinOptions The properties to join on, the conditions, sort order, projection and\n\t * paging for the primary entities, the optional grouping and group conditions, and the optional\n\t * conditions, sort order and projection for the joined entities.\n\t * @returns All the entities for the storage matching the conditions with their joined entities,\n\t * and a cursor which can be used to request more entities.\n\t * @throws GeneralError if the join connector does not read from the same server and database.\n\t */\n\tpublic async queryJoin<U>(\n\t\tjoinConnector: IEntityStorageConnector<U>,\n\t\tjoinOptions: IEntityStorageJoinOptions<T, U>\n\t): Promise<{ entities: (Partial<T> & { joined: Partial<U>[] })[]; cursor?: string }> {\n\t\tGuards.object<IEntityStorageConnector<U>>(\n\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(joinConnector),\n\t\t\tjoinConnector\n\t\t);\n\n\t\t// The join runs as one statement against this connector's connection, so the other side has\n\t\t// to be a PostgreSQL connector reading from the same server and database.\n\t\tconst typedJoinConnector = joinConnector as PostgreSqlEntityStorageConnector<U>;\n\t\tif (\n\t\t\tjoinConnector.className?.() !== PostgreSqlEntityStorageConnector.CLASS_NAME ||\n\t\t\ttypedJoinConnector._config?.host !== this._config.host ||\n\t\t\ttypedJoinConnector._config?.port !== this._config.port ||\n\t\t\ttypedJoinConnector._config?.database !== this._config.database\n\t\t) {\n\t\t\tthrow new GeneralError(PostgreSqlEntityStorageConnector.CLASS_NAME, \"joinConnectorMismatch\", {\n\t\t\t\tdatabase: this._config.database\n\t\t\t});\n\t\t}\n\n\t\tEntityStorageHelper.validateJoinOptions(\n\t\t\tthis._entitySchema,\n\t\t\ttypedJoinConnector._entitySchema,\n\t\t\tjoinOptions\n\t\t);\n\n\t\treturn this.queryJoinPage(typedJoinConnector, joinOptions, joinOptions.groupProperty);\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\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\n\n\t\tlet queryStr: string | undefined;\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\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 { whereClauses, values } = this.buildWhereClause(conditions, partitionKey);\n\n\t\t\tqueryStr = `SELECT COUNT(*) AS count FROM \"${this._config.tableName}\"`;\n\t\t\tif (whereClauses.length > 0) {\n\t\t\t\tqueryStr += ` WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t}\n\n\t\t\tconst result = await dbConnection.unsafe(queryStr, values);\n\t\t\treturn Number(result[0].count);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"countFailed\",\n\t\t\t\t{ sql: queryStr },\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Read a page of primary entities and their joined entities in a single statement. The page of\n\t * primary rows is selected in a derived table so the limit and the cursor apply to the primary\n\t * entities rather than to the rows the join multiplies them into. When grouping, the derived\n\t * table keeps only the first row of each group in the sort order, which makes one row stand for\n\t * the whole group and lets the same key set cursor step past every row the group holds.\n\t * @param joinConnector The connector holding the entities to join to.\n\t * @param joinOptions The join configuration.\n\t * @param groupProperty The optional property to group the primary entities by.\n\t * @returns The entities with their joined entities, and the next page cursor.\n\t * @internal\n\t */\n\tprivate async queryJoinPage<U>(\n\t\tjoinConnector: PostgreSqlEntityStorageConnector<U>,\n\t\tjoinOptions: IEntityStorageJoinOptions<T, U>,\n\t\tgroupProperty: keyof T | undefined\n\t): Promise<{ entities: (Partial<T> & { joined: Partial<U>[] })[]; cursor?: string }> {\n\t\tconst returnSize = joinOptions.limit ?? PostgreSqlEntityStorageConnector._DEFAULT_LIMIT;\n\t\tconst pkPropName = String(this._primaryKeyProperty.property);\n\t\tconst joinColumn = String(joinOptions.property);\n\t\tconst joinedPrimaryKey = String(joinConnector._primaryKeyProperty.property);\n\n\t\tconst normalizedOptions = EntityStorageHelper.normalizeJoinOptions(joinOptions);\n\t\tconst keySetValues = EntityStorageHelper.decodeCursor<T, U, unknown[]>(\n\t\t\tnormalizedOptions,\n\t\t\tjoinOptions.cursor\n\t\t);\n\n\t\tlet sql = \"\";\n\t\ttry {\n\t\t\tconst keySetCols = this.buildKeySetColumns(joinOptions.sortProperties);\n\n\t\t\t// The key set columns, the join column and the group column are needed to page, to join\n\t\t\t// and to re-attach the members of a group, so they are read even when the caller did not\n\t\t\t// ask for them, then removed from the entities.\n\t\t\tconst primary = this.buildColumnSelection(\n\t\t\t\tthis._entitySchema,\n\t\t\t\tjoinOptions.properties,\n\t\t\t\tkeySetCols\n\t\t\t\t\t.map(c => c.prop)\n\t\t\t\t\t.concat(joinColumn)\n\t\t\t\t\t.concat(Is.empty(groupProperty) ? [] : [String(groupProperty)])\n\t\t\t);\n\t\t\tconst joined = this.buildColumnSelection(\n\t\t\t\tjoinConnector._entitySchema,\n\t\t\t\tjoinOptions.joinProperties,\n\t\t\t\t[joinedPrimaryKey]\n\t\t\t);\n\n\t\t\tconst partitionKey = await this.resolvePartitionKey();\n\t\t\tconst values: ParameterOrJSON<never>[] = [];\n\n\t\t\t// PostgreSQL numbers its placeholders, so every clause is built in the order it appears\n\t\t\t// in the statement and its values are appended as it goes.\n\t\t\tconst where = this.buildWhereClause(\n\t\t\t\tjoinOptions.conditions,\n\t\t\t\tpartitionKey,\n\t\t\t\t\"t\",\n\t\t\t\tvalues.length + 1\n\t\t\t);\n\t\t\tvalues.push(...where.values);\n\t\t\tconst whereClauses = [...where.whereClauses];\n\n\t\t\tif (!Is.empty(groupProperty)) {\n\t\t\t\twhereClauses.push(`t.\"${String(groupProperty)}\" IS NOT NULL`);\n\t\t\t}\n\n\t\t\tconst narrowing = await this.buildNarrowingClauses(\n\t\t\t\tjoinConnector,\n\t\t\t\tjoinOptions,\n\t\t\t\tgroupProperty,\n\t\t\t\tpartitionKey,\n\t\t\t\t\"t\",\n\t\t\t\tvalues.length + 1\n\t\t\t);\n\t\t\twhereClauses.push(...narrowing.clauses);\n\t\t\tvalues.push(...narrowing.values);\n\n\t\t\tconst columnList = primary.columns.map(c => `\"${c}\"`).join(\", \");\n\t\t\tconst pageOrderBy = keySetCols.map(c => `\"${c.prop}\" ${c.asc ? \"ASC\" : \"DESC\"}`).join(\", \");\n\n\t\t\tconst keySet = this.buildKeySetClause(keySetCols, keySetValues, values.length + 1);\n\t\t\tvalues.push(...keySet.values);\n\n\t\t\tlet pageSql: string;\n\t\t\tif (Is.empty(groupProperty)) {\n\t\t\t\tpageSql = `SELECT ${columnList} FROM \"${this._config.tableName}\" AS t WHERE ${[...whereClauses, ...keySet.clauses].join(\" AND \")} ORDER BY ${pageOrderBy} LIMIT ${returnSize + 1}`;\n\t\t\t} else {\n\t\t\t\t// Ranking inside each group and keeping the first row collapses the group to the one\n\t\t\t\t// row the result stands on, so the ordering, the projection and the cursor all work\n\t\t\t\t// on ordinary rows rather than on a distinct list of group values.\n\t\t\t\tconst rankedSql = `SELECT ${columnList}, ROW_NUMBER() OVER (PARTITION BY t.\"${String(groupProperty)}\" ORDER BY ${keySetCols.map(c => `t.\"${c.prop}\" ${c.asc ? \"ASC\" : \"DESC\"}`).join(\", \")}) AS \"${PostgreSqlEntityStorageConnector._GROUP_RANK_COLUMN}\" FROM \"${this._config.tableName}\" AS t WHERE ${whereClauses.join(\" AND \")}`;\n\t\t\t\tconst rankedWhere = [\n\t\t\t\t\t`ranked.\"${PostgreSqlEntityStorageConnector._GROUP_RANK_COLUMN}\" = 1`,\n\t\t\t\t\t...keySet.clauses\n\t\t\t\t];\n\t\t\t\tpageSql = `SELECT ${columnList} FROM (${rankedSql}) AS ranked WHERE ${rankedWhere.join(\" AND \")} ORDER BY ${pageOrderBy} LIMIT ${returnSize + 1}`;\n\t\t\t}\n\n\t\t\t// A group stands on one row for ordering and paging, but its joined list has to hold the\n\t\t\t// matches of every entity in the group, so the other members are re-attached to the page\n\t\t\t// and the join hangs off them. The same joined entity reached through more than one\n\t\t\t// member is collapsed when the rows are collected.\n\t\t\tlet fromClause = `(${pageSql}) AS p`;\n\t\t\tlet joinFromAlias = \"p\";\n\n\t\t\tif (!Is.empty(groupProperty)) {\n\t\t\t\tconst members = this.buildWhereClause(\n\t\t\t\t\tjoinOptions.conditions,\n\t\t\t\t\tpartitionKey,\n\t\t\t\t\t\"m\",\n\t\t\t\t\tvalues.length + 1\n\t\t\t\t);\n\t\t\t\tvalues.push(...members.values);\n\t\t\t\tconst memberNarrowing = await this.buildNarrowingClauses(\n\t\t\t\t\tjoinConnector,\n\t\t\t\t\tjoinOptions,\n\t\t\t\t\tundefined,\n\t\t\t\t\tpartitionKey,\n\t\t\t\t\t\"m\",\n\t\t\t\t\tvalues.length + 1\n\t\t\t\t);\n\t\t\t\tvalues.push(...memberNarrowing.values);\n\n\t\t\t\tfromClause += ` LEFT JOIN \"${this._config.tableName}\" AS m ON ${[\n\t\t\t\t\t`m.\"${String(groupProperty)}\" = p.\"${String(groupProperty)}\"`,\n\t\t\t\t\t...members.whereClauses,\n\t\t\t\t\t...memberNarrowing.clauses\n\t\t\t\t].join(\" AND \")}`;\n\t\t\t\tjoinFromAlias = \"m\";\n\t\t\t}\n\n\t\t\tconst join = await joinConnector.buildJoinClause(\n\t\t\t\tString(joinOptions.joinProperty),\n\t\t\t\tjoinOptions.joinConditions,\n\t\t\t\t\"j\",\n\t\t\t\tjoinFromAlias,\n\t\t\t\tjoinColumn,\n\t\t\t\tvalues.length + 1\n\t\t\t);\n\t\t\tvalues.push(...join.values);\n\n\t\t\t// PostgreSQL returns a flat row, so each column is aliased by position and mapped back\n\t\t\t// afterwards rather than relying on the table it came from.\n\t\t\tconst selectClause = primary.columns\n\t\t\t\t.map((c, i) => `p.\"${c}\" AS \"p${i}\"`)\n\t\t\t\t.concat(joined.columns.map((c, i) => `j.\"${c}\" AS \"j${i}\"`))\n\t\t\t\t.join(\", \");\n\n\t\t\tconst outerOrderBy = keySetCols\n\t\t\t\t.map(c => `p.\"${c.prop}\" ${c.asc ? \"ASC\" : \"DESC\"}`)\n\t\t\t\t.concat(this.buildJoinOrderBy(joinOptions, \"j\"))\n\t\t\t\t.join(\", \");\n\n\t\t\tsql = `SELECT ${selectClause} FROM ${fromClause} LEFT JOIN \"${joinConnector._config.tableName}\" AS j ON ${join.clause} ORDER BY ${outerOrderBy}`;\n\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst rows = await dbConnection.unsafe(sql, values);\n\n\t\t\tconst groups = this.collectJoinRows(\n\t\t\t\trows as { [alias: string]: unknown }[],\n\t\t\t\tprimary.columns,\n\t\t\t\tjoined.columns,\n\t\t\t\tpkPropName,\n\t\t\t\tjoinedPrimaryKey\n\t\t\t);\n\n\t\t\tconst hasMore = groups.length > returnSize;\n\t\t\tconst pageGroups = hasMore ? groups.slice(0, returnSize) : groups;\n\n\t\t\tconst entities: (Partial<T> & { joined: Partial<U>[] })[] = [];\n\t\t\tfor (const group of pageGroups) {\n\t\t\t\tconst entity = this.prepareJoinEntity<T>(group.key, this._entitySchema, primary.internal);\n\t\t\t\tentities.push({\n\t\t\t\t\t...entity,\n\t\t\t\t\tjoined: group.joined.map(j =>\n\t\t\t\t\t\tthis.prepareJoinEntity<U>(j, joinConnector._entitySchema, joined.internal)\n\t\t\t\t\t)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlet nextCursor: string | undefined;\n\t\t\tif (hasMore && pageGroups.length > 0) {\n\t\t\t\tconst lastRow = pageGroups[pageGroups.length - 1].key;\n\t\t\t\tnextCursor = EntityStorageHelper.encodeCursor(\n\t\t\t\t\tnormalizedOptions,\n\t\t\t\t\tkeySetCols.map(c => lastRow[c.prop])\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn { entities, cursor: nextCursor };\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryJoinFailed\",\n\t\t\t\t{ sql },\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Build the clauses which narrow the rows a page is built from, beyond the plain conditions.\n\t * An inner join requires the row to have at least one joined entity, and a group condition\n\t * requires the group the row belongs to to hold an entity which matches it.\n\t * @param joinConnector The connector holding the entities to join to.\n\t * @param joinOptions The join configuration.\n\t * @param groupProperty The optional property the entities are grouped by.\n\t * @param partitionKey The partition key of this connector.\n\t * @param alias The alias of the row being narrowed.\n\t * @param startIndex The number the first placeholder takes.\n\t * @returns The clauses and their bound values.\n\t * @internal\n\t */\n\tprivate async buildNarrowingClauses<U>(\n\t\tjoinConnector: PostgreSqlEntityStorageConnector<U>,\n\t\tjoinOptions: IEntityStorageJoinOptions<T, U>,\n\t\tgroupProperty: keyof T | undefined,\n\t\tpartitionKey: string | undefined,\n\t\talias: string,\n\t\tstartIndex: number\n\t): Promise<{ clauses: string[]; values: ParameterOrJSON<never>[] }> {\n\t\tconst clauses: string[] = [];\n\t\tconst values: ParameterOrJSON<never>[] = [];\n\n\t\tif (joinOptions.joinRequired ?? false) {\n\t\t\tconst exists = await joinConnector.buildJoinExistsClause(\n\t\t\t\tString(joinOptions.joinProperty),\n\t\t\t\tjoinOptions.joinConditions,\n\t\t\t\t\"jx\",\n\t\t\t\talias,\n\t\t\t\tString(joinOptions.property),\n\t\t\t\tstartIndex + values.length\n\t\t\t);\n\t\t\tclauses.push(exists.clause);\n\t\t\tvalues.push(...exists.values);\n\t\t}\n\n\t\tif (!Is.empty(groupProperty) && Is.arrayValue(joinOptions.groupConditions)) {\n\t\t\tconst groupColumn = String(groupProperty);\n\t\t\tfor (let i = 0; i < joinOptions.groupConditions.length; i++) {\n\t\t\t\tconst memberAlias = `gx${i}`;\n\t\t\t\tconst group = this.buildWhereClause(\n\t\t\t\t\tjoinOptions.groupConditions[i],\n\t\t\t\t\tpartitionKey,\n\t\t\t\t\tmemberAlias,\n\t\t\t\t\tstartIndex + values.length\n\t\t\t\t);\n\t\t\t\tclauses.push(\n\t\t\t\t\t`EXISTS (SELECT 1 FROM \"${this._config.tableName}\" AS ${memberAlias} WHERE ${memberAlias}.\"${groupColumn}\" = ${alias}.\"${groupColumn}\" AND ${group.whereClauses.join(\" AND \")})`\n\t\t\t\t);\n\t\t\t\tvalues.push(...group.values);\n\t\t\t}\n\t\t}\n\n\t\treturn { clauses, values };\n\t}\n\n\t/**\n\t * Build the clause which requires a primary entity to have at least one joined entity. Called\n\t * on the connector holding the joined entities so its partition key and property types apply.\n\t * @param joinProperty The column on this connector's table to join to.\n\t * @param joinConditions The optional conditions to match for the joined entities.\n\t * @param alias The alias of the joined table inside the clause.\n\t * @param primaryAlias The alias of the primary entity being narrowed.\n\t * @param primaryColumn The column on the primary entity to join from.\n\t * @param startIndex The number the first placeholder takes.\n\t * @returns The clause and its bound values.\n\t * @internal\n\t */\n\tprivate async buildJoinExistsClause(\n\t\tjoinProperty: string,\n\t\tjoinConditions: EntityCondition<T> | undefined,\n\t\talias: string,\n\t\tprimaryAlias: string,\n\t\tprimaryColumn: string,\n\t\tstartIndex: number\n\t): Promise<{ clause: string; values: ParameterOrJSON<never>[] }> {\n\t\tconst partitionKey = await this.resolvePartitionKey();\n\t\tconst where = this.buildWhereClause(joinConditions, partitionKey, alias, startIndex);\n\n\t\treturn {\n\t\t\tclause: `EXISTS (SELECT 1 FROM \"${this._config.tableName}\" AS ${alias} WHERE ${alias}.\"${joinProperty}\" = ${primaryAlias}.\"${primaryColumn}\" AND ${where.whereClauses.join(\" AND \")})`,\n\t\t\tvalues: where.values\n\t\t};\n\t}\n\n\t/**\n\t * Build the ON clause which attaches the joined table, including its own partition key and any\n\t * conditions the caller supplied for the joined entities. Called on the connector holding the\n\t * joined entities so the partition key and the property types come from its own schema and\n\t * configuration.\n\t * @param joinProperty The column on this connector's table to join to.\n\t * @param joinConditions The optional conditions to match for the joined entities.\n\t * @param alias The alias of the joined table.\n\t * @param primaryAlias The alias of the table holding the primary entities.\n\t * @param primaryColumn The column on the primary table to join from.\n\t * @param startIndex The number the first placeholder takes.\n\t * @returns The ON clause and its bound values.\n\t * @internal\n\t */\n\tprivate async buildJoinClause(\n\t\tjoinProperty: string,\n\t\tjoinConditions: EntityCondition<T> | undefined,\n\t\talias: string,\n\t\tprimaryAlias: string,\n\t\tprimaryColumn: string,\n\t\tstartIndex: number\n\t): Promise<{ clause: string; values: ParameterOrJSON<never>[] }> {\n\t\tconst partitionKey = await this.resolvePartitionKey();\n\t\tconst where = this.buildWhereClause(joinConditions, partitionKey, alias, startIndex);\n\n\t\treturn {\n\t\t\tclause: [\n\t\t\t\t`${alias}.\"${joinProperty}\" = ${primaryAlias}.\"${primaryColumn}\"`,\n\t\t\t\t...where.whereClauses\n\t\t\t].join(\" AND \"),\n\t\t\tvalues: where.values\n\t\t};\n\t}\n\n\t/**\n\t * Build the ORDER BY fragments which order the joined entities within each primary entity.\n\t * @param joinOptions The join configuration.\n\t * @param alias The alias of the joined table.\n\t * @returns The order by fragments, empty when no sort order was requested.\n\t * @internal\n\t */\n\tprivate buildJoinOrderBy<U>(\n\t\tjoinOptions: IEntityStorageJoinOptions<T, U>,\n\t\talias: string\n\t): string[] {\n\t\treturn (joinOptions.joinSortProperties ?? []).map(\n\t\t\ts =>\n\t\t\t\t`${alias}.\"${String(s.property)}\" ${s.sortDirection === SortDirection.Ascending ? \"ASC\" : \"DESC\"}`\n\t\t);\n\t}\n\n\t/**\n\t * Build the ordered keySet columns used for the page order and the cursor, matching the\n\t * behaviour of query so both paginate the same way.\n\t * @param sortProperties The optional sort order.\n\t * @returns The ordered columns with their direction.\n\t * @internal\n\t */\n\tprivate buildKeySetColumns(\n\t\tsortProperties?: { property: keyof T; sortDirection: SortDirection }[]\n\t): { prop: string; asc: boolean }[] {\n\t\tconst pkPropName = String(this._primaryKeyProperty.property);\n\t\tconst keySetCols: { prop: string; asc: boolean }[] = [];\n\n\t\tfor (const sortProperty of sortProperties ?? []) {\n\t\t\tkeySetCols.push({\n\t\t\t\tprop: String(sortProperty.property),\n\t\t\t\tasc: sortProperty.sortDirection === SortDirection.Ascending\n\t\t\t});\n\t\t}\n\n\t\tif (!keySetCols.some(c => c.prop === pkPropName)) {\n\t\t\tkeySetCols.push({ prop: pkPropName, asc: true });\n\t\t}\n\n\t\treturn keySetCols;\n\t}\n\n\t/**\n\t * Build the keySet condition which continues the page from a previous cursor.\n\t * @param keySetCols The ordered keySet columns.\n\t * @param lastValues The key set values of the last entity of the previous page.\n\t * @param startIndex The number the first placeholder takes.\n\t * @returns The clauses and their bound values.\n\t * @internal\n\t */\n\tprivate buildKeySetClause(\n\t\tkeySetCols: { prop: string; asc: boolean }[],\n\t\tlastValues: unknown[] | undefined,\n\t\tstartIndex: number\n\t): { clauses: string[]; values: ParameterOrJSON<never>[] } {\n\t\tif (!Is.arrayValue(lastValues)) {\n\t\t\treturn { clauses: [], values: [] };\n\t\t}\n\n\t\tconst values: ParameterOrJSON<never>[] = [];\n\t\tconst orParts: string[] = [];\n\n\t\tfor (let i = 0; i < keySetCols.length; i++) {\n\t\t\tconst parts: string[] = [];\n\t\t\tfor (let j = 0; j < i; j++) {\n\t\t\t\tvalues.push(lastValues[j] as ParameterOrJSON<never>);\n\t\t\t\tparts.push(`\"${keySetCols[j].prop}\" = $${startIndex + values.length - 1}`);\n\t\t\t}\n\t\t\tconst op = keySetCols[i].asc ? \">\" : \"<\";\n\t\t\tvalues.push(lastValues[i] as ParameterOrJSON<never>);\n\t\t\tparts.push(`\"${keySetCols[i].prop}\" ${op} $${startIndex + values.length - 1}`);\n\t\t\torParts.push(parts.length === 1 ? parts[0] : `(${parts.join(\" AND \")})`);\n\t\t}\n\n\t\treturn { clauses: [`(${orParts.join(\" OR \")})`], values };\n\t}\n\n\t/**\n\t * Work out which columns to read for one side of the join, honouring the caller's projection\n\t * but adding the columns the join itself needs.\n\t * @param schema The schema of the entities being read.\n\t * @param properties The optional projection requested by the caller.\n\t * @param required The columns the join needs regardless of the projection.\n\t * @returns The columns to read and the ones which were only added internally.\n\t * @internal\n\t */\n\tprivate buildColumnSelection<E>(\n\t\tschema: IEntitySchema<E>,\n\t\tproperties: (keyof E)[] | undefined,\n\t\trequired: string[]\n\t): { columns: string[]; internal: string[] } {\n\t\tconst columns: string[] = [];\n\t\tconst internal: string[] = [];\n\n\t\tif (Is.arrayValue(properties)) {\n\t\t\tfor (const prop of properties) {\n\t\t\t\tconst column = String(prop);\n\t\t\t\tif (!columns.includes(column)) {\n\t\t\t\t\tcolumns.push(column);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const column of required) {\n\t\t\t\tif (!columns.includes(column)) {\n\t\t\t\t\tcolumns.push(column);\n\t\t\t\t\tinternal.push(column);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const prop of schema.properties ?? []) {\n\t\t\t\tconst column = String(prop.property);\n\t\t\t\tif (!columns.includes(column)) {\n\t\t\t\t\tcolumns.push(column);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { columns, internal };\n\t}\n\n\t/**\n\t * Collapse the flat rows returned by the join into one entry per primary entity, preserving the\n\t * order the database returned them in.\n\t * @param rows The rows from the join statement, whose columns are aliased by position.\n\t * @param primaryColumns The primary columns in the order they were aliased.\n\t * @param joinedColumns The joined columns in the order they were aliased.\n\t * @param identityColumn The column which identifies a primary entity.\n\t * @param joinedPrimaryKey The primary key column of the joined entities.\n\t * @returns One entry per primary entity with its joined entities.\n\t * @internal\n\t */\n\tprivate collectJoinRows(\n\t\trows: { [alias: string]: unknown }[],\n\t\tprimaryColumns: string[],\n\t\tjoinedColumns: string[],\n\t\tidentityColumn: string,\n\t\tjoinedPrimaryKey: string\n\t): { key: { [column: string]: unknown }; joined: { [column: string]: unknown }[] }[] {\n\t\tconst groups: {\n\t\t\tkey: { [column: string]: unknown };\n\t\t\tjoined: { [column: string]: unknown }[];\n\t\t}[] = [];\n\n\t\tif (!Is.array(rows)) {\n\t\t\treturn groups;\n\t\t}\n\n\t\tlet current:\n\t\t\t{ key: { [column: string]: unknown }; joined: { [column: string]: unknown }[] } | undefined;\n\t\tlet currentIdentity: string | undefined;\n\t\tlet seenJoined = new Set<string>();\n\n\t\tfor (const row of rows) {\n\t\t\tconst primaryRow: { [column: string]: unknown } = {};\n\t\t\tfor (let i = 0; i < primaryColumns.length; i++) {\n\t\t\t\tprimaryRow[primaryColumns[i]] = row[`p${i}`];\n\t\t\t}\n\n\t\t\tconst identity = this.rowKey(primaryRow[identityColumn]);\n\n\t\t\tif (Is.undefined(current) || identity !== currentIdentity) {\n\t\t\t\tcurrent = { key: primaryRow, joined: [] };\n\t\t\t\tcurrentIdentity = identity;\n\t\t\t\tseenJoined = new Set<string>();\n\t\t\t\tgroups.push(current);\n\t\t\t}\n\n\t\t\tconst joinedRow: { [column: string]: unknown } = {};\n\t\t\tfor (let i = 0; i < joinedColumns.length; i++) {\n\t\t\t\tjoinedRow[joinedColumns[i]] = row[`j${i}`];\n\t\t\t}\n\n\t\t\t// A left join with no match produces a row whose joined columns are all null, and the\n\t\t\t// same joined entity appears more than once when several primary rows in a group share\n\t\t\t// the same join value.\n\t\t\tif (!Is.empty(joinedRow[joinedPrimaryKey])) {\n\t\t\t\tconst joinedIdentity = this.rowKey(joinedRow[joinedPrimaryKey]);\n\t\t\t\tif (!seenJoined.has(joinedIdentity)) {\n\t\t\t\t\tseenJoined.add(joinedIdentity);\n\t\t\t\t\tcurrent.joined.push(joinedRow);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn groups;\n\t}\n\n\t/**\n\t * Turn a raw column value into a key which can be compared between rows.\n\t * @param value The value read from the storage.\n\t * @returns The key for the value.\n\t * @internal\n\t */\n\tprivate rowKey(value: unknown): string {\n\t\treturn Is.string(value) ? value : JSON.stringify(value);\n\t}\n\n\t/**\n\t * Apply to a row read by a join the same clean up a plain query applies to its entities, then\n\t * remove the columns which were only read to satisfy the join.\n\t * @param row The raw row read from the storage.\n\t * @param schema The schema of the entity.\n\t * @param internal The columns to remove.\n\t * @returns The entity.\n\t * @internal\n\t */\n\tprivate prepareJoinEntity<E>(\n\t\trow: { [column: string]: unknown },\n\t\tschema: IEntitySchema<E>,\n\t\tinternal: string[]\n\t): Partial<E> {\n\t\tconst prepared: { [column: string]: unknown } = { ...row };\n\n\t\tfor (const prop of schema.properties ?? []) {\n\t\t\tconst column = String(prop.property);\n\t\t\tif (\n\t\t\t\t(prop.type === EntitySchemaPropertyType.Object ||\n\t\t\t\t\tprop.type === EntitySchemaPropertyType.Array) &&\n\t\t\t\tIs.string(prepared[column])\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tprepared[column] = JSON.parse(String(prepared[column]));\n\t\t\t\t} catch {\n\t\t\t\t\t// Text which is not JSON is left as it was read, matching what a plain query does.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn EntityStorageHelper.unPrepareEntity<E>(prepared as Partial<E>, [\n\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t...internal\n\t\t]);\n\t}\n\n\t/**\n\t * Get the partition key for the current context.\n\t * @returns The partition key, or undefined when the connector is not partitioned.\n\t * @internal\n\t */\n\tprivate async resolvePartitionKey(): Promise<string | undefined> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\treturn ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t}\n\n\t/**\n\t * Qualify a column with a table alias, needed when the statement reads from more than one table.\n\t * @param column The column name.\n\t * @param tableAlias The optional table alias.\n\t * @returns The quoted column, prefixed with the alias when one was supplied.\n\t * @internal\n\t */\n\tprivate qualifiedColumn(column: string, tableAlias?: string): string {\n\t\treturn Is.stringValue(tableAlias) ? `${tableAlias}.\"${column}\"` : `\"${column}\"`;\n\t}\n\n\t/**\n\t * Check if the database exists.\n\t * @param adminClient The server-level connection to use for the check.\n\t * @returns True if the database exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async databaseExists(adminClient: postgres.Sql): Promise<boolean> {\n\t\ttry {\n\t\t\tconst res = await adminClient.unsafe(\n\t\t\t\t\"SELECT datname FROM pg_catalog.pg_database WHERE datname = $1\",\n\t\t\t\t[this._config.database] as postgres.ParameterOrJSON<never>[]\n\t\t\t);\n\t\t\treturn res.length > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a database to exist.\n\t * @param adminClient The server-level connection to use for the check.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForDatabaseExists(adminClient: postgres.Sql): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst databaseExists = await this.databaseExists(adminClient);\n\t\t\tif (databaseExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Ensure the secondary index for a property exists, dropping a legacy-named index if present.\n\t * Every query is scoped to a single partition, so the index leads with the partition key and\n\t * the property follows it, letting one index serve both the partition filter and the sort.\n\t * @param dbConnection The connection to query with.\n\t * @param indexes The indexes already on the table, keyed by index name.\n\t * @param prop The indexed property.\n\t * @param nodeLogging Optional logging component.\n\t * @internal\n\t */\n\tprivate async ensureIndex(\n\t\tdbConnection: postgres.Sql,\n\t\tindexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } },\n\t\tprop: IEntitySchemaProperty<T>,\n\t\tnodeLogging?: ILoggingComponent\n\t): Promise<void> {\n\t\tconst columnName = String(prop.property);\n\t\tconst indexName = IndexHelper.generateName(this._config.tableName, columnName);\n\t\tconst keyColumns = [PostgreSqlEntityStorageConnector._PARTITION_KEY, columnName];\n\n\t\tif (!this.isIndexCovered(indexes, keyColumns)) {\n\t\t\t// An index of ours under the same name but with a different shape predates the partition\n\t\t\t// key leading the key columns, so it has to be replaced rather than left in place.\n\t\t\tif (!Is.empty(indexes[indexName])) {\n\t\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${indexName}\"`);\n\t\t\t}\n\n\t\t\tawait dbConnection.unsafe(\n\t\t\t\t`CREATE INDEX IF NOT EXISTS \"${indexName}\" ON \"${this._config.tableName}\" (\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\", \"${columnName}\")`\n\t\t\t);\n\t\t}\n\n\t\t// TODO: remove the legacy index handling once every installation has bootstrapped on a release that contains it\n\t\tconst legacyName = IndexHelper.generateLegacyName(\n\t\t\tthis._config.tableName,\n\t\t\tcolumnName,\n\t\t\tIndexHelper.DEFAULT_MAX_IDENTIFIER_LENGTH\n\t\t);\n\t\tconst legacyIndex = indexes[legacyName];\n\n\t\t// The connector's own legacy indexes were always non-unique and single-column, anything else is an operator's\n\t\tif (!Is.empty(legacyIndex) && legacyIndex.nonUnique && legacyIndex.columns.length === 1) {\n\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${legacyName}\"`);\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: PostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"legacyIndexDropped\",\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName,\n\t\t\t\t\tindexName: legacyName,\n\t\t\t\t\tnewIndexName: indexName\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Ensure the composite index for a schema index group exists.\n\t * A group needs at least two properties to form a composite index, otherwise it is skipped.\n\t * The partition key leads the index for the same reason it leads a single property index.\n\t * @param dbConnection The connection to query with.\n\t * @param indexes The indexes already on the table, keyed by index name.\n\t * @param indexProperties The properties in the group, ordered by their index position.\n\t * @internal\n\t */\n\tprivate async ensureCompositeIndex(\n\t\tdbConnection: postgres.Sql,\n\t\tindexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } },\n\t\tindexProperties: { property: IEntitySchemaProperty<T>; direction: SortDirection }[]\n\t): Promise<void> {\n\t\tconst indexName = IndexHelper.generateCompositeName(this._config.tableName, indexProperties);\n\t\tconst keyColumns = [\n\t\t\tPostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\t...indexProperties.map(indexProperty => String(indexProperty.property.property))\n\t\t];\n\n\t\tif (this.isIndexCovered(indexes, keyColumns)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// An index of ours under the same name but with a different shape predates the partition\n\t\t// key leading the key columns, so it has to be replaced rather than left in place.\n\t\tif (!Is.empty(indexes[indexName])) {\n\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${indexName}\"`);\n\t\t}\n\n\t\tconst indexCols = [\n\t\t\t`\"${PostgreSqlEntityStorageConnector._PARTITION_KEY}\" ASC`,\n\t\t\t...indexProperties.map(\n\t\t\t\tindexProperty =>\n\t\t\t\t\t`\"${String(indexProperty.property.property)}\" ${indexProperty.direction === SortDirection.Descending ? \"DESC\" : \"ASC\"}`\n\t\t\t)\n\t\t].join(\", \");\n\n\t\tawait dbConnection.unsafe(\n\t\t\t`CREATE INDEX IF NOT EXISTS \"${indexName}\" ON \"${this._config.tableName}\" (${indexCols})`\n\t\t);\n\t}\n\n\t/**\n\t * Read the key columns of every usable index on the table, in key order.\n\t * @param dbConnection The connection to query with.\n\t * @returns The key columns and uniqueness of each index, keyed by index name.\n\t * @internal\n\t */\n\tprivate async readIndexes(\n\t\tdbConnection: postgres.Sql\n\t): Promise<{ [indexName: string]: { columns: string[]; nonUnique: boolean } }> {\n\t\tconst indexRows = await dbConnection.unsafe(\n\t\t\t`SELECT i.relname AS \"indexName\", a.attname AS \"columnName\", k.pos AS \"position\", ix.indisunique AS \"isUnique\"\n\t\t\tFROM pg_index ix\n\t\t\tJOIN pg_class t ON t.oid = ix.indrelid\n\t\t\tJOIN pg_namespace n ON n.oid = t.relnamespace\n\t\t\tJOIN pg_class i ON i.oid = ix.indexrelid\n\t\t\tJOIN pg_am am ON am.oid = i.relam\n\t\t\tJOIN LATERAL generate_series(0, ix.indnkeyatts - 1) AS k(pos) ON true\n\t\t\tJOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ix.indkey[k.pos]\n\t\t\tWHERE n.nspname = 'public'\n\t\t\t\tAND t.relname = $1\n\t\t\t\tAND ix.indisvalid\n\t\t\t\tAND ix.indisready\n\t\t\t\tAND ix.indpred IS NULL\n\t\t\t\tAND am.amname = 'btree'\n\t\t\tORDER BY i.relname, k.pos`,\n\t\t\t[this._config.tableName] as ParameterOrJSON<never>[]\n\t\t);\n\n\t\tconst indexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } } = {};\n\n\t\tfor (const row of indexRows) {\n\t\t\tconst indexName = ObjectHelper.propertyGet<string>(row, \"indexName\");\n\t\t\tconst columnName = ObjectHelper.propertyGet<string>(row, \"columnName\");\n\t\t\tconst position = Coerce.integer(ObjectHelper.propertyGet(row, \"position\"));\n\n\t\t\tif (Is.stringValue(indexName) && Is.stringValue(columnName) && Is.integer(position)) {\n\t\t\t\tindexes[indexName] ??= {\n\t\t\t\t\tcolumns: [],\n\t\t\t\t\tnonUnique: ObjectHelper.propertyGet(row, \"isUnique\") === false\n\t\t\t\t};\n\t\t\t\t// An expression key has no column to join to, leaving a hole which stops the\n\t\t\t\t// index from matching any key column list beyond that position.\n\t\t\t\tindexes[indexName].columns[position] = columnName;\n\t\t\t}\n\t\t}\n\n\t\treturn indexes;\n\t}\n\n\t/**\n\t * Check if any of the indexes already starts with the given key columns.\n\t * @param indexes The indexes on the table, keyed by index name.\n\t * @param keyColumns The leading key columns the index must have, in order.\n\t * @returns True if an index already leads with the key columns.\n\t * @internal\n\t */\n\tprivate isIndexCovered(\n\t\tindexes: { [indexName: string]: { columns: string[]; nonUnique: boolean } },\n\t\tkeyColumns: string[]\n\t): boolean {\n\t\treturn Object.values(indexes).some(index =>\n\t\t\tkeyColumns.every((keyColumn, position) => index.columns[position] === keyColumn)\n\t\t);\n\t}\n\n\t/**\n\t * Check if the table exists.\n\t * @returns True if the table exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async tableExists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\t\t\tconst res = await dbConnection.unsafe(\n\t\t\t\t\"SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1 LIMIT 1\",\n\t\t\t\t[this._config.tableName] as postgres.ParameterOrJSON<never>[]\n\t\t\t);\n\t\t\treturn res.length > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a table to exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForTableExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst tableExists = await this.tableExists();\n\t\t\tif (tableExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a table to not exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForTableNotExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst tableExists = await this.tableExists();\n\t\t\tif (!tableExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Retrieve (or lazily create) the shared postgres connection for this endpoint and database.\n\t * @returns The shared connection.\n\t * @internal\n\t */\n\tprivate async getClient(): Promise<postgres.Sql> {\n\t\treturn ConnectionHelper.openClient<postgres.Sql>(\n\t\t\t\"postgreSqlConnections\",\n\t\t\tthis.createClientId(),\n\t\t\tthis._instanceId,\n\t\t\tthis._mutexTimeoutMs,\n\t\t\tasync () => postgres(this.createConnectionConfig())\n\t\t);\n\t}\n\n\t/**\n\t * Build a stable cache key for the shared client based on connection parameters.\n\t * @returns The cache key.\n\t * @internal\n\t */\n\tprivate createClientId(): string {\n\t\treturn `${this._config.host}|${this._config.port ?? 5432}|${this._config.user}|${this._config.database}`;\n\t}\n\n\t/**\n\t * Create a new DB connection configuration.\n\t * @param includeDatabase Whether to include the database name in the options.\n\t * @returns The PostgreSql connection configuration.\n\t * @internal\n\t */\n\tprivate createConnectionConfig(\n\t\tincludeDatabase: boolean = true\n\t): postgres.Options<{ [key: string]: postgres.PostgresType }> {\n\t\tconst opts: { [key: string]: unknown } = {\n\t\t\thost: this._config.host,\n\t\t\tport: this._config.port ?? 5432,\n\t\t\tuser: this._config.user,\n\t\t\tpassword: this._config.password,\n\t\t\tmax: this._config?.pool?.max,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tidle_timeout: this._config?.pool?.idleTimeout,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tconnect_timeout: this._config?.pool?.connectTimeout,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tmax_lifetime: this._config?.pool?.maxLifetime,\n\t\t\t// The driver returns BIGINT (int64/uint64 properties) as a string, the schema expects a number.\n\t\t\ttypes: {\n\t\t\t\tbigint: {\n\t\t\t\t\tto: 20,\n\t\t\t\t\tfrom: [20],\n\t\t\t\t\tserialize: (value: number | bigint): string => value.toString(),\n\t\t\t\t\tparse: (value: string): number => Number(value)\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tif (includeDatabase) {\n\t\t\topts.database = this._config.database;\n\t\t}\n\t\treturn opts;\n\t}\n\n\t/**\n\t * Build where clause arrays for a query, combining partition key and optional conditions.\n\t * @param conditions The optional entity conditions to include.\n\t * @param partitionKey The partition key value.\n\t * @param tableAlias The optional table alias to qualify the columns with, needed when the\n\t * clauses are used in a statement which reads from more than one table.\n\t * @param startIndex The number the first placeholder takes, so clauses can be added to a\n\t * statement which already holds values.\n\t * @returns The where clauses and bound values.\n\t * @internal\n\t */\n\tprivate buildWhereClause(\n\t\tconditions: EntityCondition<T> | undefined,\n\t\tpartitionKey: string | undefined,\n\t\ttableAlias?: string,\n\t\tstartIndex: number = 1\n\t): { whereClauses: string[]; values: ParameterOrJSON<never>[] } {\n\t\tconst whereClauses: string[] = [];\n\t\tconst values: ParameterOrJSON<never>[] = [];\n\n\t\tconst finalConditions: EntityCondition<T> = {\n\t\t\tconditions: [],\n\t\t\tlogicalOperator: LogicalOperator.And\n\t\t};\n\n\t\tfinalConditions.conditions.push({\n\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY,\n\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\tvalue: partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t});\n\n\t\tif (!Is.empty(conditions)) {\n\t\t\tfinalConditions.conditions.push(conditions);\n\t\t}\n\n\t\tthis.buildQueryParameters(\"\", finalConditions, whereClauses, values, startIndex, tableAlias);\n\n\t\treturn { whereClauses, values };\n\t}\n\n\t/**\n\t * Create an SQL condition clause.\n\t * @param objectPath The path for the nested object.\n\t * @param condition The conditions to create the query from.\n\t * @param whereClauses The where clauses to use in the query.\n\t * @param values The values to use in the query.\n\t * @param valueIndex The current value index.\n\t * @param tableAlias The optional table alias to qualify the columns with.\n\t * @internal\n\t */\n\tprivate buildQueryParameters(\n\t\tobjectPath: string,\n\t\tcondition: EntityCondition<T> | undefined,\n\t\twhereClauses: string[],\n\t\tvalues: unknown[],\n\t\tvalueIndex: number,\n\t\ttableAlias?: string\n\t): void {\n\t\tif (Is.undefined(condition)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\tif (condition.conditions.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst joinConditions: string[] = condition.conditions.map(c => {\n\t\t\t\tconst subWhereClauses: string[] = [];\n\t\t\t\tconst subValues: unknown[] = [];\n\t\t\t\tthis.buildQueryParameters(\n\t\t\t\t\tobjectPath,\n\t\t\t\t\tc,\n\t\t\t\t\tsubWhereClauses,\n\t\t\t\t\tsubValues,\n\t\t\t\t\tvalueIndex,\n\t\t\t\t\ttableAlias\n\t\t\t\t);\n\t\t\t\tvalues.push(...subValues);\n\t\t\t\tvalueIndex += subValues.length;\n\t\t\t\treturn subWhereClauses.join(\" AND \");\n\t\t\t});\n\n\t\t\tconst logicalOperator = this.mapConditionalOperator(condition.logicalOperator);\n\t\t\tconst queryClause = joinConditions.filter(j => j.length > 0).join(` ${logicalOperator} `);\n\n\t\t\tif (queryClause.length > 0) {\n\t\t\t\twhereClauses.push(`(${queryClause})`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst schemaProp = this._entitySchema.properties?.find(p => p.property === condition.property);\n\t\tconst comparison = this.mapComparisonOperator(\n\t\t\tobjectPath,\n\t\t\tcondition,\n\t\t\tschemaProp?.type,\n\t\t\tvalues,\n\t\t\tvalueIndex,\n\t\t\ttableAlias\n\t\t);\n\t\twhereClauses.push(comparison);\n\t}\n\n\t/**\n\t * Map the framework comparison operators to those in MySQL.\n\t * @param objectPath The prefix to use for the condition.\n\t * @param comparator The operator to map.\n\t * @param type The type of the property.\n\t * @param values The values to use in the query.\n\t * @param valueIndex The current value index.\n\t * @param tableAlias The optional table alias to qualify the columns with.\n\t * @returns The comparison expression.\n\t * @throws GeneralError if the comparison operator is not supported.\n\t * @internal\n\t */\n\tprivate mapComparisonOperator(\n\t\tobjectPath: string,\n\t\tcomparator: IComparator,\n\t\ttype: EntitySchemaPropertyType | undefined,\n\t\tvalues: unknown[],\n\t\tvalueIndex: number,\n\t\ttableAlias?: string\n\t): string {\n\t\tlet prop = objectPath;\n\t\tif (prop.length > 0) {\n\t\t\tprop += \".\";\n\t\t}\n\n\t\tprop += comparator.property;\n\n\t\tif (comparator.comparison === ComparisonOperator.In) {\n\t\t\tconst inValues = Is.array(comparator.value) ? comparator.value : [comparator.value];\n\t\t\tif (inValues.length === 0) {\n\t\t\t\t// PostgreSQL rejects `IN ()` as a syntax error - short-circuit to a condition\n\t\t\t\t// that is always false so the query returns zero rows cleanly (#141).\n\t\t\t\treturn \"1 = 0\";\n\t\t\t}\n\t\t\tvalues.push(...inValues.map(val => this.propertyToDbValue(val, type)));\n\t\t\tconst placeholders = inValues.map((value, index) => `$${valueIndex + index}`).join(\", \");\n\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} IN (${placeholders})`;\n\t\t}\n\n\t\t// null/undefined must use IS NULL / IS NOT NULL - never a parameterised placeholder.\n\t\t// Passing undefined through propertyToDbValue() coerces it to NaN for number fields\n\t\t// (Number(undefined) === NaN), and null coerces to 0 (Number(null) === 0), both of\n\t\t// which produce semantically wrong or invalid SQL.\n\t\tif (comparator.value === null || comparator.value === undefined) {\n\t\t\tif (\n\t\t\t\tcomparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals\n\t\t\t) {\n\t\t\t\tconst nullCheck =\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.Equals ? \"IS NULL\" : \"IS NOT NULL\";\n\n\t\t\t\tif (comparator.property.split(\".\").length > 1) {\n\t\t\t\t\tconst rootProp = comparator.property.split(\".\")[0];\n\t\t\t\t\tconst nestedParts = comparator.property.split(\".\").slice(1);\n\t\t\t\t\tconst jsonPath = nestedParts\n\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->> '${p}'` : `-> '${p}'`))\n\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\tconst jsonTextExpr = `(${this.qualifiedColumn(rootProp, tableAlias)}::jsonb ${jsonPath})`;\n\t\t\t\t\treturn `${jsonTextExpr} ${nullCheck}`;\n\t\t\t\t}\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} ${nullCheck}`;\n\t\t\t}\n\t\t}\n\n\t\tconst dbValue = this.propertyToDbValue(comparator.value, type);\n\t\tvalues.push(dbValue);\n\n\t\tif (comparator.property.split(\".\").length > 1) {\n\t\t\tconst rootProp = comparator.property.split(\".\")[0];\n\t\t\tconst nestedParts = comparator.property.split(\".\").slice(1);\n\t\t\tconst rootSchema = this._entitySchema.properties?.find(p => p.property === rootProp);\n\t\t\tconst isArray = rootSchema?.type === EntitySchemaPropertyType.Array;\n\t\t\tconst jsonPath = nestedParts\n\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->> '${p}'` : `-> '${p}'`))\n\t\t\t\t.join(\"\");\n\t\t\tconst jsonTextExpr = `(${this.qualifiedColumn(rootProp, tableAlias)}::jsonb ${jsonPath})`;\n\n\t\t\tswitch (comparator.comparison) {\n\t\t\t\tcase ComparisonOperator.Includes: {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`%${String(comparator.value)}%`);\n\t\t\t\t\tif (isArray) {\n\t\t\t\t\t\tconst elemPath = nestedParts\n\t\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->>'${p}'` : `->'${p}'`))\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\t\treturn `EXISTS (SELECT 1 FROM jsonb_array_elements(${this.qualifiedColumn(rootProp, tableAlias)}) elem WHERE elem${elemPath} LIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `${jsonTextExpr} LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tcase ComparisonOperator.NotIncludes: {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`%${String(comparator.value)}%`);\n\t\t\t\t\tif (isArray) {\n\t\t\t\t\t\tconst elemPath = nestedParts\n\t\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->>'${p}'` : `->'${p}'`))\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\t\treturn `NOT EXISTS (SELECT 1 FROM jsonb_array_elements(${this.qualifiedColumn(rootProp, tableAlias)}) elem WHERE elem${elemPath} LIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `${jsonTextExpr} NOT LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tcase ComparisonOperator.StartsWith: {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`${this.escapeLike(String(comparator.value))}%`);\n\t\t\t\t\tif (isArray) {\n\t\t\t\t\t\tconst elemPath = nestedParts\n\t\t\t\t\t\t\t.map((p, i, arr) => (i === arr.length - 1 ? `->>'${p}'` : `->'${p}'`))\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\t\treturn `EXISTS (SELECT 1 FROM jsonb_array_elements(${this.qualifiedColumn(rootProp, tableAlias)}) elem WHERE elem${elemPath} LIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `${jsonTextExpr} LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tcase ComparisonOperator.NotEquals:\n\t\t\t\t\treturn `${jsonTextExpr} <> $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.GreaterThan:\n\t\t\t\t\treturn `${jsonTextExpr} > $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.LessThan:\n\t\t\t\t\treturn `${jsonTextExpr} < $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.GreaterThanOrEqual:\n\t\t\t\t\treturn `${jsonTextExpr} >= $${valueIndex}`;\n\t\t\t\tcase ComparisonOperator.LessThanOrEqual:\n\t\t\t\t\treturn `${jsonTextExpr} <= $${valueIndex}`;\n\t\t\t\tdefault:\n\t\t\t\t\treturn `${jsonTextExpr} = $${valueIndex}`;\n\t\t\t}\n\t\t}\n\n\t\tswitch (comparator.comparison) {\n\t\t\tcase ComparisonOperator.Equals:\n\t\t\t\tif (Is.object(comparator.value) || Is.array(comparator.value)) {\n\t\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} = $${valueIndex}::jsonb`;\n\t\t\t\t}\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} = $${valueIndex}`;\n\t\t\tcase ComparisonOperator.NotEquals:\n\t\t\t\tif (Is.object(comparator.value) || Is.array(comparator.value)) {\n\t\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} != $${valueIndex}::jsonb`;\n\t\t\t\t}\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} <> $${valueIndex}`;\n\t\t\tcase ComparisonOperator.GreaterThan:\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} > $${valueIndex}`;\n\t\t\tcase ComparisonOperator.LessThan:\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} < $${valueIndex}`;\n\t\t\tcase ComparisonOperator.GreaterThanOrEqual:\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} >= $${valueIndex}`;\n\t\t\tcase ComparisonOperator.LessThanOrEqual:\n\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} <= $${valueIndex}`;\n\t\t\tcase ComparisonOperator.Includes: {\n\t\t\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} LIKE '%' || $${valueIndex} || '%'`;\n\t\t\t\t}\n\t\t\t\tif (type === EntitySchemaPropertyType.Array || type === EntitySchemaPropertyType.Object) {\n\t\t\t\t\treturn `EXISTS (SELECT 1 FROM jsonb_array_elements(${this.qualifiedColumn(prop, tableAlias)}) elem WHERE elem @> $${valueIndex}::jsonb)`;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase ComparisonOperator.NotIncludes: {\n\t\t\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} NOT LIKE '%' || $${valueIndex} || '%'`;\n\t\t\t\t}\n\t\t\t\tif (type === EntitySchemaPropertyType.Array || type === EntitySchemaPropertyType.Object) {\n\t\t\t\t\treturn `NOT EXISTS (SELECT 1 FROM jsonb_array_elements(${this.qualifiedColumn(prop, tableAlias)}) elem WHERE elem @> $${valueIndex}::jsonb)`;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase ComparisonOperator.StartsWith: {\n\t\t\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\t\t\tvalues.pop();\n\t\t\t\t\tvalues.push(`${this.escapeLike(String(comparator.value))}%`);\n\t\t\t\t\treturn `${this.qualifiedColumn(prop, tableAlias)} LIKE $${valueIndex}`;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"comparisonNotSupported\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcomparison: comparator.comparison\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Escape the LIKE wildcard characters in a value so they match literally.\n\t * @param value The value to escape.\n\t * @returns The escaped value.\n\t * @internal\n\t */\n\tprivate escapeLike(value: string): string {\n\t\treturn value.replace(/[\\\\%_]/g, \"\\\\$&\");\n\t}\n\n\t/**\n\t * Format a value to insert into DB.\n\t * @param value The value to format.\n\t * @param type The type for the property.\n\t * @returns The value after conversion.\n\t * @internal\n\t */\n\tprivate propertyToDbValue(value: unknown, type?: EntitySchemaPropertyType): unknown {\n\t\tif (type === EntitySchemaPropertyType.String) {\n\t\t\treturn String(value);\n\t\t} else if (type === EntitySchemaPropertyType.Number) {\n\t\t\treturn Number(value);\n\t\t} else if (type === EntitySchemaPropertyType.Boolean) {\n\t\t\treturn Boolean(value);\n\t\t} else if (\n\t\t\ttype === EntitySchemaPropertyType.Object ||\n\t\t\ttype === EntitySchemaPropertyType.Array\n\t\t) {\n\t\t\treturn value;\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Map the framework conditional operators to those in MySQL.\n\t * @param operator The operator to map.\n\t * @returns The conditional operator.\n\t * @throws GeneralError if the conditional operator is not supported.\n\t * @internal\n\t */\n\tprivate mapConditionalOperator(operator?: LogicalOperator): string {\n\t\tif ((operator ?? LogicalOperator.And) === LogicalOperator.And) {\n\t\t\treturn \"AND\";\n\t\t} else if (operator === LogicalOperator.Or) {\n\t\t\treturn \"OR\";\n\t\t}\n\n\t\tthrow new GeneralError(PostgreSqlEntityStorageConnector.CLASS_NAME, \"conditionalNotSupported\", {\n\t\t\toperator\n\t\t});\n\t}\n\n\t/**\n\t * Verify the conditions for the entity.\n\t * @param conditions The conditions to verify.\n\t * @param obj The object to verify the conditions against.\n\t * @returns True if all conditions are met, false otherwise.\n\t * @internal\n\t */\n\tprivate verifyConditions(\n\t\tconditions: { property: keyof T; value: unknown }[],\n\t\tobj: { [key in keyof T]: unknown }\n\t): boolean {\n\t\treturn conditions.every(\n\t\t\tcondition => ObjectHelper.propertyGet(obj, condition.property as string) === condition.value\n\t\t);\n\t}\n\n\t/**\n\t * Build a mutex key for optimistic-locking critical sections.\n\t * @param partitionKey The resolved partition key.\n\t * @param id The entity id.\n\t * @returns The mutex key.\n\t * @internal\n\t */\n\tprivate buildOptimisticMutexKey(partitionKey: string | undefined, id: string): string {\n\t\treturn `${PostgreSqlEntityStorageConnector.CLASS_NAME}:optimistic:${this._config.tableName}:${partitionKey ?? PostgreSqlEntityStorageConnector._PARTITION_KEY_VALUE}:${id}`;\n\t}\n\n\t/**\n\t * Map entity schema properties to SQL properties.\n\t * @param entitySchema The schema of the entity.\n\t * @returns The SQL properties as a string.\n\t * @throws GeneralError if the entity properties do not exist.\n\t * @internal\n\t */\n\tprivate mapPostgreSqlProperties(entitySchema: IEntitySchema<T>): string {\n\t\tconst sqlTypeMap: { [key in EntitySchemaPropertyType]: string } = {\n\t\t\t[EntitySchemaPropertyType.String]: \"TEXT\",\n\t\t\t[EntitySchemaPropertyType.Number]: \"REAL\",\n\t\t\t[EntitySchemaPropertyType.Integer]: \"INTEGER\",\n\t\t\t[EntitySchemaPropertyType.Object]: \"JSONB\",\n\t\t\t[EntitySchemaPropertyType.Array]: \"JSONB\",\n\t\t\t[EntitySchemaPropertyType.Boolean]: \"BOOLEAN\"\n\t\t};\n\n\t\tif (!entitySchema.properties) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tPostgreSqlEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"entitySchemaPropertiesUndefined\"\n\t\t\t);\n\t\t}\n\n\t\tconst primaryKeys: string[] = [];\n\n\t\tconst props: IEntitySchemaProperty<T>[] = [...entitySchema.properties];\n\n\t\tprops.unshift({\n\t\t\tproperty: PostgreSqlEntityStorageConnector._PARTITION_KEY as keyof T,\n\t\t\ttype: EntitySchemaPropertyType.String,\n\t\t\tmaxLength: PostgreSqlEntityStorageConnector._PARTITION_KEY_MAX_LENGTH,\n\t\t\toptional: false,\n\t\t\tisPrimary: true\n\t\t});\n\n\t\tconst columnDefinitions = props\n\t\t\t.map(prop => {\n\t\t\t\tlet sqlType = sqlTypeMap[prop.type] || \"TEXT\";\n\t\t\t\tif (prop.format) {\n\t\t\t\t\tswitch (prop.type) {\n\t\t\t\t\t\tcase EntitySchemaPropertyType.String:\n\t\t\t\t\t\t\tswitch (prop.format) {\n\t\t\t\t\t\t\t\tcase \"uuid\":\n\t\t\t\t\t\t\t\t\tsqlType = \"UUID\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EntitySchemaPropertyType.Number:\n\t\t\t\t\t\t\tswitch (prop.format) {\n\t\t\t\t\t\t\t\tcase \"float\":\n\t\t\t\t\t\t\t\t\tsqlType = \"REAL\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"double\":\n\t\t\t\t\t\t\t\t\tsqlType = \"DOUBLE PRECISION\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EntitySchemaPropertyType.Integer:\n\t\t\t\t\t\t\tswitch (prop.format) {\n\t\t\t\t\t\t\t\tcase \"int8\":\n\t\t\t\t\t\t\t\tcase \"uint8\":\n\t\t\t\t\t\t\t\t\tsqlType = \"SMALLINT\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"int16\":\n\t\t\t\t\t\t\t\t\tsqlType = \"SMALLINT\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"uint16\":\n\t\t\t\t\t\t\t\tcase \"int32\":\n\t\t\t\t\t\t\t\t\tsqlType = \"INTEGER\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"uint32\":\n\t\t\t\t\t\t\t\tcase \"int64\":\n\t\t\t\t\t\t\t\tcase \"uint64\":\n\t\t\t\t\t\t\t\t\tsqlType = \"BIGINT\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// An explicit maxLength always wins, otherwise a format default only applies when the\n\t\t\t\t// format did not already map to a dedicated column type such as UUID.\n\t\t\t\tconst formatMaxLength =\n\t\t\t\t\tsqlType === \"TEXT\" && Is.stringValue(prop.format)\n\t\t\t\t\t\t? EntitySchemaHelper.FORMAT_MAX_LENGTHS[prop.format]\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst maxLength = prop.maxLength ?? formatMaxLength;\n\n\t\t\t\tif (\n\t\t\t\t\tprop.type === EntitySchemaPropertyType.String &&\n\t\t\t\t\tIs.integer(maxLength) &&\n\t\t\t\t\tmaxLength > 0 &&\n\t\t\t\t\tmaxLength <= PostgreSqlEntityStorageConnector._MAX_VARCHAR_LENGTH\n\t\t\t\t) {\n\t\t\t\t\tsqlType = `VARCHAR(${maxLength})`;\n\t\t\t\t}\n\n\t\t\t\tconst columnName = String(prop.property);\n\t\t\t\tconst nullable = prop.optional ? \" NULL\" : \" NOT NULL\";\n\n\t\t\t\tif (prop.isPrimary) {\n\t\t\t\t\tprimaryKeys.push(columnName);\n\t\t\t\t}\n\n\t\t\t\treturn `\"${columnName}\" ${sqlType}${nullable}`;\n\t\t\t})\n\t\t\t.join(\", \");\n\n\t\tconst primaryKeyDefinition =\n\t\t\tprimaryKeys.length > 0 ? `, PRIMARY KEY (\"${primaryKeys.join('\", \"')}\")` : \"\";\n\t\treturn columnDefinitions + primaryKeyDefinition;\n\t}\n}\n"]}
|