@relq/orm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +236 -0
- package/dist/cjs/__test-types.cjs +17 -0
- package/dist/cjs/addon/cursor.cjs +1473 -0
- package/dist/cjs/addon/pg.cjs +4969 -0
- package/dist/cjs/cache/index.cjs +9 -0
- package/dist/cjs/cache/query-cache.cjs +311 -0
- package/dist/cjs/condition/array-condition-builder.cjs +527 -0
- package/dist/cjs/condition/array-numeric-condition-builder.cjs +186 -0
- package/dist/cjs/condition/array-specialized-condition-builder.cjs +206 -0
- package/dist/cjs/condition/array-string-condition-builder.cjs +146 -0
- package/dist/cjs/condition/base-condition-builder.cjs +2 -0
- package/dist/cjs/condition/condition-collector.cjs +461 -0
- package/dist/cjs/condition/fulltext-condition-builder.cjs +61 -0
- package/dist/cjs/condition/geometric-condition-builder.cjs +228 -0
- package/dist/cjs/condition/index.cjs +29 -0
- package/dist/cjs/condition/jsonb-condition-builder.cjs +448 -0
- package/dist/cjs/condition/network-condition-builder.cjs +237 -0
- package/dist/cjs/condition/postgis-condition-builder.cjs +188 -0
- package/dist/cjs/condition/range-condition-builder.cjs +98 -0
- package/dist/cjs/core/helpers/ConnectedAggregateBuilder.cjs +132 -0
- package/dist/cjs/core/helpers/ConnectedCTEBuilder.cjs +53 -0
- package/dist/cjs/core/helpers/ConnectedCountBuilder.cjs +73 -0
- package/dist/cjs/core/helpers/ConnectedDeleteBuilder.cjs +65 -0
- package/dist/cjs/core/helpers/ConnectedInsertBuilder.cjs +112 -0
- package/dist/cjs/core/helpers/ConnectedInsertFromSelectBuilder.cjs +66 -0
- package/dist/cjs/core/helpers/ConnectedQueryBuilder.cjs +146 -0
- package/dist/cjs/core/helpers/ConnectedRawQueryBuilder.cjs +46 -0
- package/dist/cjs/core/helpers/ConnectedSelectBuilder.cjs +331 -0
- package/dist/cjs/core/helpers/ConnectedTransactionBuilder.cjs +105 -0
- package/dist/cjs/core/helpers/ConnectedUpdateBuilder.cjs +79 -0
- package/dist/cjs/core/helpers/PaginateBuilder.cjs +178 -0
- package/dist/cjs/core/helpers/ReturningExecutor.cjs +70 -0
- package/dist/cjs/core/helpers/capability-guard.cjs +10 -0
- package/dist/cjs/core/helpers/index.cjs +31 -0
- package/dist/cjs/core/helpers/methods.cjs +10 -0
- package/dist/cjs/core/helpers/query-convenience.cjs +238 -0
- package/dist/cjs/core/helpers/select-joins.cjs +251 -0
- package/dist/cjs/core/helpers/select-pagination.cjs +233 -0
- package/dist/cjs/core/helpers/select-types.cjs +2 -0
- package/dist/cjs/core/pg-family/cockroachdb-client/capabilities.cjs +31 -0
- package/dist/cjs/core/pg-family/cockroachdb-client/index.cjs +7 -0
- package/dist/cjs/core/pg-family/cockroachdb-client/relq-cockroach.cjs +16 -0
- package/dist/cjs/core/pg-family/dsql-client/capabilities.cjs +31 -0
- package/dist/cjs/core/pg-family/dsql-client/index.cjs +7 -0
- package/dist/cjs/core/pg-family/dsql-client/relq-dsql.cjs +16 -0
- package/dist/cjs/core/pg-family/index.cjs +19 -0
- package/dist/cjs/core/pg-family/nile-client/capabilities.cjs +31 -0
- package/dist/cjs/core/pg-family/nile-client/index.cjs +7 -0
- package/dist/cjs/core/pg-family/nile-client/relq-nile.cjs +36 -0
- package/dist/cjs/core/pg-family/nile-client/tenant-context.cjs +44 -0
- package/dist/cjs/core/pg-family/pg-client/capabilities.cjs +31 -0
- package/dist/cjs/core/pg-family/pg-client/index.cjs +7 -0
- package/dist/cjs/core/pg-family/pg-client/relq-postgres.cjs +43 -0
- package/dist/cjs/core/pg-family/shared/pg-base.cjs +385 -0
- package/dist/cjs/core/pg-family/shared/pg-dialect.cjs +67 -0
- package/dist/cjs/core/pg-family/shared/pg-error-parser.cjs +34 -0
- package/dist/cjs/core/pg-family/shared/pg-type-coercion.cjs +14 -0
- package/dist/cjs/core/relq-base.cjs +307 -0
- package/dist/cjs/core/relq-client.cjs +56 -0
- package/dist/cjs/core/shared/cleanup.cjs +36 -0
- package/dist/cjs/core/shared/column-mapping.cjs +97 -0
- package/dist/cjs/core/shared/errors.cjs +17 -0
- package/dist/cjs/core/shared/index.cjs +24 -0
- package/dist/cjs/core/shared/table-accessor.cjs +22 -0
- package/dist/cjs/core/shared/transform.cjs +35 -0
- package/dist/cjs/core/shared/types.cjs +2 -0
- package/dist/cjs/core/shared/validation.cjs +140 -0
- package/dist/cjs/core/types/core.types.cjs +2 -0
- package/dist/cjs/count/count-builder.cjs +88 -0
- package/dist/cjs/count/index.cjs +5 -0
- package/dist/cjs/delete/delete-builder.cjs +176 -0
- package/dist/cjs/delete/index.cjs +5 -0
- package/dist/cjs/explain/explain-builder.cjs +99 -0
- package/dist/cjs/explain/index.cjs +5 -0
- package/dist/cjs/index.cjs +26 -0
- package/dist/cjs/insert/conflict-builder.cjs +213 -0
- package/dist/cjs/insert/index.cjs +5 -0
- package/dist/cjs/insert/insert-builder.cjs +320 -0
- package/dist/cjs/insert/insert-from-select-builder.cjs +86 -0
- package/dist/cjs/pubsub/index.cjs +7 -0
- package/dist/cjs/pubsub/listen-notify-builder.cjs +57 -0
- package/dist/cjs/pubsub/listener-connection.cjs +180 -0
- package/dist/cjs/raw/index.cjs +8 -0
- package/dist/cjs/raw/raw-query-builder.cjs +27 -0
- package/dist/cjs/raw/sql-template.cjs +73 -0
- package/dist/cjs/select/aggregate-builder.cjs +179 -0
- package/dist/cjs/select/index.cjs +16 -0
- package/dist/cjs/select/join-builder.cjs +192 -0
- package/dist/cjs/select/join-condition-builder.cjs +189 -0
- package/dist/cjs/select/join-internals.cjs +5 -0
- package/dist/cjs/select/join-many-condition-builder.cjs +159 -0
- package/dist/cjs/select/scalar-query-builder.cjs +134 -0
- package/dist/cjs/select/scalar-select-builder.cjs +78 -0
- package/dist/cjs/select/select-builder.cjs +426 -0
- package/dist/cjs/select/sql-expression.cjs +38 -0
- package/dist/cjs/select/table-proxy.cjs +99 -0
- package/dist/cjs/shared/aws-dsql.cjs +181 -0
- package/dist/cjs/shared/errors/relq-errors.cjs +361 -0
- package/dist/cjs/shared/pg-format.cjs +383 -0
- package/dist/cjs/shared/types/config-types.cjs +51 -0
- package/dist/cjs/transaction/index.cjs +6 -0
- package/dist/cjs/transaction/transaction-builder.cjs +78 -0
- package/dist/cjs/types/aggregate-types.cjs +2 -0
- package/dist/cjs/types/inference-types.cjs +18 -0
- package/dist/cjs/types/pagination-types.cjs +7 -0
- package/dist/cjs/types/result-types.cjs +2 -0
- package/dist/cjs/types/scalar-types.cjs +2 -0
- package/dist/cjs/types/schema-types.cjs +2 -0
- package/dist/cjs/types/subscription-types.cjs +2 -0
- package/dist/cjs/types.cjs +2 -0
- package/dist/cjs/update/array-update-builder.cjs +232 -0
- package/dist/cjs/update/index.cjs +16 -0
- package/dist/cjs/update/jsonb-update-builder.cjs +219 -0
- package/dist/cjs/update/update-builder.cjs +274 -0
- package/dist/cjs/utils/addon/pg/cursor.cjs +8 -0
- package/dist/cjs/utils/addon/pg/pg.cjs +23 -0
- package/dist/cjs/utils/case-converter.cjs +58 -0
- package/dist/cjs/utils/env-resolver.cjs +226 -0
- package/dist/cjs/utils/environment-detection.cjs +124 -0
- package/dist/cjs/utils/fk-resolver.cjs +186 -0
- package/dist/cjs/utils/index.cjs +25 -0
- package/dist/cjs/utils/pool-defaults.cjs +91 -0
- package/dist/cjs/utils/type-coercion.cjs +120 -0
- package/dist/cjs/window/index.cjs +5 -0
- package/dist/cjs/window/window-builder.cjs +80 -0
- package/dist/esm/__test-types.js +15 -0
- package/dist/esm/addon/cursor.js +1440 -0
- package/dist/esm/addon/pg.js +4931 -0
- package/dist/esm/cache/index.js +1 -0
- package/dist/esm/cache/query-cache.js +303 -0
- package/dist/esm/condition/array-condition-builder.js +519 -0
- package/dist/esm/condition/array-numeric-condition-builder.js +182 -0
- package/dist/esm/condition/array-specialized-condition-builder.js +200 -0
- package/dist/esm/condition/array-string-condition-builder.js +142 -0
- package/dist/esm/condition/base-condition-builder.js +1 -0
- package/dist/esm/condition/condition-collector.js +452 -0
- package/dist/esm/condition/fulltext-condition-builder.js +53 -0
- package/dist/esm/condition/geometric-condition-builder.js +220 -0
- package/dist/esm/condition/index.js +8 -0
- package/dist/esm/condition/jsonb-condition-builder.js +439 -0
- package/dist/esm/condition/network-condition-builder.js +229 -0
- package/dist/esm/condition/postgis-condition-builder.js +180 -0
- package/dist/esm/condition/range-condition-builder.js +90 -0
- package/dist/esm/core/helpers/ConnectedAggregateBuilder.js +128 -0
- package/dist/esm/core/helpers/ConnectedCTEBuilder.js +49 -0
- package/dist/esm/core/helpers/ConnectedCountBuilder.js +69 -0
- package/dist/esm/core/helpers/ConnectedDeleteBuilder.js +61 -0
- package/dist/esm/core/helpers/ConnectedInsertBuilder.js +108 -0
- package/dist/esm/core/helpers/ConnectedInsertFromSelectBuilder.js +62 -0
- package/dist/esm/core/helpers/ConnectedQueryBuilder.js +142 -0
- package/dist/esm/core/helpers/ConnectedRawQueryBuilder.js +42 -0
- package/dist/esm/core/helpers/ConnectedSelectBuilder.js +327 -0
- package/dist/esm/core/helpers/ConnectedTransactionBuilder.js +100 -0
- package/dist/esm/core/helpers/ConnectedUpdateBuilder.js +75 -0
- package/dist/esm/core/helpers/PaginateBuilder.js +174 -0
- package/dist/esm/core/helpers/ReturningExecutor.js +66 -0
- package/dist/esm/core/helpers/capability-guard.js +7 -0
- package/dist/esm/core/helpers/index.js +13 -0
- package/dist/esm/core/helpers/methods.js +6 -0
- package/dist/esm/core/helpers/query-convenience.js +194 -0
- package/dist/esm/core/helpers/select-joins.js +246 -0
- package/dist/esm/core/helpers/select-pagination.js +226 -0
- package/dist/esm/core/helpers/select-types.js +1 -0
- package/dist/esm/core/pg-family/cockroachdb-client/capabilities.js +28 -0
- package/dist/esm/core/pg-family/cockroachdb-client/index.js +2 -0
- package/dist/esm/core/pg-family/cockroachdb-client/relq-cockroach.js +12 -0
- package/dist/esm/core/pg-family/dsql-client/capabilities.js +28 -0
- package/dist/esm/core/pg-family/dsql-client/index.js +2 -0
- package/dist/esm/core/pg-family/dsql-client/relq-dsql.js +12 -0
- package/dist/esm/core/pg-family/index.js +6 -0
- package/dist/esm/core/pg-family/nile-client/capabilities.js +28 -0
- package/dist/esm/core/pg-family/nile-client/index.js +2 -0
- package/dist/esm/core/pg-family/nile-client/relq-nile.js +32 -0
- package/dist/esm/core/pg-family/nile-client/tenant-context.js +40 -0
- package/dist/esm/core/pg-family/pg-client/capabilities.js +28 -0
- package/dist/esm/core/pg-family/pg-client/index.js +2 -0
- package/dist/esm/core/pg-family/pg-client/relq-postgres.js +39 -0
- package/dist/esm/core/pg-family/shared/pg-base.js +347 -0
- package/dist/esm/core/pg-family/shared/pg-dialect.js +63 -0
- package/dist/esm/core/pg-family/shared/pg-error-parser.js +29 -0
- package/dist/esm/core/pg-family/shared/pg-type-coercion.js +6 -0
- package/dist/esm/core/relq-base.js +270 -0
- package/dist/esm/core/relq-client.js +48 -0
- package/dist/esm/core/shared/cleanup.js +27 -0
- package/dist/esm/core/shared/column-mapping.js +90 -0
- package/dist/esm/core/shared/errors.js +13 -0
- package/dist/esm/core/shared/index.js +6 -0
- package/dist/esm/core/shared/table-accessor.js +19 -0
- package/dist/esm/core/shared/transform.js +30 -0
- package/dist/esm/core/shared/types.js +1 -0
- package/dist/esm/core/shared/validation.js +136 -0
- package/dist/esm/core/types/core.types.js +1 -0
- package/dist/esm/count/count-builder.js +81 -0
- package/dist/esm/count/index.js +1 -0
- package/dist/esm/delete/delete-builder.js +169 -0
- package/dist/esm/delete/index.js +1 -0
- package/dist/esm/explain/explain-builder.js +95 -0
- package/dist/esm/explain/index.js +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/insert/conflict-builder.js +202 -0
- package/dist/esm/insert/index.js +1 -0
- package/dist/esm/insert/insert-builder.js +313 -0
- package/dist/esm/insert/insert-from-select-builder.js +79 -0
- package/dist/esm/pubsub/index.js +1 -0
- package/dist/esm/pubsub/listen-notify-builder.js +48 -0
- package/dist/esm/pubsub/listener-connection.js +173 -0
- package/dist/esm/raw/index.js +2 -0
- package/dist/esm/raw/raw-query-builder.js +20 -0
- package/dist/esm/raw/sql-template.js +66 -0
- package/dist/esm/select/aggregate-builder.js +172 -0
- package/dist/esm/select/index.js +4 -0
- package/dist/esm/select/join-builder.js +184 -0
- package/dist/esm/select/join-condition-builder.js +181 -0
- package/dist/esm/select/join-internals.js +2 -0
- package/dist/esm/select/join-many-condition-builder.js +151 -0
- package/dist/esm/select/scalar-query-builder.js +126 -0
- package/dist/esm/select/scalar-select-builder.js +70 -0
- package/dist/esm/select/select-builder.js +419 -0
- package/dist/esm/select/sql-expression.js +33 -0
- package/dist/esm/select/table-proxy.js +91 -0
- package/dist/esm/shared/aws-dsql.js +140 -0
- package/dist/esm/shared/errors/relq-errors.js +339 -0
- package/dist/esm/shared/pg-format.js +375 -0
- package/dist/esm/shared/types/config-types.js +46 -0
- package/dist/esm/transaction/index.js +1 -0
- package/dist/esm/transaction/transaction-builder.js +70 -0
- package/dist/esm/types/aggregate-types.js +1 -0
- package/dist/esm/types/inference-types.js +12 -0
- package/dist/esm/types/pagination-types.js +4 -0
- package/dist/esm/types/result-types.js +1 -0
- package/dist/esm/types/scalar-types.js +1 -0
- package/dist/esm/types/schema-types.js +1 -0
- package/dist/esm/types/subscription-types.js +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/update/array-update-builder.js +219 -0
- package/dist/esm/update/index.js +3 -0
- package/dist/esm/update/jsonb-update-builder.js +211 -0
- package/dist/esm/update/update-builder.js +267 -0
- package/dist/esm/utils/addon/pg/cursor.js +1 -0
- package/dist/esm/utils/addon/pg/pg.js +2 -0
- package/dist/esm/utils/case-converter.js +55 -0
- package/dist/esm/utils/env-resolver.js +213 -0
- package/dist/esm/utils/environment-detection.js +114 -0
- package/dist/esm/utils/fk-resolver.js +178 -0
- package/dist/esm/utils/index.js +4 -0
- package/dist/esm/utils/pool-defaults.js +85 -0
- package/dist/esm/utils/type-coercion.js +112 -0
- package/dist/esm/window/index.js +1 -0
- package/dist/esm/window/window-builder.js +73 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +7281 -0
- package/dist/index.js +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { mergeWithDefaults } from "../../orm/utils/pool-defaults.js";
|
|
2
|
+
export function isPoolingEnabled(config) {
|
|
3
|
+
return config.pooling !== false;
|
|
4
|
+
}
|
|
5
|
+
export function toPoolConfig(config) {
|
|
6
|
+
const smartDefaults = config.disableSmartDefaults
|
|
7
|
+
? { min: 0, max: 10, idleTimeoutMillis: 30000, connectionTimeoutMillis: 0 }
|
|
8
|
+
: mergeWithDefaults(config.pool);
|
|
9
|
+
const isAws = !!config.aws;
|
|
10
|
+
const host = isAws ? config.aws.hostname : (config.host || 'localhost');
|
|
11
|
+
const port = config.aws?.port ?? config.port ?? 5432;
|
|
12
|
+
const user = config.aws?.user ?? config.user ?? (isAws ? 'admin' : undefined);
|
|
13
|
+
const ssl = isAws ? (config.aws.ssl ?? true) : config.ssl;
|
|
14
|
+
const isWorkers = typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers';
|
|
15
|
+
const allowExitOnIdle = !isWorkers;
|
|
16
|
+
const poolConfig = {
|
|
17
|
+
host,
|
|
18
|
+
port,
|
|
19
|
+
database: config.database,
|
|
20
|
+
user,
|
|
21
|
+
password: config.password,
|
|
22
|
+
min: config.pool?.min ?? smartDefaults.min,
|
|
23
|
+
max: config.pool?.max ?? smartDefaults.max,
|
|
24
|
+
idleTimeoutMillis: config.pool?.idleTimeoutMillis ?? smartDefaults.idleTimeoutMillis,
|
|
25
|
+
connectionTimeoutMillis: config.pool?.connectionTimeoutMillis ?? smartDefaults.connectionTimeoutMillis,
|
|
26
|
+
application_name: config.pool?.application_name,
|
|
27
|
+
ssl: config.pool?.ssl ?? ssl,
|
|
28
|
+
allowExitOnIdle
|
|
29
|
+
};
|
|
30
|
+
if (config.connectionString) {
|
|
31
|
+
return {
|
|
32
|
+
connectionString: config.connectionString,
|
|
33
|
+
min: poolConfig.min,
|
|
34
|
+
max: poolConfig.max,
|
|
35
|
+
idleTimeoutMillis: poolConfig.idleTimeoutMillis,
|
|
36
|
+
connectionTimeoutMillis: poolConfig.connectionTimeoutMillis,
|
|
37
|
+
application_name: poolConfig.application_name,
|
|
38
|
+
ssl: poolConfig.ssl,
|
|
39
|
+
allowExitOnIdle
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return poolConfig;
|
|
43
|
+
}
|
|
44
|
+
export function isAwsDsqlConfig(config) {
|
|
45
|
+
return !!config.aws?.hostname && !!config.aws?.region;
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TransactionBuilder, SavepointBuilder } from "./transaction-builder.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import format from "../shared/pg-format.js";
|
|
2
|
+
export class TransactionBuilder {
|
|
3
|
+
isolationLevel;
|
|
4
|
+
mode;
|
|
5
|
+
__deferrable;
|
|
6
|
+
isolation(level) {
|
|
7
|
+
this.isolationLevel = level;
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
readWrite() {
|
|
11
|
+
this.mode = 'READ WRITE';
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
readOnly() {
|
|
15
|
+
this.mode = 'READ ONLY';
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
deferrable() {
|
|
19
|
+
this.__deferrable = true;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
notDeferrable() {
|
|
23
|
+
this.__deferrable = false;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
begin() {
|
|
27
|
+
let sql = 'BEGIN';
|
|
28
|
+
const options = [];
|
|
29
|
+
if (this.isolationLevel) {
|
|
30
|
+
options.push(`ISOLATION LEVEL ${this.isolationLevel}`);
|
|
31
|
+
}
|
|
32
|
+
if (this.mode) {
|
|
33
|
+
options.push(this.mode);
|
|
34
|
+
}
|
|
35
|
+
if (this.__deferrable !== undefined) {
|
|
36
|
+
options.push(this.__deferrable ? 'DEFERRABLE' : 'NOT DEFERRABLE');
|
|
37
|
+
}
|
|
38
|
+
if (options.length > 0) {
|
|
39
|
+
sql += ` ${options.join(', ')}`;
|
|
40
|
+
}
|
|
41
|
+
return sql;
|
|
42
|
+
}
|
|
43
|
+
commit() {
|
|
44
|
+
return 'COMMIT';
|
|
45
|
+
}
|
|
46
|
+
rollback() {
|
|
47
|
+
return 'ROLLBACK';
|
|
48
|
+
}
|
|
49
|
+
toString() {
|
|
50
|
+
return this.begin();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class SavepointBuilder {
|
|
54
|
+
savepointName;
|
|
55
|
+
constructor(savepointName) {
|
|
56
|
+
this.savepointName = savepointName;
|
|
57
|
+
}
|
|
58
|
+
create() {
|
|
59
|
+
return `SAVEPOINT ${format.ident(this.savepointName)}`;
|
|
60
|
+
}
|
|
61
|
+
rollback() {
|
|
62
|
+
return `ROLLBACK TO SAVEPOINT ${format.ident(this.savepointName)}`;
|
|
63
|
+
}
|
|
64
|
+
release() {
|
|
65
|
+
return `RELEASE SAVEPOINT ${format.ident(this.savepointName)}`;
|
|
66
|
+
}
|
|
67
|
+
toString() {
|
|
68
|
+
return this.create();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function isColumnAlias(col) {
|
|
2
|
+
return Array.isArray(col) && col.length === 2;
|
|
3
|
+
}
|
|
4
|
+
export function isAggregateColumn(col) {
|
|
5
|
+
return /^[a-z_]+\(/i.test(col);
|
|
6
|
+
}
|
|
7
|
+
export function getColumnName(col) {
|
|
8
|
+
return isColumnAlias(col) ? col[0] : col;
|
|
9
|
+
}
|
|
10
|
+
export function getResultKey(col) {
|
|
11
|
+
return isColumnAlias(col) ? col[1] : col;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import format from "../shared/pg-format.js";
|
|
2
|
+
export class ArrayStringUpdateBuilder {
|
|
3
|
+
set(values) {
|
|
4
|
+
if (values.length === 0)
|
|
5
|
+
return 'ARRAY[]::text[]';
|
|
6
|
+
const formatted = values.map(v => format('%L', v)).join(',');
|
|
7
|
+
return `ARRAY[${formatted}]`;
|
|
8
|
+
}
|
|
9
|
+
append(value) {
|
|
10
|
+
return format('array_append(%I, %L)', this.getContextColumn(), value);
|
|
11
|
+
}
|
|
12
|
+
prepend(value) {
|
|
13
|
+
return format('array_prepend(%L, %I)', value, this.getContextColumn());
|
|
14
|
+
}
|
|
15
|
+
remove(value) {
|
|
16
|
+
return format('array_remove(%I, %L)', this.getContextColumn(), value);
|
|
17
|
+
}
|
|
18
|
+
concat(values) {
|
|
19
|
+
if (values.length === 0)
|
|
20
|
+
return format('%I', this.getContextColumn());
|
|
21
|
+
const formatted = values.map(v => format('%L', v)).join(',');
|
|
22
|
+
return format('%I || ARRAY[%s]', this.getContextColumn(), formatted);
|
|
23
|
+
}
|
|
24
|
+
getContextColumn() {
|
|
25
|
+
return '__COLUMN__';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class ArrayNumericUpdateBuilder {
|
|
29
|
+
set(values) {
|
|
30
|
+
if (values.length === 0)
|
|
31
|
+
return 'ARRAY[]::integer[]';
|
|
32
|
+
return `ARRAY[${values.join(',')}]`;
|
|
33
|
+
}
|
|
34
|
+
append(value) {
|
|
35
|
+
return format('array_append(%I, %s)', this.getContextColumn(), value);
|
|
36
|
+
}
|
|
37
|
+
prepend(value) {
|
|
38
|
+
return format('array_prepend(%s, %I)', value, this.getContextColumn());
|
|
39
|
+
}
|
|
40
|
+
remove(value) {
|
|
41
|
+
return format('array_remove(%I, %s)', this.getContextColumn(), value);
|
|
42
|
+
}
|
|
43
|
+
concat(values) {
|
|
44
|
+
if (values.length === 0)
|
|
45
|
+
return format('%I', this.getContextColumn());
|
|
46
|
+
return format('%I || ARRAY[%s]', this.getContextColumn(), values.join(','));
|
|
47
|
+
}
|
|
48
|
+
getContextColumn() {
|
|
49
|
+
return '__COLUMN__';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export class ArrayBooleanUpdateBuilder {
|
|
53
|
+
set(values) {
|
|
54
|
+
if (values.length === 0)
|
|
55
|
+
return 'ARRAY[]::boolean[]';
|
|
56
|
+
return `ARRAY[${values.map(v => v.toString()).join(',')}]`;
|
|
57
|
+
}
|
|
58
|
+
append(value) {
|
|
59
|
+
return format('array_append(%I, %s)', this.getContextColumn(), value.toString());
|
|
60
|
+
}
|
|
61
|
+
prepend(value) {
|
|
62
|
+
return format('array_prepend(%s, %I)', value.toString(), this.getContextColumn());
|
|
63
|
+
}
|
|
64
|
+
remove(value) {
|
|
65
|
+
return format('array_remove(%I, %s)', this.getContextColumn(), value.toString());
|
|
66
|
+
}
|
|
67
|
+
concat(values) {
|
|
68
|
+
if (values.length === 0)
|
|
69
|
+
return format('%I', this.getContextColumn());
|
|
70
|
+
return format('%I || ARRAY[%s]', this.getContextColumn(), values.map(v => v.toString()).join(','));
|
|
71
|
+
}
|
|
72
|
+
getContextColumn() {
|
|
73
|
+
return '__COLUMN__';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export class ArrayUuidUpdateBuilder {
|
|
77
|
+
set(values) {
|
|
78
|
+
if (values.length === 0)
|
|
79
|
+
return 'ARRAY[]::uuid[]';
|
|
80
|
+
const formatted = values.map(v => format('%L::uuid', v)).join(',');
|
|
81
|
+
return `ARRAY[${formatted}]`;
|
|
82
|
+
}
|
|
83
|
+
append(value) {
|
|
84
|
+
return format('array_append(%I, %L::uuid)', this.getContextColumn(), value);
|
|
85
|
+
}
|
|
86
|
+
prepend(value) {
|
|
87
|
+
return format('array_prepend(%L::uuid, %I)', value, this.getContextColumn());
|
|
88
|
+
}
|
|
89
|
+
remove(value) {
|
|
90
|
+
return format('array_remove(%I, %L::uuid)', this.getContextColumn(), value);
|
|
91
|
+
}
|
|
92
|
+
concat(values) {
|
|
93
|
+
if (values.length === 0)
|
|
94
|
+
return format('%I', this.getContextColumn());
|
|
95
|
+
const formatted = values.map(v => format('%L::uuid', v)).join(',');
|
|
96
|
+
return format('%I || ARRAY[%s]', this.getContextColumn(), formatted);
|
|
97
|
+
}
|
|
98
|
+
getContextColumn() {
|
|
99
|
+
return '__COLUMN__';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export class ArrayDateUpdateBuilder {
|
|
103
|
+
set(values) {
|
|
104
|
+
if (values.length === 0)
|
|
105
|
+
return 'ARRAY[]::timestamp[]';
|
|
106
|
+
const formatted = values.map(v => {
|
|
107
|
+
const dateStr = v instanceof Date ? v.toISOString() : v;
|
|
108
|
+
return format('%L::timestamp', dateStr);
|
|
109
|
+
}).join(',');
|
|
110
|
+
return `ARRAY[${formatted}]`;
|
|
111
|
+
}
|
|
112
|
+
append(value) {
|
|
113
|
+
const dateStr = value instanceof Date ? value.toISOString() : value;
|
|
114
|
+
return format('array_append(%I, %L::timestamp)', this.getContextColumn(), dateStr);
|
|
115
|
+
}
|
|
116
|
+
prepend(value) {
|
|
117
|
+
const dateStr = value instanceof Date ? value.toISOString() : value;
|
|
118
|
+
return format('array_prepend(%L::timestamp, %I)', dateStr, this.getContextColumn());
|
|
119
|
+
}
|
|
120
|
+
remove(value) {
|
|
121
|
+
const dateStr = value instanceof Date ? value.toISOString() : value;
|
|
122
|
+
return format('array_remove(%I, %L::timestamp)', this.getContextColumn(), dateStr);
|
|
123
|
+
}
|
|
124
|
+
concat(values) {
|
|
125
|
+
if (values.length === 0)
|
|
126
|
+
return format('%I', this.getContextColumn());
|
|
127
|
+
const formatted = values.map(v => {
|
|
128
|
+
const dateStr = v instanceof Date ? v.toISOString() : v;
|
|
129
|
+
return format('%L::timestamp', dateStr);
|
|
130
|
+
}).join(',');
|
|
131
|
+
return format('%I || ARRAY[%s]', this.getContextColumn(), formatted);
|
|
132
|
+
}
|
|
133
|
+
getContextColumn() {
|
|
134
|
+
return '__COLUMN__';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export class ArrayJsonbUpdateBuilder {
|
|
138
|
+
set(values) {
|
|
139
|
+
if (values.length === 0)
|
|
140
|
+
return 'ARRAY[]::jsonb[]';
|
|
141
|
+
const formatted = values.map(v => format('%L::jsonb', JSON.stringify(v))).join(',');
|
|
142
|
+
return `ARRAY[${formatted}]`;
|
|
143
|
+
}
|
|
144
|
+
append(value) {
|
|
145
|
+
return format('array_append(%I, %L::jsonb)', this.getContextColumn(), JSON.stringify(value));
|
|
146
|
+
}
|
|
147
|
+
prepend(value) {
|
|
148
|
+
return format('array_prepend(%L::jsonb, %I)', JSON.stringify(value), this.getContextColumn());
|
|
149
|
+
}
|
|
150
|
+
remove(value) {
|
|
151
|
+
return format('array_remove(%I, %L::jsonb)', this.getContextColumn(), JSON.stringify(value));
|
|
152
|
+
}
|
|
153
|
+
concat(values) {
|
|
154
|
+
if (values.length === 0)
|
|
155
|
+
return format('%I', this.getContextColumn());
|
|
156
|
+
const formatted = values.map(v => format('%L::jsonb', JSON.stringify(v))).join(',');
|
|
157
|
+
return format('%I || ARRAY[%s]', this.getContextColumn(), formatted);
|
|
158
|
+
}
|
|
159
|
+
removeWhere(key, value) {
|
|
160
|
+
const formattedValue = format('%L', value);
|
|
161
|
+
return `ARRAY(SELECT elem FROM unnest(${format('%I', this.getContextColumn())}) AS elem WHERE elem->>${format('%L', key)} != ${formattedValue})`;
|
|
162
|
+
}
|
|
163
|
+
removeWhereAll(conditions) {
|
|
164
|
+
const whereClauses = Object.entries(conditions)
|
|
165
|
+
.map(([key, value]) => `elem->>${format('%L', key)} = ${format('%L', value)}`)
|
|
166
|
+
.join(' AND ');
|
|
167
|
+
return `ARRAY(SELECT elem FROM unnest(${format('%I', this.getContextColumn())}) AS elem WHERE NOT (${whereClauses}))`;
|
|
168
|
+
}
|
|
169
|
+
filterWhere(key, value) {
|
|
170
|
+
const formattedValue = format('%L', value);
|
|
171
|
+
return `ARRAY(SELECT elem FROM unnest(${format('%I', this.getContextColumn())}) AS elem WHERE elem->>${format('%L', key)} = ${formattedValue})`;
|
|
172
|
+
}
|
|
173
|
+
updateWhere(matchKey, matchValue, updates) {
|
|
174
|
+
const matchCondition = `elem->>${format('%L', matchKey)} = ${format('%L', matchValue)}`;
|
|
175
|
+
const updateEntries = Object.entries(updates);
|
|
176
|
+
if (updateEntries.length === 0) {
|
|
177
|
+
return format('%I', this.getContextColumn());
|
|
178
|
+
}
|
|
179
|
+
let setExpr = 'elem';
|
|
180
|
+
for (const [key, value] of updateEntries) {
|
|
181
|
+
const jsonbValue = typeof value === 'string' ? `"${value}"` : JSON.stringify(value);
|
|
182
|
+
setExpr = `jsonb_set(${setExpr}, ${format('%L', `{${key}}`)}, ${format('%L', jsonbValue)}::jsonb)`;
|
|
183
|
+
}
|
|
184
|
+
return `ARRAY(SELECT CASE WHEN ${matchCondition} THEN ${setExpr} ELSE elem END FROM unnest(${format('%I', this.getContextColumn())}) AS elem)`;
|
|
185
|
+
}
|
|
186
|
+
getContextColumn() {
|
|
187
|
+
return '__COLUMN__';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export class ArrayUpdateBuilder {
|
|
191
|
+
currentColumn;
|
|
192
|
+
constructor(currentColumn) {
|
|
193
|
+
this.currentColumn = currentColumn;
|
|
194
|
+
}
|
|
195
|
+
get string() {
|
|
196
|
+
return new ArrayStringUpdateBuilder();
|
|
197
|
+
}
|
|
198
|
+
get numeric() {
|
|
199
|
+
return new ArrayNumericUpdateBuilder();
|
|
200
|
+
}
|
|
201
|
+
get integer() {
|
|
202
|
+
return this.numeric;
|
|
203
|
+
}
|
|
204
|
+
get boolean() {
|
|
205
|
+
return new ArrayBooleanUpdateBuilder();
|
|
206
|
+
}
|
|
207
|
+
get uuid() {
|
|
208
|
+
return new ArrayUuidUpdateBuilder();
|
|
209
|
+
}
|
|
210
|
+
get date() {
|
|
211
|
+
return new ArrayDateUpdateBuilder();
|
|
212
|
+
}
|
|
213
|
+
get timestamp() {
|
|
214
|
+
return this.date;
|
|
215
|
+
}
|
|
216
|
+
get jsonb() {
|
|
217
|
+
return new ArrayJsonbUpdateBuilder();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { UpdateBuilder } from "./update-builder.js";
|
|
2
|
+
export { ArrayUpdateBuilder, ArrayStringUpdateBuilder, ArrayNumericUpdateBuilder, ArrayBooleanUpdateBuilder, ArrayUuidUpdateBuilder, ArrayDateUpdateBuilder, ArrayJsonbUpdateBuilder } from "./array-update-builder.js";
|
|
3
|
+
export { JsonbUpdateBuilder, JsonbArrayBuilder } from "./jsonb-update-builder.js";
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import format from "../shared/pg-format.js";
|
|
2
|
+
export class JsonbArrayBuilder {
|
|
3
|
+
currentColumn;
|
|
4
|
+
constructor(currentColumn) {
|
|
5
|
+
this.currentColumn = currentColumn;
|
|
6
|
+
}
|
|
7
|
+
set(values) {
|
|
8
|
+
return format('%L::jsonb', JSON.stringify(values));
|
|
9
|
+
}
|
|
10
|
+
append(value) {
|
|
11
|
+
return format('COALESCE(%I, \'[]\'::jsonb) || %L::jsonb', this.currentColumn, JSON.stringify([value]));
|
|
12
|
+
}
|
|
13
|
+
prepend(value) {
|
|
14
|
+
return format('%L::jsonb || COALESCE(%I, \'[]\'::jsonb)', JSON.stringify([value]), this.currentColumn);
|
|
15
|
+
}
|
|
16
|
+
concat(values) {
|
|
17
|
+
if (values.length === 0) {
|
|
18
|
+
return format('COALESCE(%I, \'[]\'::jsonb)', this.currentColumn);
|
|
19
|
+
}
|
|
20
|
+
return format('COALESCE(%I, \'[]\'::jsonb) || %L::jsonb', this.currentColumn, JSON.stringify(values));
|
|
21
|
+
}
|
|
22
|
+
insertAt(index, value) {
|
|
23
|
+
return format('jsonb_insert(COALESCE(%I, \'[]\'::jsonb), %L, %L::jsonb)', this.currentColumn, `{${index}}`, JSON.stringify(value));
|
|
24
|
+
}
|
|
25
|
+
removeAt(index) {
|
|
26
|
+
return format('COALESCE(%I, \'[]\'::jsonb) - %s', this.currentColumn, index);
|
|
27
|
+
}
|
|
28
|
+
shift() {
|
|
29
|
+
return this.removeAt(0);
|
|
30
|
+
}
|
|
31
|
+
pop() {
|
|
32
|
+
return this.removeAt(-1);
|
|
33
|
+
}
|
|
34
|
+
removeWhere(key, value) {
|
|
35
|
+
const formattedValue = format('%L', value);
|
|
36
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem WHERE elem->>${format('%L', key)} != ${formattedValue}), '[]'::jsonb)`;
|
|
37
|
+
}
|
|
38
|
+
removeWhereAll(conditions) {
|
|
39
|
+
const whereClauses = Object.entries(conditions)
|
|
40
|
+
.map(([key, value]) => `elem->>${format('%L', key)} = ${format('%L', value)}`)
|
|
41
|
+
.join(' AND ');
|
|
42
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem WHERE NOT (${whereClauses})), '[]'::jsonb)`;
|
|
43
|
+
}
|
|
44
|
+
filter(key, value) {
|
|
45
|
+
const formattedValue = format('%L', value);
|
|
46
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem WHERE elem->>${format('%L', key)} = ${formattedValue}), '[]'::jsonb)`;
|
|
47
|
+
}
|
|
48
|
+
filterAll(conditions) {
|
|
49
|
+
const whereClauses = Object.entries(conditions)
|
|
50
|
+
.map(([key, value]) => `elem->>${format('%L', key)} = ${format('%L', value)}`)
|
|
51
|
+
.join(' AND ');
|
|
52
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem WHERE ${whereClauses}), '[]'::jsonb)`;
|
|
53
|
+
}
|
|
54
|
+
updateAt(index, newValue) {
|
|
55
|
+
return format('jsonb_set(COALESCE(%I, \'[]\'::jsonb), %L, %L::jsonb)', this.currentColumn, `{${index}}`, JSON.stringify(newValue));
|
|
56
|
+
}
|
|
57
|
+
updateWhere(matchKey, matchValue, updates) {
|
|
58
|
+
const matchCondition = `elem->>${format('%L', matchKey)} = ${format('%L', matchValue)}`;
|
|
59
|
+
const updateEntries = Object.entries(updates);
|
|
60
|
+
if (updateEntries.length === 0) {
|
|
61
|
+
return format('COALESCE(%I, \'[]\'::jsonb)', this.currentColumn);
|
|
62
|
+
}
|
|
63
|
+
let setExpr = 'elem';
|
|
64
|
+
for (const [key, value] of updateEntries) {
|
|
65
|
+
const jsonbValue = typeof value === 'string' ? `"${value}"` : JSON.stringify(value);
|
|
66
|
+
setExpr = `jsonb_set(${setExpr}, ${format('%L', `{${key}}`)}, ${format('%L', jsonbValue)}::jsonb)`;
|
|
67
|
+
}
|
|
68
|
+
return `COALESCE((SELECT jsonb_agg(CASE WHEN ${matchCondition} THEN ${setExpr} ELSE elem END) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem), '[]'::jsonb)`;
|
|
69
|
+
}
|
|
70
|
+
reverse() {
|
|
71
|
+
return `COALESCE((SELECT jsonb_agg(elem ORDER BY idx DESC) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) WITH ORDINALITY AS t(elem, idx)), '[]'::jsonb)`;
|
|
72
|
+
}
|
|
73
|
+
unique() {
|
|
74
|
+
return `COALESCE((SELECT jsonb_agg(DISTINCT elem) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem), '[]'::jsonb)`;
|
|
75
|
+
}
|
|
76
|
+
uniqueBy(key) {
|
|
77
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM (SELECT DISTINCT ON (elem->>${format('%L', key)}) elem FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem) t), '[]'::jsonb)`;
|
|
78
|
+
}
|
|
79
|
+
sortBy(key, direction = 'ASC') {
|
|
80
|
+
return `COALESCE((SELECT jsonb_agg(elem ORDER BY elem->>${format('%L', key)} ${direction}) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem), '[]'::jsonb)`;
|
|
81
|
+
}
|
|
82
|
+
slice(start, end) {
|
|
83
|
+
if (end === undefined) {
|
|
84
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM (SELECT elem FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) WITH ORDINALITY AS t(elem, idx) WHERE idx > ${start}) t), '[]'::jsonb)`;
|
|
85
|
+
}
|
|
86
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM (SELECT elem FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) WITH ORDINALITY AS t(elem, idx) WHERE idx > ${start} AND idx <= ${end}) t), '[]'::jsonb)`;
|
|
87
|
+
}
|
|
88
|
+
take(n) {
|
|
89
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM (SELECT elem FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) WITH ORDINALITY AS t(elem, idx) WHERE idx <= ${n}) t), '[]'::jsonb)`;
|
|
90
|
+
}
|
|
91
|
+
skip(n) {
|
|
92
|
+
return `COALESCE((SELECT jsonb_agg(elem) FROM (SELECT elem FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) WITH ORDINALITY AS t(elem, idx) WHERE idx > ${n}) t), '[]'::jsonb)`;
|
|
93
|
+
}
|
|
94
|
+
mapSet(key, value) {
|
|
95
|
+
const jsonbValue = typeof value === 'string' ? `"${value}"` : JSON.stringify(value);
|
|
96
|
+
return `COALESCE((SELECT jsonb_agg(jsonb_set(elem, ${format('%L', `{${key}}`)}, ${format('%L', jsonbValue)}::jsonb)) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem), '[]'::jsonb)`;
|
|
97
|
+
}
|
|
98
|
+
mapIncrement(key, amount = 1) {
|
|
99
|
+
return `COALESCE((SELECT jsonb_agg(jsonb_set(elem, ${format('%L', `{${key}}`)}, ((COALESCE((elem->>${format('%L', key)})::numeric, 0) + ${amount})::text)::jsonb)) FROM jsonb_array_elements(COALESCE(${format('%I', this.currentColumn)}, '[]'::jsonb)) elem), '[]'::jsonb)`;
|
|
100
|
+
}
|
|
101
|
+
mapDecrement(key, amount = 1) {
|
|
102
|
+
return this.mapIncrement(key, -amount);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export class JsonbUpdateBuilder {
|
|
106
|
+
currentColumn;
|
|
107
|
+
_array = null;
|
|
108
|
+
constructor(currentColumn = '__COLUMN__') {
|
|
109
|
+
this.currentColumn = currentColumn;
|
|
110
|
+
}
|
|
111
|
+
get array() {
|
|
112
|
+
if (!this._array) {
|
|
113
|
+
this._array = new JsonbArrayBuilder(this.currentColumn);
|
|
114
|
+
}
|
|
115
|
+
return this._array;
|
|
116
|
+
}
|
|
117
|
+
set(value) {
|
|
118
|
+
return format('%L::jsonb', JSON.stringify(value));
|
|
119
|
+
}
|
|
120
|
+
setField(path, value) {
|
|
121
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
122
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
123
|
+
const jsonbValue = typeof value === 'string' ? `"${value}"` : JSON.stringify(value);
|
|
124
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, %L::jsonb, true)', this.currentColumn, pathStr, jsonbValue);
|
|
125
|
+
}
|
|
126
|
+
removeField(key) {
|
|
127
|
+
if (Array.isArray(key)) {
|
|
128
|
+
const pathStr = `{${key.join(',')}}`;
|
|
129
|
+
return format('COALESCE(%I, \'{}\'::jsonb) #- %L', this.currentColumn, pathStr);
|
|
130
|
+
}
|
|
131
|
+
return format('COALESCE(%I, \'{}\'::jsonb) - %L', this.currentColumn, key);
|
|
132
|
+
}
|
|
133
|
+
removeFields(keys) {
|
|
134
|
+
if (keys.length === 0) {
|
|
135
|
+
return format('COALESCE(%I, \'{}\'::jsonb)', this.currentColumn);
|
|
136
|
+
}
|
|
137
|
+
const keysArray = keys.map(k => format('%L', k)).join(', ');
|
|
138
|
+
return format('COALESCE(%I, \'{}\'::jsonb) - ARRAY[%s]', this.currentColumn, keysArray);
|
|
139
|
+
}
|
|
140
|
+
merge(obj) {
|
|
141
|
+
return format('COALESCE(%I, \'{}\'::jsonb) || %L::jsonb', this.currentColumn, JSON.stringify(obj));
|
|
142
|
+
}
|
|
143
|
+
deepMerge(obj) {
|
|
144
|
+
const entries = Object.entries(obj);
|
|
145
|
+
if (entries.length === 0) {
|
|
146
|
+
return format('COALESCE(%I, \'{}\'::jsonb)', this.currentColumn);
|
|
147
|
+
}
|
|
148
|
+
let result = format('COALESCE(%I, \'{}\'::jsonb)', this.currentColumn);
|
|
149
|
+
for (const [key, value] of entries) {
|
|
150
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
151
|
+
result = format('jsonb_set(%s, %L, COALESCE(%I->%L, \'{}\'::jsonb) || %L::jsonb, true)', result, `{${key}}`, this.currentColumn, key, JSON.stringify(value));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const jsonbValue = typeof value === 'string' ? `"${value}"` : JSON.stringify(value);
|
|
155
|
+
result = format('jsonb_set(%s, %L, %L::jsonb, true)', result, `{${key}}`, jsonbValue);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
renameField(oldKey, newKey) {
|
|
161
|
+
return format('(COALESCE(%I, \'{}\'::jsonb) || jsonb_build_object(%L, %I->%L)) - %L', this.currentColumn, newKey, this.currentColumn, oldKey, oldKey);
|
|
162
|
+
}
|
|
163
|
+
increment(path, amount = 1) {
|
|
164
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
165
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
166
|
+
const extractExpr = pathArray.length === 1
|
|
167
|
+
? format('%I->>%L', this.currentColumn, pathArray[0])
|
|
168
|
+
: format('%I#>>%L', this.currentColumn, pathStr);
|
|
169
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, ((COALESCE((%s)::numeric, 0) + %s)::text)::jsonb, true)', this.currentColumn, pathStr, extractExpr, amount);
|
|
170
|
+
}
|
|
171
|
+
decrement(path, amount = 1) {
|
|
172
|
+
return this.increment(path, -amount);
|
|
173
|
+
}
|
|
174
|
+
multiply(path, factor) {
|
|
175
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
176
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
177
|
+
const extractExpr = pathArray.length === 1
|
|
178
|
+
? format('%I->>%L', this.currentColumn, pathArray[0])
|
|
179
|
+
: format('%I#>>%L', this.currentColumn, pathStr);
|
|
180
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, ((COALESCE((%s)::numeric, 0) * %s)::text)::jsonb, true)', this.currentColumn, pathStr, extractExpr, factor);
|
|
181
|
+
}
|
|
182
|
+
toggle(path) {
|
|
183
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
184
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
185
|
+
const extractExpr = pathArray.length === 1
|
|
186
|
+
? format('%I->%L', this.currentColumn, pathArray[0])
|
|
187
|
+
: format('%I#>%L', this.currentColumn, pathStr);
|
|
188
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, (NOT COALESCE((%s)::boolean, false))::text::jsonb, true)', this.currentColumn, pathStr, extractExpr);
|
|
189
|
+
}
|
|
190
|
+
setTimestamp(path) {
|
|
191
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
192
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
193
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, to_jsonb(NOW()), true)', this.currentColumn, pathStr);
|
|
194
|
+
}
|
|
195
|
+
appendString(path, suffix) {
|
|
196
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
197
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
198
|
+
const extractExpr = pathArray.length === 1
|
|
199
|
+
? format('%I->>%L', this.currentColumn, pathArray[0])
|
|
200
|
+
: format('%I#>>%L', this.currentColumn, pathStr);
|
|
201
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, to_jsonb(COALESCE(%s, \'\') || %L), true)', this.currentColumn, pathStr, extractExpr, suffix);
|
|
202
|
+
}
|
|
203
|
+
prependString(path, prefix) {
|
|
204
|
+
const pathArray = Array.isArray(path) ? path : [path];
|
|
205
|
+
const pathStr = `{${pathArray.join(',')}}`;
|
|
206
|
+
const extractExpr = pathArray.length === 1
|
|
207
|
+
? format('%I->>%L', this.currentColumn, pathArray[0])
|
|
208
|
+
: format('%I#>>%L', this.currentColumn, pathStr);
|
|
209
|
+
return format('jsonb_set(COALESCE(%I, \'{}\'::jsonb), %L, to_jsonb(%L || COALESCE(%s, \'\')), true)', this.currentColumn, pathStr, prefix, extractExpr);
|
|
210
|
+
}
|
|
211
|
+
}
|