@spinajs/orm 2.0.481 → 2.0.484
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 +72 -3
- package/lib/cjs/bootstrap.js +10 -0
- package/lib/cjs/bootstrap.js.map +1 -1
- package/lib/cjs/builders.d.ts +127 -11
- package/lib/cjs/builders.d.ts.map +1 -1
- package/lib/cjs/builders.js +368 -283
- package/lib/cjs/builders.js.map +1 -1
- package/lib/cjs/converters.d.ts +9 -2
- package/lib/cjs/converters.d.ts.map +1 -1
- package/lib/cjs/converters.js +48 -8
- package/lib/cjs/converters.js.map +1 -1
- package/lib/cjs/decorators.d.ts +26 -3
- package/lib/cjs/decorators.d.ts.map +1 -1
- package/lib/cjs/decorators.js +95 -42
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/cjs/dehydrators.js +1 -1
- package/lib/cjs/dehydrators.js.map +1 -1
- package/lib/cjs/descriptor.d.ts +1 -0
- package/lib/cjs/descriptor.d.ts.map +1 -1
- package/lib/cjs/descriptor.js +16 -40
- package/lib/cjs/descriptor.js.map +1 -1
- package/lib/cjs/driver.d.ts +136 -7
- package/lib/cjs/driver.d.ts.map +1 -1
- package/lib/cjs/driver.js +279 -0
- package/lib/cjs/driver.js.map +1 -1
- package/lib/cjs/existsRelationHandlers.d.ts +29 -0
- package/lib/cjs/existsRelationHandlers.d.ts.map +1 -0
- package/lib/cjs/existsRelationHandlers.js +138 -0
- package/lib/cjs/existsRelationHandlers.js.map +1 -0
- package/lib/cjs/fp.d.ts.map +1 -1
- package/lib/cjs/fp.js +10 -15
- package/lib/cjs/fp.js.map +1 -1
- package/lib/cjs/hydrators.d.ts.map +1 -1
- package/lib/cjs/hydrators.js +29 -2
- package/lib/cjs/hydrators.js.map +1 -1
- package/lib/cjs/identity-map.d.ts +60 -0
- package/lib/cjs/identity-map.d.ts.map +1 -0
- package/lib/cjs/identity-map.js +135 -0
- package/lib/cjs/identity-map.js.map +1 -0
- package/lib/cjs/index.d.ts +12 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +12 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/interfaces.d.ts +300 -10
- package/lib/cjs/interfaces.d.ts.map +1 -1
- package/lib/cjs/interfaces.js +54 -1
- package/lib/cjs/interfaces.js.map +1 -1
- package/lib/cjs/metadata.d.ts.map +1 -1
- package/lib/cjs/metadata.js +4 -1
- package/lib/cjs/metadata.js.map +1 -1
- package/lib/cjs/metrics.d.ts +53 -0
- package/lib/cjs/metrics.d.ts.map +1 -0
- package/lib/cjs/metrics.js +82 -0
- package/lib/cjs/metrics.js.map +1 -0
- package/lib/cjs/middlewares.d.ts +13 -1
- package/lib/cjs/middlewares.d.ts.map +1 -1
- package/lib/cjs/middlewares.js +55 -15
- package/lib/cjs/middlewares.js.map +1 -1
- package/lib/cjs/model.d.ts +129 -13
- package/lib/cjs/model.d.ts.map +1 -1
- package/lib/cjs/model.js +449 -93
- package/lib/cjs/model.js.map +1 -1
- package/lib/cjs/orm.d.ts.map +1 -1
- package/lib/cjs/orm.js +12 -3
- package/lib/cjs/orm.js.map +1 -1
- package/lib/cjs/orphan.d.ts +27 -0
- package/lib/cjs/orphan.d.ts.map +1 -0
- package/lib/cjs/orphan.js +55 -0
- package/lib/cjs/orphan.js.map +1 -0
- package/lib/cjs/primary-keys.d.ts +60 -0
- package/lib/cjs/primary-keys.d.ts.map +1 -0
- package/lib/cjs/primary-keys.js +243 -0
- package/lib/cjs/primary-keys.js.map +1 -0
- package/lib/cjs/relation-objects.d.ts +101 -9
- package/lib/cjs/relation-objects.d.ts.map +1 -1
- package/lib/cjs/relation-objects.js +194 -43
- package/lib/cjs/relation-objects.js.map +1 -1
- package/lib/cjs/relations.d.ts +7 -1
- package/lib/cjs/relations.d.ts.map +1 -1
- package/lib/cjs/relations.js +16 -1
- package/lib/cjs/relations.js.map +1 -1
- package/lib/cjs/resilience.d.ts +50 -0
- package/lib/cjs/resilience.d.ts.map +1 -0
- package/lib/cjs/resilience.js +70 -0
- package/lib/cjs/resilience.js.map +1 -0
- package/lib/cjs/snapshot.d.ts +58 -0
- package/lib/cjs/snapshot.d.ts.map +1 -0
- package/lib/cjs/snapshot.js +125 -0
- package/lib/cjs/snapshot.js.map +1 -0
- package/lib/cjs/statements.d.ts +11 -1
- package/lib/cjs/statements.d.ts.map +1 -1
- package/lib/cjs/statements.js +13 -2
- package/lib/cjs/statements.js.map +1 -1
- package/lib/cjs/subject-builder.d.ts +79 -0
- package/lib/cjs/subject-builder.d.ts.map +1 -0
- package/lib/cjs/subject-builder.js +296 -0
- package/lib/cjs/subject-builder.js.map +1 -0
- package/lib/cjs/subject-executor.d.ts +122 -0
- package/lib/cjs/subject-executor.d.ts.map +1 -0
- package/lib/cjs/subject-executor.js +319 -0
- package/lib/cjs/subject-executor.js.map +1 -0
- package/lib/cjs/subject-sorter.d.ts +70 -0
- package/lib/cjs/subject-sorter.d.ts.map +1 -0
- package/lib/cjs/subject-sorter.js +173 -0
- package/lib/cjs/subject-sorter.js.map +1 -0
- package/lib/cjs/subject.d.ts +100 -0
- package/lib/cjs/subject.d.ts.map +1 -0
- package/lib/cjs/subject.js +89 -0
- package/lib/cjs/subject.js.map +1 -0
- package/lib/cjs/unit-of-work.d.ts +52 -0
- package/lib/cjs/unit-of-work.d.ts.map +1 -0
- package/lib/cjs/unit-of-work.js +170 -0
- package/lib/cjs/unit-of-work.js.map +1 -0
- package/lib/mjs/bootstrap.js +10 -0
- package/lib/mjs/bootstrap.js.map +1 -1
- package/lib/mjs/builders.d.ts +127 -11
- package/lib/mjs/builders.d.ts.map +1 -1
- package/lib/mjs/builders.js +370 -285
- package/lib/mjs/builders.js.map +1 -1
- package/lib/mjs/converters.d.ts +9 -2
- package/lib/mjs/converters.d.ts.map +1 -1
- package/lib/mjs/converters.js +48 -8
- package/lib/mjs/converters.js.map +1 -1
- package/lib/mjs/decorators.d.ts +26 -3
- package/lib/mjs/decorators.d.ts.map +1 -1
- package/lib/mjs/decorators.js +96 -44
- package/lib/mjs/decorators.js.map +1 -1
- package/lib/mjs/dehydrators.js +1 -1
- package/lib/mjs/dehydrators.js.map +1 -1
- package/lib/mjs/descriptor.d.ts +1 -0
- package/lib/mjs/descriptor.d.ts.map +1 -1
- package/lib/mjs/descriptor.js +17 -39
- package/lib/mjs/descriptor.js.map +1 -1
- package/lib/mjs/driver.d.ts +136 -7
- package/lib/mjs/driver.d.ts.map +1 -1
- package/lib/mjs/driver.js +279 -0
- package/lib/mjs/driver.js.map +1 -1
- package/lib/mjs/existsRelationHandlers.d.ts +29 -0
- package/lib/mjs/existsRelationHandlers.d.ts.map +1 -0
- package/lib/mjs/existsRelationHandlers.js +134 -0
- package/lib/mjs/existsRelationHandlers.js.map +1 -0
- package/lib/mjs/fp.d.ts.map +1 -1
- package/lib/mjs/fp.js +10 -15
- package/lib/mjs/fp.js.map +1 -1
- package/lib/mjs/hydrators.d.ts.map +1 -1
- package/lib/mjs/hydrators.js +29 -2
- package/lib/mjs/hydrators.js.map +1 -1
- package/lib/mjs/identity-map.d.ts +60 -0
- package/lib/mjs/identity-map.d.ts.map +1 -0
- package/lib/mjs/identity-map.js +130 -0
- package/lib/mjs/identity-map.js.map +1 -0
- package/lib/mjs/index.d.ts +12 -0
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +12 -0
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/interfaces.d.ts +300 -10
- package/lib/mjs/interfaces.d.ts.map +1 -1
- package/lib/mjs/interfaces.js +53 -0
- package/lib/mjs/interfaces.js.map +1 -1
- package/lib/mjs/metadata.d.ts.map +1 -1
- package/lib/mjs/metadata.js +4 -1
- package/lib/mjs/metadata.js.map +1 -1
- package/lib/mjs/metrics.d.ts +53 -0
- package/lib/mjs/metrics.d.ts.map +1 -0
- package/lib/mjs/metrics.js +76 -0
- package/lib/mjs/metrics.js.map +1 -0
- package/lib/mjs/middlewares.d.ts +13 -1
- package/lib/mjs/middlewares.d.ts.map +1 -1
- package/lib/mjs/middlewares.js +55 -15
- package/lib/mjs/middlewares.js.map +1 -1
- package/lib/mjs/model.d.ts +129 -13
- package/lib/mjs/model.d.ts.map +1 -1
- package/lib/mjs/model.js +451 -95
- package/lib/mjs/model.js.map +1 -1
- package/lib/mjs/orm.d.ts.map +1 -1
- package/lib/mjs/orm.js +12 -3
- package/lib/mjs/orm.js.map +1 -1
- package/lib/mjs/orphan.d.ts +27 -0
- package/lib/mjs/orphan.d.ts.map +1 -0
- package/lib/mjs/orphan.js +52 -0
- package/lib/mjs/orphan.js.map +1 -0
- package/lib/mjs/primary-keys.d.ts +60 -0
- package/lib/mjs/primary-keys.d.ts.map +1 -0
- package/lib/mjs/primary-keys.js +223 -0
- package/lib/mjs/primary-keys.js.map +1 -0
- package/lib/mjs/relation-objects.d.ts +101 -9
- package/lib/mjs/relation-objects.d.ts.map +1 -1
- package/lib/mjs/relation-objects.js +194 -43
- package/lib/mjs/relation-objects.js.map +1 -1
- package/lib/mjs/relations.d.ts +7 -1
- package/lib/mjs/relations.d.ts.map +1 -1
- package/lib/mjs/relations.js +16 -1
- package/lib/mjs/relations.js.map +1 -1
- package/lib/mjs/resilience.d.ts +50 -0
- package/lib/mjs/resilience.d.ts.map +1 -0
- package/lib/mjs/resilience.js +64 -0
- package/lib/mjs/resilience.js.map +1 -0
- package/lib/mjs/snapshot.d.ts +58 -0
- package/lib/mjs/snapshot.d.ts.map +1 -0
- package/lib/mjs/snapshot.js +115 -0
- package/lib/mjs/snapshot.js.map +1 -0
- package/lib/mjs/statements.d.ts +11 -1
- package/lib/mjs/statements.d.ts.map +1 -1
- package/lib/mjs/statements.js +14 -3
- package/lib/mjs/statements.js.map +1 -1
- package/lib/mjs/subject-builder.d.ts +79 -0
- package/lib/mjs/subject-builder.d.ts.map +1 -0
- package/lib/mjs/subject-builder.js +292 -0
- package/lib/mjs/subject-builder.js.map +1 -0
- package/lib/mjs/subject-executor.d.ts +122 -0
- package/lib/mjs/subject-executor.d.ts.map +1 -0
- package/lib/mjs/subject-executor.js +312 -0
- package/lib/mjs/subject-executor.js.map +1 -0
- package/lib/mjs/subject-sorter.d.ts +70 -0
- package/lib/mjs/subject-sorter.d.ts.map +1 -0
- package/lib/mjs/subject-sorter.js +168 -0
- package/lib/mjs/subject-sorter.js.map +1 -0
- package/lib/mjs/subject.d.ts +100 -0
- package/lib/mjs/subject.d.ts.map +1 -0
- package/lib/mjs/subject.js +84 -0
- package/lib/mjs/subject.js.map +1 -0
- package/lib/mjs/unit-of-work.d.ts +52 -0
- package/lib/mjs/unit-of-work.d.ts.map +1 -0
- package/lib/mjs/unit-of-work.js +166 -0
- package/lib/mjs/unit-of-work.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +10 -7
package/lib/cjs/driver.js
CHANGED
|
@@ -16,9 +16,20 @@ const interfaces_js_1 = require("./interfaces.js");
|
|
|
16
16
|
const di_1 = require("@spinajs/di");
|
|
17
17
|
const builders_js_1 = require("./builders.js");
|
|
18
18
|
const converters_js_1 = require("./converters.js");
|
|
19
|
+
const exceptions_js_1 = require("./exceptions.js");
|
|
20
|
+
const async_hooks_1 = require("async_hooks");
|
|
21
|
+
const resilience_js_1 = require("./resilience.js");
|
|
22
|
+
const metrics_js_1 = require("./metrics.js");
|
|
19
23
|
require("./hydrators.js");
|
|
20
24
|
require("./dehydrators.js");
|
|
21
25
|
class OrmDriver extends di_1.SyncService {
|
|
26
|
+
/**
|
|
27
|
+
* The transaction currently in scope on this async execution path, or `undefined` outside
|
|
28
|
+
* a transaction.
|
|
29
|
+
*/
|
|
30
|
+
get CurrentTransaction() {
|
|
31
|
+
return this.TransactionStorage.getStore();
|
|
32
|
+
}
|
|
22
33
|
constructor(options) {
|
|
23
34
|
super();
|
|
24
35
|
/**
|
|
@@ -30,6 +41,22 @@ class OrmDriver extends di_1.SyncService {
|
|
|
30
41
|
Name: 'orm-driver',
|
|
31
42
|
DefaultConnection: false,
|
|
32
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Ambient transaction context.
|
|
46
|
+
*
|
|
47
|
+
* Statements executed inside a `transaction()` callback must run on that transaction's
|
|
48
|
+
* connection. This lives on the abstract driver — rather than being a MySQL implementation
|
|
49
|
+
* detail, as it used to be — so the guarantee is part of the contract and every driver
|
|
50
|
+
* inherits it.
|
|
51
|
+
*/
|
|
52
|
+
this.TransactionStorage = new async_hooks_1.AsyncLocalStorage();
|
|
53
|
+
/**
|
|
54
|
+
* Isolation levels this driver honours. Empty by default: a driver that declares nothing
|
|
55
|
+
* rejects every explicitly requested isolation level rather than quietly ignoring it.
|
|
56
|
+
*/
|
|
57
|
+
this.SupportedIsolationLevels = [];
|
|
58
|
+
this._state = resilience_js_1.ConnectionState.Disconnected;
|
|
59
|
+
this._healthCheckTimer = null;
|
|
33
60
|
this.Options = Object.assign(this.Options, options);
|
|
34
61
|
}
|
|
35
62
|
resolve() {
|
|
@@ -44,6 +71,207 @@ class OrmDriver extends di_1.SyncService {
|
|
|
44
71
|
this.Container.register(converters_js_1.UuidConverter).as(converters_js_1.UuidConverter);
|
|
45
72
|
this.Container.register(converters_js_1.UniversalValueConverter).as(converters_js_1.UniversalValueConverter);
|
|
46
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Effective pool settings: `Pool.*` when given, then the deprecated `PoolLimit` for `Max`,
|
|
76
|
+
* then the defaults. Resolved in one place so every driver agrees on what "unset" means.
|
|
77
|
+
*/
|
|
78
|
+
resolvedPoolOptions() {
|
|
79
|
+
const pool = this.Options.Pool ?? {};
|
|
80
|
+
return {
|
|
81
|
+
Min: pool.Min ?? 0,
|
|
82
|
+
Max: pool.Max ?? this.Options.PoolLimit ?? 10,
|
|
83
|
+
IdleTimeout: pool.IdleTimeout ?? 30000,
|
|
84
|
+
AcquireTimeout: pool.AcquireTimeout ?? 10000,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Current connection lifecycle state.
|
|
89
|
+
*/
|
|
90
|
+
get State() {
|
|
91
|
+
return this._state;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Records a state transition and logs it. Repeat transitions to the same state are ignored.
|
|
95
|
+
*/
|
|
96
|
+
setState(state) {
|
|
97
|
+
if (this._state === state) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const previous = this._state;
|
|
101
|
+
this._state = state;
|
|
102
|
+
if (state === resilience_js_1.ConnectionState.Connected) {
|
|
103
|
+
this.Log.info(`connection ${this.Options.Name} is ${state} (was ${previous})`);
|
|
104
|
+
}
|
|
105
|
+
else if (state === resilience_js_1.ConnectionState.Degraded || state === resilience_js_1.ConnectionState.Disconnected) {
|
|
106
|
+
this.Log.warn(`connection ${this.Options.Name} is ${state} (was ${previous})`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.Log.trace(`connection ${this.Options.Name} is ${state} (was ${previous})`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Effective resilience settings with defaults applied.
|
|
114
|
+
*/
|
|
115
|
+
resolvedResilienceOptions() {
|
|
116
|
+
const r = this.Options.Resilience ?? {};
|
|
117
|
+
return {
|
|
118
|
+
HealthCheckInterval: r.HealthCheckInterval ?? 30000,
|
|
119
|
+
MaxRetries: r.MaxRetries ?? 5,
|
|
120
|
+
RetryDelay: r.RetryDelay ?? 200,
|
|
121
|
+
MaxRetryDelay: r.MaxRetryDelay ?? 5000,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* True when the error means the transport died rather than the statement being wrong.
|
|
126
|
+
* Drivers override to add dialect-specific codes.
|
|
127
|
+
*/
|
|
128
|
+
isRetryableError(err) {
|
|
129
|
+
return (0, resilience_js_1.isRetryableErrorCode)(err);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Runs `operation`, and on a retryable transport failure reconnects and retries with bounded
|
|
133
|
+
* exponential backoff. Query errors propagate on the first attempt untouched.
|
|
134
|
+
*/
|
|
135
|
+
async withReconnect(operation) {
|
|
136
|
+
const { MaxRetries, RetryDelay, MaxRetryDelay } = this.resolvedResilienceOptions();
|
|
137
|
+
let lastError;
|
|
138
|
+
for (let attempt = 0; attempt <= MaxRetries; attempt++) {
|
|
139
|
+
try {
|
|
140
|
+
const result = await operation();
|
|
141
|
+
this.setState(resilience_js_1.ConnectionState.Connected);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
if (!this.isRetryableError(err)) {
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
lastError = err;
|
|
149
|
+
this.setState(resilience_js_1.ConnectionState.Degraded);
|
|
150
|
+
if (attempt === MaxRetries) {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
const wait = (0, resilience_js_1.backoffDelay)(attempt, RetryDelay, MaxRetryDelay);
|
|
154
|
+
this.Log.warn(`connection ${this.Options.Name} lost (${err.message}); reconnect attempt ${attempt + 1}/${MaxRetries} in ${wait}ms`);
|
|
155
|
+
await (0, resilience_js_1.delay)(wait);
|
|
156
|
+
try {
|
|
157
|
+
this.setState(resilience_js_1.ConnectionState.Connecting);
|
|
158
|
+
await this.connect();
|
|
159
|
+
}
|
|
160
|
+
catch (reconnectErr) {
|
|
161
|
+
this.Log.warn(`reconnect attempt ${attempt + 1} for ${this.Options.Name} failed: ${reconnectErr.message}`);
|
|
162
|
+
this.setState(resilience_js_1.ConnectionState.Degraded);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
this.setState(resilience_js_1.ConnectionState.Disconnected);
|
|
167
|
+
throw lastError;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Starts the periodic health probe. Replaces the single startup `ping()` — a connection that
|
|
171
|
+
* was healthy at boot tells you nothing about a pool holding sockets to a database that has
|
|
172
|
+
* since restarted. No-op when `Resilience.HealthCheckInterval` is 0. Idempotent.
|
|
173
|
+
*/
|
|
174
|
+
startHealthCheck() {
|
|
175
|
+
const { HealthCheckInterval } = this.resolvedResilienceOptions();
|
|
176
|
+
if (HealthCheckInterval <= 0 || this._healthCheckTimer !== null) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
this._healthCheckTimer = setInterval(() => {
|
|
180
|
+
void this.runHealthCheck();
|
|
181
|
+
}, HealthCheckInterval);
|
|
182
|
+
// Never hold the process open just to probe a database.
|
|
183
|
+
if (typeof this._healthCheckTimer.unref === 'function') {
|
|
184
|
+
this._healthCheckTimer.unref();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Stops the periodic health probe. Idempotent.
|
|
189
|
+
*/
|
|
190
|
+
stopHealthCheck() {
|
|
191
|
+
if (this._healthCheckTimer !== null) {
|
|
192
|
+
clearInterval(this._healthCheckTimer);
|
|
193
|
+
this._healthCheckTimer = null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* One health probe. A failed probe degrades the driver and attempts a single reconnect; it
|
|
198
|
+
* never throws, because it runs on a timer with no caller to receive the error.
|
|
199
|
+
*/
|
|
200
|
+
async runHealthCheck() {
|
|
201
|
+
this.publishPoolMetrics();
|
|
202
|
+
let alive = false;
|
|
203
|
+
try {
|
|
204
|
+
alive = await this.ping();
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
alive = false;
|
|
208
|
+
}
|
|
209
|
+
if (alive) {
|
|
210
|
+
this.setState(resilience_js_1.ConnectionState.Connected);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
this.setState(resilience_js_1.ConnectionState.Degraded);
|
|
214
|
+
try {
|
|
215
|
+
// The driver stays DEGRADED even when reconnecting succeeds: a fresh handle is not
|
|
216
|
+
// evidence that queries work. Only the next successful probe promotes it back to
|
|
217
|
+
// Connected — drivers whose own connect() verifies the link ( mysql takes and releases
|
|
218
|
+
// a real connection ) set the state themselves.
|
|
219
|
+
await this.connect();
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
this.Log.warn(`health check reconnect for ${this.Options.Name} failed: ${err.message}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Point-in-time pool state. The base implementation reports an empty pool; drivers that own a
|
|
227
|
+
* real pool override it. Must never throw — it runs on the health-check timer.
|
|
228
|
+
*/
|
|
229
|
+
poolMetrics() {
|
|
230
|
+
return { Size: 0, InUse: 0, Waiting: 0 };
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Pushes the current pool state and connection state to the shared `Metrics` registry from
|
|
234
|
+
* `@spinajs/telemetry-common`. Nothing has to be wired for this to work — `Metrics` owns a
|
|
235
|
+
* private registry and `@spinajs/telemetry`'s `/metrics` endpoint renders that same singleton.
|
|
236
|
+
*/
|
|
237
|
+
publishPoolMetrics() {
|
|
238
|
+
try {
|
|
239
|
+
const metrics = (0, metrics_js_1.ormMetrics)();
|
|
240
|
+
if (!metrics) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const labels = { connection: this.Options.Name };
|
|
244
|
+
const pool = this.poolMetrics();
|
|
245
|
+
(0, metrics_js_1.ormGauge)(metrics, metrics_js_1.ORM_METRIC_KEY_POOL_SIZE).set(labels, pool.Size);
|
|
246
|
+
(0, metrics_js_1.ormGauge)(metrics, metrics_js_1.ORM_METRIC_KEY_POOL_IN_USE).set(labels, pool.InUse);
|
|
247
|
+
(0, metrics_js_1.ormGauge)(metrics, metrics_js_1.ORM_METRIC_KEY_POOL_WAITING).set(labels, pool.Waiting);
|
|
248
|
+
(0, metrics_js_1.ormGauge)(metrics, metrics_js_1.ORM_METRIC_KEY_CONNECTION_STATE).set(labels, this.State === resilience_js_1.ConnectionState.Connected ? 1 : 0);
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
// Telemetry must never break a connection. This runs first on every health tick, so a
|
|
252
|
+
// registry that throws — or a driver built outside DI, as tooling and tests do — would
|
|
253
|
+
// otherwise stop the probe that follows it from ever running.
|
|
254
|
+
this.Log?.trace(`publishing pool metrics for ${this.Options.Name} failed: ${err.message}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Records one pool-acquire wait, in SECONDS ( prometheus convention ). Drivers that own a real
|
|
259
|
+
* pool call this from the acquire callback; keeping the prom-client objects behind this method
|
|
260
|
+
* is what stops every driver from needing to know about `@spinajs/telemetry-common`. Never
|
|
261
|
+
* throws, for the same reason `publishPoolMetrics` never throws.
|
|
262
|
+
*/
|
|
263
|
+
observeAcquireSeconds(seconds) {
|
|
264
|
+
try {
|
|
265
|
+
const metrics = (0, metrics_js_1.ormMetrics)();
|
|
266
|
+
if (!metrics) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
(0, metrics_js_1.ormHistogram)(metrics, metrics_js_1.ORM_METRIC_KEY_ACQUIRE_SECONDS).observe({ connection: this.Options.Name }, seconds);
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
this.Log?.trace(`observing pool acquire time for ${this.Options.Name} failed: ${err.message}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
47
275
|
/**
|
|
48
276
|
* Creates select query builder associated with this connection.
|
|
49
277
|
* This can be used to execute raw queries to db without orm model layer
|
|
@@ -94,6 +322,57 @@ class OrmDriver extends di_1.SyncService {
|
|
|
94
322
|
index() {
|
|
95
323
|
return this.Container.resolve(builders_js_1.IndexQueryBuilder, [this]);
|
|
96
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Runs `cb` inside a transaction and owns its whole lifecycle: commits when the callback
|
|
327
|
+
* resolves, rolls back when it throws, and releases the connection exactly once either way.
|
|
328
|
+
* Resolves with whatever the callback returned.
|
|
329
|
+
*
|
|
330
|
+
* Statements issued inside the callback run on this transaction's connection automatically —
|
|
331
|
+
* the context is carried through `AsyncLocalStorage`, so nothing has to be threaded through
|
|
332
|
+
* by hand.
|
|
333
|
+
*
|
|
334
|
+
* Calling it again while a transaction is already in scope on this async path does **not**
|
|
335
|
+
* open a second, independent transaction: it takes a savepoint, so a failing nested block
|
|
336
|
+
* rolls back only its own work.
|
|
337
|
+
*
|
|
338
|
+
* @param cb - the transaction body
|
|
339
|
+
* @param options - optional isolation level, validated against {@link SupportedIsolationLevels}
|
|
340
|
+
*/
|
|
341
|
+
async transaction(cb, options) {
|
|
342
|
+
if (options?.isolation && !this.SupportedIsolationLevels.includes(options.isolation)) {
|
|
343
|
+
throw new exceptions_js_1.OrmException(`isolation level ${options.isolation} not supported by driver ${this.Options.Driver}`);
|
|
344
|
+
}
|
|
345
|
+
const active = this.TransactionStorage.getStore();
|
|
346
|
+
// already inside a transaction — nest with a savepoint rather than opening a second one
|
|
347
|
+
if (active) {
|
|
348
|
+
const name = `sp_${++active.depth}`;
|
|
349
|
+
await this._savepoint(active, name);
|
|
350
|
+
try {
|
|
351
|
+
const result = await cb(this);
|
|
352
|
+
await this._releaseSavepoint(active, name);
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
await this._rollbackToSavepoint(active, name);
|
|
357
|
+
throw err;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
const ctx = await this._begin(options);
|
|
361
|
+
ctx.depth = 0;
|
|
362
|
+
try {
|
|
363
|
+
const result = await this.TransactionStorage.run(ctx, () => cb(this));
|
|
364
|
+
await this._commit(ctx);
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
// swallow a rollback failure so it cannot mask whatever actually went wrong
|
|
369
|
+
await this._rollback(ctx).catch(() => undefined);
|
|
370
|
+
throw err;
|
|
371
|
+
}
|
|
372
|
+
finally {
|
|
373
|
+
await this._dispose(ctx);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
97
376
|
}
|
|
98
377
|
exports.OrmDriver = OrmDriver;
|
|
99
378
|
__decorate([
|
package/lib/cjs/driver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/driver.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAA0C;AAC1C,sCAAsC;AACtC,
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IRelationDescriptor, ISelectQueryBuilder, RelationType } from './interfaces.js';
|
|
2
|
+
import type { WhereBuilder } from './builders.js';
|
|
3
|
+
import { WhereFunction } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Strategy that builds the EXISTS / NOT EXISTS clause for one relation type.
|
|
6
|
+
*
|
|
7
|
+
* Resolved via `Array.ofType(ExistsRelationHandler)` and dispatched by `rel.Type` from
|
|
8
|
+
* `WhereBuilder.buildExistsClause`. Implementations either:
|
|
9
|
+
* - mutate the outer builder directly and return `undefined` (eg. {@link RelationType.One}
|
|
10
|
+
* adds `WHERE FK IS NOT NULL` plus a right-join, no EXISTS sub-query is generated), or
|
|
11
|
+
* - return a correlated sub-query that the caller wraps in EXISTS/NOT EXISTS.
|
|
12
|
+
*/
|
|
13
|
+
export declare abstract class ExistsRelationHandler {
|
|
14
|
+
abstract get Type(): RelationType;
|
|
15
|
+
abstract apply<R>(builder: WhereBuilder<any>, rel: IRelationDescriptor, relationName: string, callback?: WhereFunction<R>): ISelectQueryBuilder | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare class OneExistsRelationHandler extends ExistsRelationHandler {
|
|
18
|
+
get Type(): RelationType;
|
|
19
|
+
apply<R>(builder: WhereBuilder<any>, rel: IRelationDescriptor, _relationName: string, callback?: WhereFunction<R>): ISelectQueryBuilder | undefined;
|
|
20
|
+
}
|
|
21
|
+
export declare class ManyExistsRelationHandler extends ExistsRelationHandler {
|
|
22
|
+
get Type(): RelationType;
|
|
23
|
+
apply<R>(builder: WhereBuilder<any>, rel: IRelationDescriptor, _relationName: string, callback?: WhereFunction<R>): ISelectQueryBuilder;
|
|
24
|
+
}
|
|
25
|
+
export declare class ManyToManyExistsRelationHandler extends ExistsRelationHandler {
|
|
26
|
+
get Type(): RelationType;
|
|
27
|
+
apply<R>(builder: WhereBuilder<any>, rel: IRelationDescriptor, _relationName: string, callback?: WhereFunction<R>): ISelectQueryBuilder;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=existsRelationHandlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"existsRelationHandlers.d.ts","sourceRoot":"","sources":["../../src/existsRelationHandlers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAgB,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEvG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;GAQG;AACH,8BAAsB,qBAAqB;IACzC,aAAoB,IAAI,IAAI,YAAY,CAAC;aAEzB,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB,GAAG,SAAS;CACnK;AAuBD,qBACa,wBAAyB,SAAQ,qBAAqB;IACjE,IAAW,IAAI,IAAI,YAAY,CAE9B;IAEM,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB,GAAG,SAAS;CAyC3J;AAED,qBACa,yBAA0B,SAAQ,qBAAqB;IAClE,IAAW,IAAI,IAAI,YAAY,CAE9B;IAEM,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB;CAmB/I;AAED,qBACa,+BAAgC,SAAQ,qBAAqB;IACxE,IAAW,IAAI,IAAI,YAAY,CAE9B;IAEM,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,mBAAmB;CAuB/I"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ManyToManyExistsRelationHandler = exports.ManyExistsRelationHandler = exports.OneExistsRelationHandler = exports.ExistsRelationHandler = void 0;
|
|
10
|
+
/* eslint-disable prettier/prettier */
|
|
11
|
+
const di_1 = require("@spinajs/di");
|
|
12
|
+
const util_1 = require("@spinajs/util");
|
|
13
|
+
const interfaces_js_1 = require("./interfaces.js");
|
|
14
|
+
const builders_js_1 = require("./builders.js");
|
|
15
|
+
/**
|
|
16
|
+
* Strategy that builds the EXISTS / NOT EXISTS clause for one relation type.
|
|
17
|
+
*
|
|
18
|
+
* Resolved via `Array.ofType(ExistsRelationHandler)` and dispatched by `rel.Type` from
|
|
19
|
+
* `WhereBuilder.buildExistsClause`. Implementations either:
|
|
20
|
+
* - mutate the outer builder directly and return `undefined` (eg. {@link RelationType.One}
|
|
21
|
+
* adds `WHERE FK IS NOT NULL` plus a right-join, no EXISTS sub-query is generated), or
|
|
22
|
+
* - return a correlated sub-query that the caller wraps in EXISTS/NOT EXISTS.
|
|
23
|
+
*/
|
|
24
|
+
class ExistsRelationHandler {
|
|
25
|
+
}
|
|
26
|
+
exports.ExistsRelationHandler = ExistsRelationHandler;
|
|
27
|
+
/**
|
|
28
|
+
* Resolves the correlated source primary key column reference, eg. `` `users`.`Id` ``.
|
|
29
|
+
* Falls back to the source descriptor's `TableName` when neither the builder nor its parent
|
|
30
|
+
* has an alias set, matching the legacy behaviour of `whereExist` / `whereNotExists`.
|
|
31
|
+
*/
|
|
32
|
+
function sourcePKeyRef(builder, tDesc) {
|
|
33
|
+
return sourceColumnRef(builder, tDesc, tDesc.PrimaryKey[0]);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolves an arbitrary correlated column on the source side, eg. `` `entries`.`group_id` ``.
|
|
37
|
+
*
|
|
38
|
+
* {@link RelationType.One} correlates on the source's FOREIGN key rather than its primary
|
|
39
|
+
* key, so it cannot reuse {@link sourcePKeyRef}. Both share the alias resolution: the
|
|
40
|
+
* builder's alias, its parent's, or the source table name.
|
|
41
|
+
*/
|
|
42
|
+
function sourceColumnRef(builder, tDesc, column) {
|
|
43
|
+
const sourceAlias = builder.TableAlias ?? tDesc.TableName;
|
|
44
|
+
return `\`${sourceAlias}\`.\`${column}\``;
|
|
45
|
+
}
|
|
46
|
+
let OneExistsRelationHandler = class OneExistsRelationHandler extends ExistsRelationHandler {
|
|
47
|
+
get Type() {
|
|
48
|
+
return interfaces_js_1.RelationType.One;
|
|
49
|
+
}
|
|
50
|
+
apply(builder, rel, _relationName, callback) {
|
|
51
|
+
builder.whereNotNull(rel.ForeignKey);
|
|
52
|
+
// A belongsTo with a non-null FK always has its parent row, so an unconditional check
|
|
53
|
+
// needs no sub-query at all.
|
|
54
|
+
if (!callback) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Correlated EXISTS, NOT a join.
|
|
59
|
+
*
|
|
60
|
+
* This ran as `builder.rightJoin(...)` on the OUTER builder, which only ever worked on
|
|
61
|
+
* selects: `UpdateQueryBuilder` mixes in `WhereBuilder` alone and `DeleteQueryBuilder`
|
|
62
|
+
* adds only `LimitBuilder`, so neither defines `rightJoin`. The rbac middleware runs
|
|
63
|
+
* `afterQueryCreation` on all three builder types, so any model reaching ownership
|
|
64
|
+
* through a belongsTo threw a TypeError the moment it was updated or deleted, and had
|
|
65
|
+
* to hand-roll the correlation in raw SQL instead.
|
|
66
|
+
*
|
|
67
|
+
* EXISTS is also the semantics the method name promises: the join form leaked the
|
|
68
|
+
* joined table's columns into the outer result and turned an existence test into a
|
|
69
|
+
* row-multiplying join.
|
|
70
|
+
*/
|
|
71
|
+
const tDesc = builder.Model.getModelDescriptor();
|
|
72
|
+
const alias = `${rel.TargetModel.getModelDescriptor().TableName}_exists`;
|
|
73
|
+
const relQuery = rel.TargetModel.query().setAlias(alias);
|
|
74
|
+
// lazy, so the outer alias is resolved at compile time - it may be assigned after this
|
|
75
|
+
// handler runs. Both sides stay alias-qualified so a callback that joins further tables
|
|
76
|
+
// cannot make the correlation column ambiguous.
|
|
77
|
+
relQuery.where(util_1.Lazy.oF(function () {
|
|
78
|
+
relQuery.where(new builders_js_1.RawQuery(`\`${alias}\`.\`${rel.PrimaryKey}\` = ${sourceColumnRef(builder, tDesc, rel.ForeignKey)}`));
|
|
79
|
+
}));
|
|
80
|
+
callback.apply(relQuery);
|
|
81
|
+
return relQuery;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
exports.OneExistsRelationHandler = OneExistsRelationHandler;
|
|
85
|
+
exports.OneExistsRelationHandler = OneExistsRelationHandler = __decorate([
|
|
86
|
+
(0, di_1.Injectable)(ExistsRelationHandler)
|
|
87
|
+
], OneExistsRelationHandler);
|
|
88
|
+
let ManyExistsRelationHandler = class ManyExistsRelationHandler extends ExistsRelationHandler {
|
|
89
|
+
get Type() {
|
|
90
|
+
return interfaces_js_1.RelationType.Many;
|
|
91
|
+
}
|
|
92
|
+
apply(builder, rel, _relationName, callback) {
|
|
93
|
+
const tDesc = builder.Model.getModelDescriptor();
|
|
94
|
+
const tableName = rel.TargetModel.getModelDescriptor().TableName;
|
|
95
|
+
// set alias to avoid conflicts in case of multiple relations to same model and to make
|
|
96
|
+
// sure that relation query is correct even if source query has alias
|
|
97
|
+
const relQuery = rel.TargetModel.query().setAlias(`${tableName}_exists`);
|
|
98
|
+
relQuery.where(util_1.Lazy.oF(function () {
|
|
99
|
+
relQuery.where(new builders_js_1.RawQuery(`${rel.ForeignKey} = ${sourcePKeyRef(builder, tDesc)}`));
|
|
100
|
+
}));
|
|
101
|
+
if (callback) {
|
|
102
|
+
callback.apply(relQuery);
|
|
103
|
+
}
|
|
104
|
+
return relQuery;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
exports.ManyExistsRelationHandler = ManyExistsRelationHandler;
|
|
108
|
+
exports.ManyExistsRelationHandler = ManyExistsRelationHandler = __decorate([
|
|
109
|
+
(0, di_1.Injectable)(ExistsRelationHandler)
|
|
110
|
+
], ManyExistsRelationHandler);
|
|
111
|
+
let ManyToManyExistsRelationHandler = class ManyToManyExistsRelationHandler extends ExistsRelationHandler {
|
|
112
|
+
get Type() {
|
|
113
|
+
return interfaces_js_1.RelationType.ManyToMany;
|
|
114
|
+
}
|
|
115
|
+
apply(builder, rel, _relationName, callback) {
|
|
116
|
+
const tDesc = builder.Model.getModelDescriptor();
|
|
117
|
+
const junctionModel = rel.JunctionModel;
|
|
118
|
+
const junctionTableName = junctionModel.getModelDescriptor().TableName;
|
|
119
|
+
const relQuery = junctionModel.query().setAlias(`${junctionTableName}_exists`);
|
|
120
|
+
relQuery.where(util_1.Lazy.oF(function () {
|
|
121
|
+
relQuery.where(new builders_js_1.RawQuery(`${rel.JunctionModelSourceModelFKey_Name} = ${sourcePKeyRef(builder, tDesc)}`));
|
|
122
|
+
}));
|
|
123
|
+
if (callback) {
|
|
124
|
+
relQuery.rightJoin({
|
|
125
|
+
joinModel: rel.TargetModel,
|
|
126
|
+
joinTableForeignKey: rel.PrimaryKey,
|
|
127
|
+
sourceTablePrimaryKey: rel.JunctionModelTargetModelFKey_Name,
|
|
128
|
+
callback: callback,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return relQuery;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
exports.ManyToManyExistsRelationHandler = ManyToManyExistsRelationHandler;
|
|
135
|
+
exports.ManyToManyExistsRelationHandler = ManyToManyExistsRelationHandler = __decorate([
|
|
136
|
+
(0, di_1.Injectable)(ExistsRelationHandler)
|
|
137
|
+
], ManyToManyExistsRelationHandler);
|
|
138
|
+
//# sourceMappingURL=existsRelationHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"existsRelationHandlers.js","sourceRoot":"","sources":["../../src/existsRelationHandlers.ts"],"names":[],"mappings":"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"}
|
package/lib/cjs/fp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fp.d.ts","sourceRoot":"","sources":["../../src/fp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAiB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,oBAAY,WAAW;IACrB,kBAAkB,IAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,sBAY1G;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"fp.d.ts","sourceRoot":"","sources":["../../src/fp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAiB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,oBAAY,WAAW;IACrB,kBAAkB,IAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,sBAY1G;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAMvF;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,SAAS,EAAE,SAAS,CAAC,EAAE,eAAe,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAyB9G;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,SAAS,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAK/E;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,SAAS,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAUvE"}
|
package/lib/cjs/fp.js
CHANGED
|
@@ -43,12 +43,9 @@ function _get_entity(idOrEntity, c, fresh) {
|
|
|
43
43
|
*/
|
|
44
44
|
function _update(data) {
|
|
45
45
|
return (model) => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
return model;
|
|
51
|
-
});
|
|
46
|
+
// A clean model short-circuits to { RowsAffected: 0 } - that is a no-op success,
|
|
47
|
+
// not a failure, so we always resolve the model.
|
|
48
|
+
return model.update(data).then(() => model);
|
|
52
49
|
};
|
|
53
50
|
}
|
|
54
51
|
/**
|
|
@@ -64,14 +61,16 @@ function _insert(behaviour) {
|
|
|
64
61
|
return Promise.resolve(model);
|
|
65
62
|
}
|
|
66
63
|
return model[0].constructor.insert(model, behaviour).then((res) => {
|
|
67
|
-
|
|
64
|
+
// `uuid` and `assigned` primary keys report LastInsertId 0 on a successful insert, so
|
|
65
|
+
// only RowsAffected signals failure. See @Primary({ generated }) in the ORM docs.
|
|
66
|
+
if (res.RowsAffected <= 0) {
|
|
68
67
|
return Promise.reject(new exceptions_1.ErrorCode(E_ORM_CODES.E_NO_ROWS_AFFECTED));
|
|
69
68
|
}
|
|
70
69
|
return model;
|
|
71
70
|
});
|
|
72
71
|
}
|
|
73
72
|
return model.insert(behaviour).then((res) => {
|
|
74
|
-
if (res.
|
|
73
|
+
if (res.RowsAffected <= 0) {
|
|
75
74
|
return Promise.reject(new exceptions_1.ErrorCode(E_ORM_CODES.E_NO_ROWS_AFFECTED));
|
|
76
75
|
}
|
|
77
76
|
return model;
|
|
@@ -80,12 +79,8 @@ function _insert(behaviour) {
|
|
|
80
79
|
}
|
|
81
80
|
function _insertOrUpdate() {
|
|
82
81
|
return (model) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return Promise.reject(new exceptions_1.ErrorCode(E_ORM_CODES.E_NO_ROWS_AFFECTED));
|
|
86
|
-
}
|
|
87
|
-
return model;
|
|
88
|
-
});
|
|
82
|
+
// insertOrUpdate on a clean model is a no-op success (RowsAffected 0) - resolve the model.
|
|
83
|
+
return model.insertOrUpdate().then(() => model);
|
|
89
84
|
};
|
|
90
85
|
}
|
|
91
86
|
/**
|
|
@@ -97,7 +92,7 @@ function _insertOrUpdate() {
|
|
|
97
92
|
function _delete() {
|
|
98
93
|
return (model) => {
|
|
99
94
|
return model.destroy().then((res) => {
|
|
100
|
-
if (res.
|
|
95
|
+
if (res.RowsAffected <= 0) {
|
|
101
96
|
return Promise.reject(new exceptions_1.ErrorCode(E_ORM_CODES.E_NO_ROWS_AFFECTED));
|
|
102
97
|
}
|
|
103
98
|
return model;
|
package/lib/cjs/fp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fp.js","sourceRoot":"","sources":["../../src/fp.ts"],"names":[],"mappings":";;;;;;AAmBA,kCAYC;AAQD,
|
|
1
|
+
{"version":3,"file":"fp.js","sourceRoot":"","sources":["../../src/fp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrators.d.ts","sourceRoot":"","sources":["../../src/hydrators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,8BAAsB,aAAa;aACjB,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CACxD;AAED,qBACa,kBAAmB,SAAQ,aAAa;IAC5C,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"hydrators.d.ts","sourceRoot":"","sources":["../../src/hydrators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,8BAAsB,aAAa;aACjB,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CACxD;AAED,qBACa,kBAAmB,SAAQ,aAAa;IAC5C,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CAiCrD;AAED,qBACa,qBAAsB,SAAQ,aAAa;IAC/C,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CAYrD;AAED,qBACa,yBAA0B,SAAQ,aAAa;IACnD,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CA+BrD;AAED,qBACa,wBAAyB,SAAQ,aAAa;IAClD,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CAuCrD;AAED,qBACa,6BAA8B,SAAQ,aAAa;IACvD,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;CAarD"}
|