@twin.org/entity-storage-connector-postgresql 0.9.2 → 0.9.3-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -116,32 +116,38 @@ export class PostgreSqlEntityStorageConnector {
116
116
  async bootstrap(nodeLoggingComponentType) {
117
117
  const nodeLogging = ComponentFactory.getIfExists(nodeLoggingComponentType);
118
118
  try {
119
- const dbConnection = await this.getClient();
120
- const databaseExists = await this.databaseExists();
121
- if (!databaseExists) {
122
- await nodeLogging?.log({
123
- level: "info",
124
- source: PostgreSqlEntityStorageConnector.CLASS_NAME,
125
- ts: Date.now(),
126
- message: "databaseCreating",
127
- data: {
128
- databaseName: this._config.database
129
- }
130
- });
131
- await dbConnection.unsafe(`CREATE DATABASE "${this._config.database}";`);
132
- await this.waitForDatabaseExists();
119
+ const adminClient = postgres(this.createConnectionConfig(false));
120
+ try {
121
+ const databaseExists = await this.databaseExists(adminClient);
122
+ if (!databaseExists) {
123
+ await nodeLogging?.log({
124
+ level: "info",
125
+ source: PostgreSqlEntityStorageConnector.CLASS_NAME,
126
+ ts: Date.now(),
127
+ message: "databaseCreating",
128
+ data: {
129
+ databaseName: this._config.database
130
+ }
131
+ });
132
+ await adminClient.unsafe(`CREATE DATABASE "${this._config.database}";`);
133
+ await this.waitForDatabaseExists(adminClient);
134
+ }
135
+ else {
136
+ await nodeLogging?.log({
137
+ level: "info",
138
+ source: PostgreSqlEntityStorageConnector.CLASS_NAME,
139
+ ts: Date.now(),
140
+ message: "databaseExists",
141
+ data: {
142
+ databaseName: this._config.database
143
+ }
144
+ });
145
+ }
133
146
  }
134
- else {
135
- await nodeLogging?.log({
136
- level: "info",
137
- source: PostgreSqlEntityStorageConnector.CLASS_NAME,
138
- ts: Date.now(),
139
- message: "databaseExists",
140
- data: {
141
- databaseName: this._config.database
142
- }
143
- });
147
+ finally {
148
+ await adminClient.end();
144
149
  }
150
+ const dbConnection = await this.getClient();
145
151
  const tableExists = await this.tableExists();
146
152
  if (!tableExists) {
147
153
  await nodeLogging?.log({
@@ -172,9 +178,7 @@ export class PostgreSqlEntityStorageConnector {
172
178
  if ((prop.isSecondary === true || !Is.empty(prop.sortDirection)) &&
173
179
  prop.type !== EntitySchemaPropertyType.Object &&
174
180
  prop.type !== EntitySchemaPropertyType.Array) {
175
- const columnName = String(prop.property);
176
- const indexName = IndexHelper.generateName(this._config.tableName, columnName);
177
- await dbConnection.unsafe(`CREATE INDEX IF NOT EXISTS "${indexName}" ON "${this._config.tableName}" ("${columnName}")`);
181
+ await this.ensureIndex(dbConnection, prop, nodeLogging);
178
182
  }
179
183
  }
180
184
  }
@@ -236,7 +240,7 @@ export class PostgreSqlEntityStorageConnector {
236
240
  * @returns Nothing.
237
241
  */
238
242
  async stop() {
239
- await ConnectionHelper.closeClient("postgreSqlConnections", `${this._config.host}|${this._config.port ?? 5432}|${this._config.user}`, this._instanceId, this._mutexTimeoutMs, async (sql) => sql.end());
243
+ await ConnectionHelper.closeClient("postgreSqlConnections", `${this._config.host}|${this._config.port ?? 5432}|${this._config.user}|${this._config.database}`, this._instanceId, this._mutexTimeoutMs, async (sql) => sql.end());
240
244
  }
241
245
  /**
242
246
  * Get the schema for the entities.
@@ -870,13 +874,13 @@ export class PostgreSqlEntityStorageConnector {
870
874
  }
871
875
  /**
872
876
  * Check if the database exists.
877
+ * @param adminClient The server-level connection to use for the check.
873
878
  * @returns True if the database exists, false otherwise.
874
879
  * @internal
875
880
  */
876
- async databaseExists() {
881
+ async databaseExists(adminClient) {
877
882
  try {
878
- const dbConnection = await this.getClient();
879
- const res = await dbConnection.unsafe("SELECT datname FROM pg_catalog.pg_database WHERE datname = $1", [this._config.database]);
883
+ const res = await adminClient.unsafe("SELECT datname FROM pg_catalog.pg_database WHERE datname = $1", [this._config.database]);
880
884
  return res.length > 0;
881
885
  }
882
886
  catch {
@@ -885,18 +889,79 @@ export class PostgreSqlEntityStorageConnector {
885
889
  }
886
890
  /**
887
891
  * Wait for a database to exist.
892
+ * @param adminClient The server-level connection to use for the check.
888
893
  * @returns Nothing.
889
894
  * @internal
890
895
  */
891
- async waitForDatabaseExists() {
896
+ async waitForDatabaseExists(adminClient) {
892
897
  for (let attempt = 0; attempt < 20; attempt++) {
893
- const databaseExists = await this.databaseExists();
898
+ const databaseExists = await this.databaseExists(adminClient);
894
899
  if (databaseExists) {
895
900
  break;
896
901
  }
897
902
  await new Promise(resolve => setTimeout(resolve, 250));
898
903
  }
899
904
  }
905
+ /**
906
+ * Ensure the secondary index for a property exists, replacing a legacy-named index if present.
907
+ * @param dbConnection The connection to query with.
908
+ * @param prop The indexed property.
909
+ * @param nodeLogging Optional logging component.
910
+ * @internal
911
+ */
912
+ async ensureIndex(dbConnection, prop, nodeLogging) {
913
+ const columnName = String(prop.property);
914
+ const indexName = IndexHelper.generateName(this._config.tableName, columnName);
915
+ const indexRows = await dbConnection.unsafe(`SELECT i.relname AS "indexName", ix.indisunique AS "isUnique", ix.indnkeyatts AS "keyColumnCount"
916
+ FROM pg_index ix
917
+ JOIN pg_class t ON t.oid = ix.indrelid
918
+ JOIN pg_namespace n ON n.oid = t.relnamespace
919
+ JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ix.indkey[0]
920
+ JOIN pg_class i ON i.oid = ix.indexrelid
921
+ JOIN pg_am am ON am.oid = i.relam
922
+ WHERE n.nspname = 'public'
923
+ AND t.relname = $1
924
+ AND a.attname = $2
925
+ AND ix.indisvalid
926
+ AND ix.indisready
927
+ AND ix.indpred IS NULL
928
+ AND am.amname = 'btree'`, [this._config.tableName, columnName]);
929
+ const indexNames = indexRows.map(row => ObjectHelper.propertyGet(row, "indexName"));
930
+ if (!Is.arrayValue(indexNames)) {
931
+ await dbConnection.unsafe(`CREATE INDEX IF NOT EXISTS "${indexName}" ON "${this._config.tableName}" ("${columnName}")`);
932
+ return;
933
+ }
934
+ // TODO: remove the legacy index handling once every installation has bootstrapped on a release that contains it
935
+ const legacyName = IndexHelper.generateLegacyName(this._config.tableName, columnName, IndexHelper.DEFAULT_MAX_IDENTIFIER_LENGTH);
936
+ if (!indexNames.includes(legacyName)) {
937
+ return;
938
+ }
939
+ // The connector's own legacy indexes were always non-unique and single-column, anything else is an operator's
940
+ const legacyRow = indexRows.find(row => ObjectHelper.propertyGet(row, "indexName") === legacyName);
941
+ if (!Is.object(legacyRow) ||
942
+ ObjectHelper.propertyGet(legacyRow, "isUnique") !== false ||
943
+ Coerce.integer(ObjectHelper.propertyGet(legacyRow, "keyColumnCount")) !== 1) {
944
+ return;
945
+ }
946
+ const hasCurrent = indexNames.includes(indexName);
947
+ if (hasCurrent) {
948
+ await dbConnection.unsafe(`DROP INDEX "${legacyName}"`);
949
+ }
950
+ else {
951
+ await dbConnection.unsafe(`ALTER INDEX "${legacyName}" RENAME TO "${indexName}"`);
952
+ }
953
+ await nodeLogging?.log({
954
+ level: "info",
955
+ source: PostgreSqlEntityStorageConnector.CLASS_NAME,
956
+ ts: Date.now(),
957
+ message: hasCurrent ? "legacyIndexDropped" : "legacyIndexRenamed",
958
+ data: {
959
+ tableName: this._config.tableName,
960
+ indexName: legacyName,
961
+ newIndexName: indexName
962
+ }
963
+ });
964
+ }
900
965
  /**
901
966
  * Check if the table exists.
902
967
  * @returns True if the table exists, false otherwise.
@@ -941,19 +1006,20 @@ export class PostgreSqlEntityStorageConnector {
941
1006
  }
942
1007
  }
943
1008
  /**
944
- * Retrieve (or lazily create) the shared postgres connection for this endpoint.
1009
+ * Retrieve (or lazily create) the shared postgres connection for this endpoint and database.
945
1010
  * @returns The shared connection.
946
1011
  * @internal
947
1012
  */
948
1013
  async getClient() {
949
- return ConnectionHelper.openClient("postgreSqlConnections", `${this._config.host}|${this._config.port ?? 5432}|${this._config.user}`, this._instanceId, this._mutexTimeoutMs, async () => postgres(this.createConnectionConfig()));
1014
+ return ConnectionHelper.openClient("postgreSqlConnections", `${this._config.host}|${this._config.port ?? 5432}|${this._config.user}|${this._config.database}`, this._instanceId, this._mutexTimeoutMs, async () => postgres(this.createConnectionConfig()));
950
1015
  }
951
1016
  /**
952
1017
  * Create a new DB connection configuration.
1018
+ * @param includeDatabase Whether to include the database name in the options.
953
1019
  * @returns The PostgreSql connection configuration.
954
1020
  * @internal
955
1021
  */
956
- createConnectionConfig() {
1022
+ createConnectionConfig(includeDatabase = true) {
957
1023
  const opts = {
958
1024
  host: this._config.host,
959
1025
  port: this._config.port ?? 5432,
@@ -967,6 +1033,9 @@ export class PostgreSqlEntityStorageConnector {
967
1033
  // eslint-disable-next-line camelcase
968
1034
  max_lifetime: this._config?.pool?.maxLifetime
969
1035
  };
1036
+ if (includeDatabase) {
1037
+ opts.database = this._config.database;
1038
+ }
970
1039
  return opts;
971
1040
  }
972
1041
  /**
@@ -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\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 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 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\ttry {\n\t\t\tconst dbConnection = await this.getClient();\n\n\t\t\tconst databaseExists = await this.databaseExists();\n\t\t\tif (!databaseExists) {\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: \"databaseCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tawait dbConnection.unsafe(`CREATE DATABASE \"${this._config.database}\";`);\n\t\t\t\tawait this.waitForDatabaseExists();\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: \"databaseExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatabaseName: this._config.database\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\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\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\tconst columnName = String(prop.property);\n\t\t\t\t\tconst indexName = IndexHelper.generateName(this._config.tableName, columnName);\n\t\t\t\t\tawait dbConnection.unsafe(\n\t\t\t\t\t\t`CREATE INDEX IF NOT EXISTS \"${indexName}\" ON \"${this._config.tableName}\" (\"${columnName}\")`\n\t\t\t\t\t);\n\t\t\t\t}\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: \"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\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\t`${this._config.host}|${this._config.port ?? 5432}|${this._config.user}`,\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 0;\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: `${this._config.tableName}Migration${Date.now()}`\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 * @returns True if the database exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async databaseExists(): 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 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 * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForDatabaseExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst databaseExists = await this.databaseExists();\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 * 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.\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\t`${this._config.host}|${this._config.port ?? 5432}|${this._config.user}`,\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 * Create a new DB connection configuration.\n\t * @returns The PostgreSql connection configuration.\n\t * @internal\n\t */\n\tprivate createConnectionConfig(): 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};\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).toLowerCase()}%`);\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 LOWER(elem${elemPath}) ILIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `LOWER(${jsonTextExpr}) ILIKE $${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).toLowerCase()}%`);\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 LOWER(elem${elemPath}) ILIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `LOWER(${jsonTextExpr}) NOT ILIKE $${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}\" ILIKE '%' || $${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 ILIKE '%' || $${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\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 * 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\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\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\tIndexHelper,\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 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 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\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\tconst dbConnection = await this.getClient();\n\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\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, prop, nodeLogging);\n\t\t\t\t}\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: \"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\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\t`${this._config.host}|${this._config.port ?? 5432}|${this._config.user}|${this._config.database}`,\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 0;\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: `${this._config.tableName}Migration${Date.now()}`\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, replacing a legacy-named index if present.\n\t * @param dbConnection The connection to query with.\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\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\n\t\tconst indexRows = await dbConnection.unsafe(\n\t\t\t`SELECT i.relname AS \"indexName\", ix.indisunique AS \"isUnique\", ix.indnkeyatts AS \"keyColumnCount\"\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_attribute a ON a.attrelid = t.oid AND a.attnum = ix.indkey[0]\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\tWHERE n.nspname = 'public'\n\t\t\t\tAND t.relname = $1\n\t\t\t\tAND a.attname = $2\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\t[this._config.tableName, columnName] as ParameterOrJSON<never>[]\n\t\t);\n\t\tconst indexNames = indexRows.map(row => ObjectHelper.propertyGet<string>(row, \"indexName\"));\n\n\t\tif (!Is.arrayValue(indexNames)) {\n\t\t\tawait dbConnection.unsafe(\n\t\t\t\t`CREATE INDEX IF NOT EXISTS \"${indexName}\" ON \"${this._config.tableName}\" (\"${columnName}\")`\n\t\t\t);\n\t\t\treturn;\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\tif (!indexNames.includes(legacyName)) {\n\t\t\treturn;\n\t\t}\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\tconst legacyRow = indexRows.find(\n\t\t\trow => ObjectHelper.propertyGet(row, \"indexName\") === legacyName\n\t\t);\n\t\tif (\n\t\t\t!Is.object(legacyRow) ||\n\t\t\tObjectHelper.propertyGet(legacyRow, \"isUnique\") !== false ||\n\t\t\tCoerce.integer(ObjectHelper.propertyGet(legacyRow, \"keyColumnCount\")) !== 1\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst hasCurrent = indexNames.includes(indexName);\n\t\tif (hasCurrent) {\n\t\t\tawait dbConnection.unsafe(`DROP INDEX \"${legacyName}\"`);\n\t\t} else {\n\t\t\tawait dbConnection.unsafe(`ALTER INDEX \"${legacyName}\" RENAME TO \"${indexName}\"`);\n\t\t}\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: hasCurrent ? \"legacyIndexDropped\" : \"legacyIndexRenamed\",\n\t\t\tdata: {\n\t\t\t\ttableName: this._config.tableName,\n\t\t\t\tindexName: legacyName,\n\t\t\t\tnewIndexName: indexName\n\t\t\t}\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\t`${this._config.host}|${this._config.port ?? 5432}|${this._config.user}|${this._config.database}`,\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 * 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};\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).toLowerCase()}%`);\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 LOWER(elem${elemPath}) ILIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `LOWER(${jsonTextExpr}) ILIKE $${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).toLowerCase()}%`);\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 LOWER(elem${elemPath}) ILIKE $${valueIndex})`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `LOWER(${jsonTextExpr}) NOT ILIKE $${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}\" ILIKE '%' || $${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 ILIKE '%' || $${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\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 * 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\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\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"]}
package/docs/changelog.md CHANGED
@@ -1,5 +1,88 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.3-next.2](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-postgresql-v0.9.3-next.1...entity-storage-connector-postgresql-v0.9.3-next.2) (2026-09-01)
4
+
5
+
6
+ ### Features
7
+
8
+ * replace the connector's own legacy indexes on bootstrap ([#243](https://github.com/iotaledger/twin-entity-storage/issues/243)) ([55fd01d](https://github.com/iotaledger/twin-entity-storage/commit/55fd01d9f2ae4d9e8f523f9b8ce85dafb5a49316))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/entity-storage-models bumped from 0.9.3-next.1 to 0.9.3-next.2
16
+ * devDependencies
17
+ * @twin.org/entity-storage-connector-memory bumped from 0.9.3-next.1 to 0.9.3-next.2
18
+
19
+ ## [0.9.3-next.1](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-postgresql-v0.9.3-next.0...entity-storage-connector-postgresql-v0.9.3-next.1) (2026-08-26)
20
+
21
+
22
+ ### Features
23
+
24
+ * add context id features ([#55](https://github.com/iotaledger/twin-entity-storage/issues/55)) ([99c15a2](https://github.com/iotaledger/twin-entity-storage/commit/99c15a257539b61d9da63649ce573ebf47699fc9))
25
+ * add ISchemaMigration chain, SchemaVersionMigrator runner and version store ([#110](https://github.com/iotaledger/twin-entity-storage/issues/110)) ([2dac924](https://github.com/iotaledger/twin-entity-storage/commit/2dac9244a752cb58304d1649ff03c3a2469783dd))
26
+ * add production release automation ([1eb4c8e](https://github.com/iotaledger/twin-entity-storage/commit/1eb4c8ee3eb099defdfc2d063ae44935276dcae8))
27
+ * add support for object comparison conditions ([eb505a1](https://github.com/iotaledger/twin-entity-storage/commit/eb505a17a3642e95c4e3cf137a77a0a8fb388c97))
28
+ * add validate-locales ([e66ef0d](https://github.com/iotaledger/twin-entity-storage/commit/e66ef0de26ca2f82b3fe89bb5c7a15a0978a9644))
29
+ * adding schema migration functionality to all the connectors ([#85](https://github.com/iotaledger/twin-entity-storage/issues/85)) ([fd1555a](https://github.com/iotaledger/twin-entity-storage/commit/fd1555a34380158214a577586dafae821e72a578))
30
+ * additional information in health ([1e658b7](https://github.com/iotaledger/twin-entity-storage/commit/1e658b74288e9411538286d25b81823df80703e9))
31
+ * disable endpoint discovery for cosmos ([49df2a2](https://github.com/iotaledger/twin-entity-storage/commit/49df2a254f385dc42e2e1f7e26e71f89b5bf5bcf))
32
+ * entity storage conditions ([#115](https://github.com/iotaledger/twin-entity-storage/issues/115)) ([7a53884](https://github.com/iotaledger/twin-entity-storage/commit/7a53884f6acb856d77733e4e0f23ec1c00b74cb4))
33
+ * entity storage enhancements ([#86](https://github.com/iotaledger/twin-entity-storage/issues/86)) ([1279af4](https://github.com/iotaledger/twin-entity-storage/commit/1279af42615c6497bb06539842cee44842dd1f75))
34
+ * eslint migration to flat config ([f033b64](https://github.com/iotaledger/twin-entity-storage/commit/f033b64984c0e6a8129d929c9dd816dcc1b8dab0))
35
+ * indexing ([#207](https://github.com/iotaledger/twin-entity-storage/issues/207)) ([2fd1f0d](https://github.com/iotaledger/twin-entity-storage/commit/2fd1f0d992344905c9dd1a44addfc4f9d5b5c168))
36
+ * input validation ([#162](https://github.com/iotaledger/twin-entity-storage/issues/162)) ([3e1e428](https://github.com/iotaledger/twin-entity-storage/commit/3e1e42887955cf079efd5989e197ddf8e0fa8c47))
37
+ * linting and dependency update ([c307b60](https://github.com/iotaledger/twin-entity-storage/commit/c307b606d03ea436b7c43d4e1764b5c08f415555))
38
+ * logging naming consistency ([f99d12d](https://github.com/iotaledger/twin-entity-storage/commit/f99d12dea04b6d4f2b5632ff5473e9ec7d5f9055))
39
+ * migration progress ([#121](https://github.com/iotaledger/twin-entity-storage/issues/121)) ([d032162](https://github.com/iotaledger/twin-entity-storage/commit/d032162768b6b7d4ccca7e39b80f8bc3ba46440e))
40
+ * migration property remover ([#221](https://github.com/iotaledger/twin-entity-storage/issues/221)) ([f7569ec](https://github.com/iotaledger/twin-entity-storage/commit/f7569ec44529b23d5c93789818440eb65d177570))
41
+ * mysql non offset paging ([#172](https://github.com/iotaledger/twin-entity-storage/issues/172)) ([0633165](https://github.com/iotaledger/twin-entity-storage/commit/063316563fa8abe221251cd34fdd6c03538b9bb3))
42
+ * optimistic locking ([#201](https://github.com/iotaledger/twin-entity-storage/issues/201)) ([80cbe3b](https://github.com/iotaledger/twin-entity-storage/commit/80cbe3b611c47b16328bceab02cfb8423fe1bbcd))
43
+ * pooled connections ([#208](https://github.com/iotaledger/twin-entity-storage/issues/208)) ([5d832d1](https://github.com/iotaledger/twin-entity-storage/commit/5d832d15b0639f13ad3f5d2c68c946a72264310a))
44
+ * remove default loggers ([7c8c7b1](https://github.com/iotaledger/twin-entity-storage/commit/7c8c7b132c23e95abd465c0ca3bad5ec8d95f91e))
45
+ * synchronised storage ([#44](https://github.com/iotaledger/twin-entity-storage/issues/44)) ([94e10e2](https://github.com/iotaledger/twin-entity-storage/commit/94e10e26d1feec801449dc04af7a9757ac7495ff))
46
+ * typescript 6 update ([995a0c6](https://github.com/iotaledger/twin-entity-storage/commit/995a0c6fa9a6813bfdc7200779ce3664236e59e9))
47
+ * update dependencies ([7ccc0c4](https://github.com/iotaledger/twin-entity-storage/commit/7ccc0c429125d073dc60b3de6cf101abc8cc6cba))
48
+ * update framework core ([b59a380](https://github.com/iotaledger/twin-entity-storage/commit/b59a380bb7fba2b43610f69074dcdee24a4737da))
49
+ * update health signatures ([#188](https://github.com/iotaledger/twin-entity-storage/issues/188)) ([0159094](https://github.com/iotaledger/twin-entity-storage/commit/015909423958a7a20505a92b23793a044d26f6a4))
50
+ * use shared store mechanism ([#34](https://github.com/iotaledger/twin-entity-storage/issues/34)) ([68b6b71](https://github.com/iotaledger/twin-entity-storage/commit/68b6b71e7a96d7d016cd57bfff36775b56bf3f93))
51
+
52
+
53
+ ### Bug Fixes
54
+
55
+ * adding integers types handler ([#82](https://github.com/iotaledger/twin-entity-storage/issues/82)) ([2704717](https://github.com/iotaledger/twin-entity-storage/commit/2704717fde7c0c8b39e8036b4d2a61654b51f917))
56
+ * adding tests and fixes for dot notation ([#76](https://github.com/iotaledger/twin-entity-storage/issues/76)) ([3879337](https://github.com/iotaledger/twin-entity-storage/commit/387933797e33543e4d8b2d49b8beeb792512a4ff))
57
+ * adding tests and support when neccesary for string include operator when needed ([#72](https://github.com/iotaledger/twin-entity-storage/issues/72)) ([3c723dd](https://github.com/iotaledger/twin-entity-storage/commit/3c723dd5694814398099d9d4594089dc6c66ba97))
58
+ * adding tests for debugging and patching the missing quotes and parse error handeling ([#61](https://github.com/iotaledger/twin-entity-storage/issues/61)) ([f746be5](https://github.com/iotaledger/twin-entity-storage/commit/f746be530799bede1db08482cf65fe780c5e75a0))
59
+ * allow multi-property sort on DynamoDB and CosmosDB connectors ([#196](https://github.com/iotaledger/twin-entity-storage/issues/196)) ([f1bb582](https://github.com/iotaledger/twin-entity-storage/commit/f1bb5826d75dae331ad6b42df5de330a308c5405))
60
+ * cache full connection ([#237](https://github.com/iotaledger/twin-entity-storage/issues/237)) ([1712eaa](https://github.com/iotaledger/twin-entity-storage/commit/1712eaa92ab3878ef8a8ee7fd29fa32a6fc9725e))
61
+ * check column coverage instead of exact index name to prevent duplicate secondary indexes ([#231](https://github.com/iotaledger/twin-entity-storage/issues/231)) ([6ca9f7f](https://github.com/iotaledger/twin-entity-storage/commit/6ca9f7fcea04a854e473042a8c2ef5c0aff80df0))
62
+ * dynamodb get with condition ignores primary key ([d2d0ec2](https://github.com/iotaledger/twin-entity-storage/commit/d2d0ec21023bc22f0e5a35c2d49396d90b42a4ce))
63
+ * dynamodb query gsi ([#140](https://github.com/iotaledger/twin-entity-storage/issues/140)) ([45b56d6](https://github.com/iotaledger/twin-entity-storage/commit/45b56d6260c9876012030cc6c85026ea84aebff5))
64
+ * guard against empty IN list in all SQL-style connectors ([#101](https://github.com/iotaledger/twin-entity-storage/issues/101)) ([fb2bf8b](https://github.com/iotaledger/twin-entity-storage/commit/fb2bf8beb148f0c9b92661c4899e28cd4559f39a))
65
+ * handle empty conditions ([#159](https://github.com/iotaledger/twin-entity-storage/issues/159)) ([ae3319c](https://github.com/iotaledger/twin-entity-storage/commit/ae3319c3136bccc94244b2d79b3baef7a1b037d7))
66
+ * include semantics with json conversion ([4d1f37e](https://github.com/iotaledger/twin-entity-storage/commit/4d1f37ef93eba0039c39e0f12a642565ddc28394))
67
+ * migration partitions ([#182](https://github.com/iotaledger/twin-entity-storage/issues/182)) ([bcbaf26](https://github.com/iotaledger/twin-entity-storage/commit/bcbaf26f11d34beabefdfcaf8101b7c234ca5ac9))
68
+ * null secondary indexes ([#103](https://github.com/iotaledger/twin-entity-storage/issues/103)) ([5e44f11](https://github.com/iotaledger/twin-entity-storage/commit/5e44f11bb5af5bf2c27d6f1d56aba5851116ff89))
69
+ * only count btree indexes as secondary index coverage on postgresql ([#240](https://github.com/iotaledger/twin-entity-storage/issues/240)) ([607d948](https://github.com/iotaledger/twin-entity-storage/commit/607d948339d22e1e69f045759af9a29b3211ba78))
70
+ * query params force coercion ([dd6aa87](https://github.com/iotaledger/twin-entity-storage/commit/dd6aa87efdfb60bab7d6756a86888863c45c51a7))
71
+ * route GSI sort-key conditions to KeyConditionExpression and cross-connector cursor-walk tests ([#127](https://github.com/iotaledger/twin-entity-storage/issues/127)) ([6a24e1b](https://github.com/iotaledger/twin-entity-storage/commit/6a24e1b5f3b8b426987e43da3af6766d8cb68afb))
72
+ * schema version check crashes in multi-tenant mode ([#192](https://github.com/iotaledger/twin-entity-storage/issues/192)) ([a816341](https://github.com/iotaledger/twin-entity-storage/commit/a8163415ce116582f3c3c23294f7f4062099d8f3))
73
+ * skip partition ids with mismatched depth during partition enumeration ([#218](https://github.com/iotaledger/twin-entity-storage/issues/218)) ([8fc2386](https://github.com/iotaledger/twin-entity-storage/commit/8fc238699e2891f0c982530c011fe4438004b0ae))
74
+ * tests and fixes for the comparisons for null and undefined ([#79](https://github.com/iotaledger/twin-entity-storage/issues/79)) ([e7ffd62](https://github.com/iotaledger/twin-entity-storage/commit/e7ffd62e9ec40ef31498e6e2350bb25d9c84638a))
75
+ * use hashing to restrict index name length ([757d572](https://github.com/iotaledger/twin-entity-storage/commit/757d5728161a00c1d1865ad6df3231eecfad16f2))
76
+
77
+
78
+ ### Dependencies
79
+
80
+ * The following workspace dependencies were updated
81
+ * dependencies
82
+ * @twin.org/entity-storage-models bumped from 0.9.3-next.0 to 0.9.3-next.1
83
+ * devDependencies
84
+ * @twin.org/entity-storage-connector-memory bumped from 0.9.3-next.0 to 0.9.3-next.1
85
+
3
86
  ## [0.9.2](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-postgresql-v0.9.2...entity-storage-connector-postgresql-v0.9.2) (2026-08-24)
4
87
 
5
88
 
package/locales/en.json CHANGED
@@ -6,7 +6,9 @@
6
6
  "tableCreating": "Table \"{tableName}\" creating",
7
7
  "tableExists": "Table \"{tableName}\" created or it already exists",
8
8
  "tableDropping": "Dropping table \"{tableName}\"",
9
- "tableDropped": "Table \"{tableName}\" dropped"
9
+ "tableDropped": "Table \"{tableName}\" dropped",
10
+ "legacyIndexDropped": "Legacy index \"{indexName}\" dropped from table \"{tableName}\", \"{newIndexName}\" already covers the column",
11
+ "legacyIndexRenamed": "Legacy index \"{indexName}\" renamed to \"{newIndexName}\" on table \"{tableName}\""
10
12
  }
11
13
  },
12
14
  "warn": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/entity-storage-connector-postgresql",
3
- "version": "0.9.2",
3
+ "version": "0.9.3-next.2",
4
4
  "description": "PostgreSQL connector for relational persistence and advanced SQL features.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,13 +14,13 @@
14
14
  "node": ">=24.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/api-models": "^0.9.2",
18
- "@twin.org/context": "^0.9.2",
19
- "@twin.org/core": "^0.9.2",
20
- "@twin.org/entity": "^0.9.2",
21
- "@twin.org/entity-storage-models": "^0.9.2",
22
- "@twin.org/logging-models": "^0.9.1",
23
- "@twin.org/nameof": "^0.9.2",
17
+ "@twin.org/api-models": "next",
18
+ "@twin.org/context": "next",
19
+ "@twin.org/core": "next",
20
+ "@twin.org/entity": "next",
21
+ "@twin.org/entity-storage-models": "0.9.3-next.2",
22
+ "@twin.org/logging-models": "next",
23
+ "@twin.org/nameof": "next",
24
24
  "postgres": "3.4.9"
25
25
  },
26
26
  "main": "./dist/es/index.js",