jsonbadger 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -18
- package/docs/api/connection.md +144 -0
- package/docs/api/delta-tracker.md +106 -0
- package/docs/api/document.md +77 -0
- package/docs/api/field-types.md +329 -0
- package/docs/api/index.md +35 -0
- package/docs/api/model.md +392 -0
- package/docs/api/query-builder.md +81 -0
- package/docs/api/schema.md +204 -0
- package/docs/architecture-flow.md +397 -0
- package/docs/examples.md +495 -218
- package/docs/jsonb-ops.md +171 -0
- package/docs/lifecycle/model-compilation.md +111 -0
- package/docs/lifecycle.md +146 -0
- package/docs/query-translation.md +11 -10
- package/package.json +10 -3
- package/src/connection/connect.js +12 -17
- package/src/connection/connection.js +128 -0
- package/src/connection/server-capabilities.js +60 -59
- package/src/constants/defaults.js +32 -19
- package/src/constants/{id-strategies.js → id-strategy.js} +28 -29
- package/src/constants/intake-mode.js +8 -0
- package/src/debug/debug-logger.js +17 -15
- package/src/errors/model-overwrite-error.js +25 -0
- package/src/errors/query-error.js +25 -23
- package/src/errors/validation-error.js +25 -23
- package/src/field-types/base-field-type.js +137 -140
- package/src/field-types/builtins/advanced.js +365 -365
- package/src/field-types/builtins/index.js +579 -585
- package/src/field-types/field-type-namespace.js +9 -0
- package/src/field-types/registry.js +149 -122
- package/src/index.js +26 -36
- package/src/migration/ensure-index.js +157 -154
- package/src/migration/ensure-schema.js +27 -15
- package/src/migration/ensure-table.js +44 -31
- package/src/migration/schema-indexes-resolver.js +8 -6
- package/src/model/document-instance.js +29 -540
- package/src/model/document.js +60 -0
- package/src/model/factory/constants.js +36 -0
- package/src/model/factory/index.js +58 -0
- package/src/model/model.js +875 -0
- package/src/model/operations/delete-one.js +39 -0
- package/src/model/operations/insert-one.js +35 -0
- package/src/model/operations/query-builder.js +132 -0
- package/src/model/operations/update-one.js +333 -0
- package/src/model/state.js +34 -0
- package/src/schema/field-definition-parser.js +213 -218
- package/src/schema/path-introspection.js +87 -82
- package/src/schema/schema-compiler.js +126 -212
- package/src/schema/schema.js +621 -138
- package/src/sql/index.js +17 -0
- package/src/sql/jsonb/ops.js +153 -0
- package/src/{query → sql/jsonb}/path-parser.js +54 -43
- package/src/sql/jsonb/read/elem-match.js +133 -0
- package/src/{query → sql/jsonb/read}/operators/contains.js +13 -7
- package/src/sql/jsonb/read/operators/elem-match.js +9 -0
- package/src/{query → sql/jsonb/read}/operators/has-all-keys.js +17 -11
- package/src/{query → sql/jsonb/read}/operators/has-any-keys.js +18 -11
- package/src/sql/jsonb/read/operators/has-key.js +12 -0
- package/src/{query → sql/jsonb/read}/operators/jsonpath-exists.js +22 -15
- package/src/{query → sql/jsonb/read}/operators/jsonpath-match.js +22 -15
- package/src/{query → sql/jsonb/read}/operators/size.js +23 -16
- package/src/sql/parameter-binder.js +18 -13
- package/src/sql/read/build-count-query.js +12 -0
- package/src/sql/read/build-find-query.js +25 -0
- package/src/sql/read/limit-skip.js +21 -0
- package/src/sql/read/sort.js +85 -0
- package/src/sql/read/where/base-fields.js +310 -0
- package/src/sql/read/where/casting.js +90 -0
- package/src/sql/read/where/context.js +79 -0
- package/src/sql/read/where/field-clause.js +58 -0
- package/src/sql/read/where/index.js +38 -0
- package/src/sql/read/where/operator-entries.js +29 -0
- package/src/{query → sql/read/where}/operators/all.js +16 -10
- package/src/sql/read/where/operators/eq.js +12 -0
- package/src/{query → sql/read/where}/operators/gt.js +23 -16
- package/src/{query → sql/read/where}/operators/gte.js +23 -16
- package/src/{query → sql/read/where}/operators/in.js +18 -12
- package/src/sql/read/where/operators/index.js +40 -0
- package/src/{query → sql/read/where}/operators/lt.js +23 -16
- package/src/{query → sql/read/where}/operators/lte.js +23 -16
- package/src/sql/read/where/operators/ne.js +12 -0
- package/src/{query → sql/read/where}/operators/nin.js +18 -12
- package/src/{query → sql/read/where}/operators/regex.js +14 -8
- package/src/sql/read/where/operators.js +126 -0
- package/src/sql/read/where/text-operators.js +83 -0
- package/src/sql/run.js +46 -0
- package/src/sql/write/build-delete-query.js +33 -0
- package/src/sql/write/build-insert-query.js +42 -0
- package/src/sql/write/build-update-query.js +65 -0
- package/src/utils/assert.js +34 -27
- package/src/utils/delta-tracker/.archive/1 tracker-redesign-codex-v2.md +250 -0
- package/src/utils/delta-tracker/.archive/1 tracker-redesign-gemini.md +101 -0
- package/src/utils/delta-tracker/.archive/2 evaluation by gemini.txt +65 -0
- package/src/utils/delta-tracker/.archive/2 evaluation by grok.txt +39 -0
- package/src/utils/delta-tracker/.archive/3 gemini evaluate grok.txt +37 -0
- package/src/utils/delta-tracker/.archive/3 grok evaluate gemini.txt +63 -0
- package/src/utils/delta-tracker/.archive/4 gemini veredict.txt +16 -0
- package/src/utils/delta-tracker/.archive/index.1.js +587 -0
- package/src/utils/delta-tracker/.archive/index.2.js +612 -0
- package/src/utils/delta-tracker/index.js +592 -0
- package/src/utils/dirty-tracker/inline.js +335 -0
- package/src/utils/dirty-tracker/instance.js +414 -0
- package/src/utils/dirty-tracker/static.js +343 -0
- package/src/utils/json-safe.js +13 -9
- package/src/utils/object-path.js +227 -33
- package/src/utils/object.js +408 -168
- package/src/utils/string.js +55 -0
- package/src/utils/value.js +169 -30
- package/docs/api.md +0 -152
- package/src/connection/disconnect.js +0 -16
- package/src/connection/pool-store.js +0 -46
- package/src/model/model-factory.js +0 -555
- package/src/query/limit-skip-compiler.js +0 -31
- package/src/query/operators/elem-match.js +0 -3
- package/src/query/operators/eq.js +0 -6
- package/src/query/operators/has-key.js +0 -6
- package/src/query/operators/index.js +0 -60
- package/src/query/operators/ne.js +0 -6
- package/src/query/query-builder.js +0 -93
- package/src/query/sort-compiler.js +0 -30
- package/src/query/where-compiler.js +0 -477
- package/src/sql/sql-runner.js +0 -31
package/src/utils/value.js
CHANGED
|
@@ -1,30 +1,169 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
1
|
+
const uuidv7_pattern = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
2
|
+
|
|
3
|
+
function is_object(value) {
|
|
4
|
+
return typeof value === 'object'
|
|
5
|
+
&& !(value == null)
|
|
6
|
+
&& !(value instanceof Date)
|
|
7
|
+
&& !(value instanceof Map)
|
|
8
|
+
&& !(value instanceof Set)
|
|
9
|
+
&& !Array.isArray(value)
|
|
10
|
+
&& !ArrayBuffer.isView(value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function is_not_object(value) {
|
|
14
|
+
return typeof value !== 'object'
|
|
15
|
+
|| value == null
|
|
16
|
+
|| value instanceof Date
|
|
17
|
+
|| value instanceof Map
|
|
18
|
+
|| value instanceof Set
|
|
19
|
+
|| Array.isArray(value)
|
|
20
|
+
|| ArrayBuffer.isView(value);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Checks whether a value is a plain object with a null or default object prototype.
|
|
25
|
+
*
|
|
26
|
+
* @param {*} value Value to inspect.
|
|
27
|
+
* @returns {boolean}
|
|
28
|
+
*/
|
|
29
|
+
function is_plain_object(value) {
|
|
30
|
+
if(!is_object(value)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const prototype_value = Object.getPrototypeOf(value);
|
|
35
|
+
return prototype_value === Object.prototype || prototype_value === null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function is_nan(value) {
|
|
39
|
+
if(value === null || value === undefined) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const numeric_value = Number(value);
|
|
44
|
+
return Number.isNaN(numeric_value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Normalizes one value into a finite number, falling back to zero.
|
|
49
|
+
*
|
|
50
|
+
* @param {*} value Value to normalize.
|
|
51
|
+
* @returns {number}
|
|
52
|
+
*/
|
|
53
|
+
function to_number(value) {
|
|
54
|
+
const number = Number(value || 0);
|
|
55
|
+
return Number.isFinite(number) ? number : 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function to_int(value) {
|
|
59
|
+
return Math.floor(Number(value));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Checks whether one value is a valid UUIDv7 string.
|
|
64
|
+
*
|
|
65
|
+
* @param {*} value Value to inspect.
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
*/
|
|
68
|
+
function is_uuid_v7(value) {
|
|
69
|
+
if(typeof value !== 'string') {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return uuidv7_pattern.test(value);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function is_string(value) {
|
|
77
|
+
return typeof value === 'string';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function is_function(value) {
|
|
81
|
+
return typeof value === 'function';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function is_boolean(value) {
|
|
85
|
+
return typeof value === 'boolean';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function is_date(value) {
|
|
89
|
+
return value instanceof Date;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function is_not_date(value) {
|
|
93
|
+
return !(value instanceof Date);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function is_valid_timestamp(value) {
|
|
97
|
+
return !Number.isNaN(new Date(value).getTime());
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function to_iso_timestamp(value) {
|
|
101
|
+
// Treat falsy values as non-normalizable input and return them unchanged
|
|
102
|
+
// rather than assuming they represent a valid timestamp.
|
|
103
|
+
if(!value) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if(value instanceof Date) {
|
|
108
|
+
return value.toISOString();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const parsed_timestamp = new Date(value);
|
|
112
|
+
|
|
113
|
+
if(Number.isNaN(parsed_timestamp.getTime())) {
|
|
114
|
+
return String(value);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return parsed_timestamp.toISOString();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Returns the value if the evaluator passes, otherwise returns the default.
|
|
122
|
+
* @param {function} evaluator - The condition to check against.
|
|
123
|
+
* @param {any} value - The primary value to test.
|
|
124
|
+
* @param {any} default_value - The fallback value.
|
|
125
|
+
* @returns {any}
|
|
126
|
+
*/
|
|
127
|
+
function get_if(evaluator, value, default_value) {
|
|
128
|
+
if(evaluator(value)) {
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return default_value;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export {
|
|
136
|
+
is_object,
|
|
137
|
+
is_plain_object,
|
|
138
|
+
is_not_object,
|
|
139
|
+
is_nan,
|
|
140
|
+
is_uuid_v7,
|
|
141
|
+
to_int,
|
|
142
|
+
to_number,
|
|
143
|
+
is_string,
|
|
144
|
+
is_function,
|
|
145
|
+
is_boolean,
|
|
146
|
+
is_date,
|
|
147
|
+
is_not_date,
|
|
148
|
+
is_valid_timestamp,
|
|
149
|
+
to_iso_timestamp,
|
|
150
|
+
get_if
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export default {
|
|
154
|
+
is_object,
|
|
155
|
+
is_plain_object,
|
|
156
|
+
is_not_object,
|
|
157
|
+
is_nan,
|
|
158
|
+
is_uuid_v7,
|
|
159
|
+
to_int,
|
|
160
|
+
to_number,
|
|
161
|
+
is_string,
|
|
162
|
+
is_function,
|
|
163
|
+
is_boolean,
|
|
164
|
+
is_date,
|
|
165
|
+
is_not_date,
|
|
166
|
+
is_valid_timestamp,
|
|
167
|
+
to_iso_timestamp,
|
|
168
|
+
get_if
|
|
169
|
+
};
|
package/docs/api.md
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# jsonbadger API
|
|
2
|
-
|
|
3
|
-
## Top-level exports
|
|
4
|
-
|
|
5
|
-
Named exports:
|
|
6
|
-
- `connect(connection_uri, connection_options)`
|
|
7
|
-
- `disconnect()`
|
|
8
|
-
- `Schema`
|
|
9
|
-
- `IdStrategies`
|
|
10
|
-
- `model(schema_instance, model_options)`
|
|
11
|
-
- `create_field_type(path_value, type_reference, options?)`
|
|
12
|
-
- `register_field_type(type_name, type_constructor, references?)`
|
|
13
|
-
- `resolve_field_type(type_reference)`
|
|
14
|
-
|
|
15
|
-
Default export (`jsonbadger`) includes the same plus:
|
|
16
|
-
- `field_types.UUIDv7`
|
|
17
|
-
- `field_types.boolean_convert_to_true`
|
|
18
|
-
- `field_types.boolean_convert_to_false`
|
|
19
|
-
|
|
20
|
-
## connect
|
|
21
|
-
|
|
22
|
-
`connect(connection_uri, connection_options)` opens (or reuses) a shared PostgreSQL pool.
|
|
23
|
-
|
|
24
|
-
`connection_options`:
|
|
25
|
-
- `max`: pool size (default `10`)
|
|
26
|
-
- `debug`: logs SQL/debug events when `true`
|
|
27
|
-
- `auto_index`: server-wide default for automatic index creation when `Model.ensure_table()` is called (default `true`)
|
|
28
|
-
- `id_strategy`: server-wide default row-id strategy (`IdStrategies.bigserial` or `IdStrategies.uuidv7`, default `IdStrategies.bigserial`)
|
|
29
|
-
- any `pg` pool options (`ssl`, `host`, `port`, `user`, `password`, `database`)
|
|
30
|
-
|
|
31
|
-
UUIDv7 compatibility behavior:
|
|
32
|
-
- `connect(...)` performs an internal PostgreSQL capability scan (server version + native `uuidv7()` function presence) and caches the result for later model/runtime checks.
|
|
33
|
-
- If the connection-level `id_strategy` resolves to `IdStrategies.uuidv7` and native support is unavailable, `connect(...)` fails fast.
|
|
34
|
-
- Model-level `uuidv7` overrides defined after `connect(...)` are validated on use with the cached capability metadata.
|
|
35
|
-
- Optional troubleshooting commands only: `SELECT version();` and `SHOW server_version;`. Runtime checks use machine-readable checks internally.
|
|
36
|
-
|
|
37
|
-
## schema
|
|
38
|
-
|
|
39
|
-
`new Schema(schema_def, options?)`
|
|
40
|
-
|
|
41
|
-
`Schema` is responsible for document structure and index declarations.
|
|
42
|
-
|
|
43
|
-
methods:
|
|
44
|
-
- `validate(payload)`
|
|
45
|
-
- `path(path_name)`
|
|
46
|
-
- `get_path_type(path_name)`
|
|
47
|
-
- `is_array_root(path_name)`
|
|
48
|
-
- `create_index(index_spec, index_options?)`
|
|
49
|
-
- `get_indexes()`
|
|
50
|
-
|
|
51
|
-
`create_index` supports:
|
|
52
|
-
- single-path index: `schema.create_index('profile.city')`
|
|
53
|
-
- compound index: `schema.create_index({name: 1, type: -1})`
|
|
54
|
-
- optional options: `unique` and `name`
|
|
55
|
-
|
|
56
|
-
Notes:
|
|
57
|
-
- Single-path string specs (`'profile.city'`) create GIN indexes and do not support `unique`.
|
|
58
|
-
- Object specs (`{field: 1}` / compound) create BTREE indexes and support `unique`.
|
|
59
|
-
|
|
60
|
-
Path-level sugar in schema definitions is also supported:
|
|
61
|
-
- `{name: {type: String, index: true}}` -> single-path index
|
|
62
|
-
- `{age: {type: Number, index: 1}}` -> ascending single-path spec
|
|
63
|
-
- `{age: {type: Number, index: -1}}` -> descending single-path spec
|
|
64
|
-
- `{email: {type: String, index: {unique: true, name: 'idx_users_email_unique'}}}` -> path-level index options
|
|
65
|
-
- optional direction in object form: `direction` or `order` (`1` or `-1`)
|
|
66
|
-
|
|
67
|
-
## model
|
|
68
|
-
|
|
69
|
-
`const User = model(user_schema, { table_name, data_column?, id_strategy?, auto_index? })`
|
|
70
|
-
|
|
71
|
-
- `table_name` is required.
|
|
72
|
-
- `data_column` defaults to `data`.
|
|
73
|
-
- `id_strategy` defaults to connection-level `id_strategy`, then library default `IdStrategies.bigserial`.
|
|
74
|
-
- `auto_index` defaults to model option if set, otherwise connection-level `auto_index`.
|
|
75
|
-
|
|
76
|
-
UUIDv7 notes:
|
|
77
|
-
- `IdStrategies.uuidv7` uses database-generated row IDs via table DDL (`id UUID PRIMARY KEY DEFAULT uuidv7()`).
|
|
78
|
-
- jsonbadger validates `uuidv7` support before uuidv7-backed table/schema/write paths using cached server capability metadata.
|
|
79
|
-
|
|
80
|
-
static methods:
|
|
81
|
-
- `ensure_table()`: manual migration call that ensures the table exists (for `IdStrategies.uuidv7`, table DDL uses `DEFAULT uuidv7()`); when `auto_index` is enabled, applies declared schema indexes once per model instance. First-write methods (`save()`, `update_one(...)`) can also create the table automatically.
|
|
82
|
-
- `ensure_index()`: ensures table exists and applies declared schema indexes immediately.
|
|
83
|
-
- `ensure_schema()`: ensures table and applies declared schema indexes.
|
|
84
|
-
- `find(query_filter, projection_value?)`
|
|
85
|
-
- `find_one(query_filter)`
|
|
86
|
-
- `count_documents(query_filter)`
|
|
87
|
-
- `update_one(query_filter, update_definition)`
|
|
88
|
-
- supported operators: `$set`, `$insert`, `$set_lax`
|
|
89
|
-
- operator application order is deterministic and nested: `$set` -> `$insert` -> `$set_lax`
|
|
90
|
-
- `$insert` maps to PostgreSQL `jsonb_insert(...)`
|
|
91
|
-
- `$set_lax` maps to PostgreSQL `jsonb_set_lax(...)` and supports object form `{ value, create_if_missing?, null_value_treatment? }`
|
|
92
|
-
- update paths allow numeric nested segments for JSON array indexes (for example, `tags.0`)
|
|
93
|
-
- conflicting update paths (same path or parent/child overlap across operators) are rejected before SQL execution
|
|
94
|
-
- `delete_one(query_filter)`
|
|
95
|
-
- deletes one matching row and returns the deleted document data
|
|
96
|
-
- returns `null` when no row matches
|
|
97
|
-
- does not implicitly call `ensure_table()`; if the table does not exist yet, returns `null`
|
|
98
|
-
|
|
99
|
-
instance methods:
|
|
100
|
-
- `validate()`
|
|
101
|
-
- `get(path_name, runtime_options?)`
|
|
102
|
-
- `set(path_name, value, runtime_options?)`
|
|
103
|
-
- `mark_modified(path_name)`
|
|
104
|
-
- `is_modified(path_name?)`
|
|
105
|
-
- `clear_modified()`
|
|
106
|
-
- `to_object(serialization_options?)`
|
|
107
|
-
- `to_json(serialization_options?)`
|
|
108
|
-
- `save()`
|
|
109
|
-
|
|
110
|
-
Runtime behavior notes:
|
|
111
|
-
- Read/query execution (`find(...).exec()`, `find_one(...).exec()`, `count_documents(...).exec()`) does not implicitly call `ensure_table()`.
|
|
112
|
-
- Use `ensure_table()` / `ensure_schema()` explicitly, or let a first write (`save()` / `update_one(...)`) create the table.
|
|
113
|
-
- `set(...)` applies field setters + casting by default and marks the path as modified.
|
|
114
|
-
- `mark_modified(path_name)` is required after in-place `Mixed`/`Date` mutations (for example mutating nested objects or calling `Date` mutator methods directly).
|
|
115
|
-
- `is_modified(path_name?)` and `clear_modified()` are available runtime helpers for dirty-path inspection/reset.
|
|
116
|
-
- `immutable: true` fields are writable before first persist and become protected after a successful `save()`.
|
|
117
|
-
- `to_object(...)` / `to_json(...)` apply getters by default; pass `{ getters: false }` to bypass getter transforms during serialization.
|
|
118
|
-
|
|
119
|
-
For built-in FieldType declaration examples and edge-case notes, see [`docs/examples.md`](examples.md).
|
|
120
|
-
|
|
121
|
-
For copy-paste usage examples (including all current query/update operators), see [`docs/examples.md`](examples.md). For PostgreSQL translation semantics, see [`docs/query-translation.md`](query-translation.md).
|
|
122
|
-
|
|
123
|
-
## query filters
|
|
124
|
-
|
|
125
|
-
Supported filter/operator families (current implemented set):
|
|
126
|
-
- scalar comparisons: direct equality, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`
|
|
127
|
-
- sets/arrays: `$in`, `$nin`, `$all`, `$size`, `$contains`, `$elem_match`
|
|
128
|
-
- regex: `$regex` (+ `$options`)
|
|
129
|
-
- JSONB key existence: `$has_key`, `$has_any_keys`, `$has_all_keys`
|
|
130
|
-
- JSONPath: `$json_path_exists`, `$json_path_match`
|
|
131
|
-
|
|
132
|
-
Existence semantics:
|
|
133
|
-
- `$has_key` / `$has_any_keys` / `$has_all_keys` map directly to PostgreSQL `?`, `?|`, and `?&`.
|
|
134
|
-
- These operators are top-level for the JSONB value on the left side of the operator.
|
|
135
|
-
- When used with a nested field path, jsonbadger extracts that nested JSONB value first, then applies the existence operator to that extracted value.
|
|
136
|
-
|
|
137
|
-
JSONPath notes:
|
|
138
|
-
- `$json_path_exists` maps to `@?` and binds the JSONPath string as a `::jsonpath` parameter.
|
|
139
|
-
- `$json_path_match` maps to `@@` and binds the JSONPath string as a `::jsonpath` parameter.
|
|
140
|
-
|
|
141
|
-
## query builder
|
|
142
|
-
|
|
143
|
-
builder chain:
|
|
144
|
-
- `.where(filter)`
|
|
145
|
-
- `.sort(sort_definition)`
|
|
146
|
-
- `.limit(limit_value)`
|
|
147
|
-
- `.skip(skip_value)`
|
|
148
|
-
- `.exec()`
|
|
149
|
-
|
|
150
|
-
## PostgreSQL capability map (summary)
|
|
151
|
-
|
|
152
|
-
See [`docs/query-translation.md`](query-translation.md) for the dedicated operator/function capability map, including update operators (`jsonb_set`, `jsonb_insert`, `jsonb_set_lax`) and indexability expectations for query operators over JSONB.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import debug_logger from '#src/debug/debug-logger.js';
|
|
2
|
-
import {clear_pool, get_debug_mode, get_pool, has_pool} from '#src/connection/pool-store.js';
|
|
3
|
-
|
|
4
|
-
export default async function disconnect() {
|
|
5
|
-
if(!has_pool()) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const debug_mode = get_debug_mode();
|
|
10
|
-
const pool_instance = get_pool();
|
|
11
|
-
|
|
12
|
-
await pool_instance.end();
|
|
13
|
-
clear_pool();
|
|
14
|
-
|
|
15
|
-
debug_logger(debug_mode, 'connection_closed', null);
|
|
16
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import defaults from '#src/constants/defaults.js';
|
|
2
|
-
|
|
3
|
-
const connection_state = {
|
|
4
|
-
pool_instance: null,
|
|
5
|
-
debug_mode: defaults.connection_options.debug,
|
|
6
|
-
connection_options: Object.assign({}, defaults.connection_options),
|
|
7
|
-
server_capabilities: null
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export function has_pool() {
|
|
11
|
-
return connection_state.pool_instance !== null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function get_pool() {
|
|
15
|
-
if(connection_state.pool_instance) {
|
|
16
|
-
return connection_state.pool_instance;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
throw new Error('jsonbadger is not connected. Call connect() first.');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function set_pool(pool_instance, connection_options, server_capabilities) {
|
|
23
|
-
connection_state.pool_instance = pool_instance;
|
|
24
|
-
connection_state.connection_options = Object.assign({}, defaults.connection_options, connection_options || {});
|
|
25
|
-
connection_state.debug_mode = connection_state.connection_options.debug;
|
|
26
|
-
connection_state.server_capabilities = server_capabilities === null ? null : Object.freeze(Object.assign({}, server_capabilities));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function clear_pool() {
|
|
30
|
-
connection_state.pool_instance = null;
|
|
31
|
-
connection_state.connection_options = Object.assign({}, defaults.connection_options);
|
|
32
|
-
connection_state.debug_mode = defaults.connection_options.debug;
|
|
33
|
-
connection_state.server_capabilities = null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function get_debug_mode() {
|
|
37
|
-
return connection_state.debug_mode;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function get_connection_options() {
|
|
41
|
-
return Object.assign({}, connection_state.connection_options);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function get_server_capabilities() {
|
|
45
|
-
return connection_state.server_capabilities;
|
|
46
|
-
}
|