@rws-framework/db 3.11.0 → 3.12.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/dist/helper/db/schema-generator.js +17 -1
- package/dist/models/core/RWSModel.js +29 -9
- package/dist/models/types/RelationTypes.d.ts +4 -0
- package/dist/models/utils/RelationUtils.js +2 -1
- package/package.json +1 -1
- package/src/helper/db/schema-generator.ts +21 -1
- package/src/models/core/RWSModel.ts +30 -9
- package/src/models/types/RelationTypes.ts +5 -1
- package/src/models/utils/RelationUtils.ts +2 -1
|
@@ -11,6 +11,7 @@ const _model_1 = require("../../models/_model");
|
|
|
11
11
|
const utils_1 = require("./utils");
|
|
12
12
|
const type_converter_1 = require("./type-converter");
|
|
13
13
|
const relation_manager_1 = require("./relation-manager");
|
|
14
|
+
const child_process_1 = require("child_process");
|
|
14
15
|
const _EXECUTE_PRISMA_CMD = true;
|
|
15
16
|
const _REMOVE_SCHEMA_FILE = true;
|
|
16
17
|
/**
|
|
@@ -339,8 +340,23 @@ datasource db {
|
|
|
339
340
|
*/
|
|
340
341
|
static async pushDBModels(configService, dbService, leaveFile = false) {
|
|
341
342
|
process.env = { ...process.env, [this.dbUrlVarName]: configService.get('db_url') };
|
|
343
|
+
console.log({ env: process.env.PRISMA_DB_URL });
|
|
342
344
|
const [_, schemaPath] = utils_1.DbUtils.getProcessedSchemaDir();
|
|
343
|
-
|
|
345
|
+
const prismaPath = require.resolve('prisma/build/index.js');
|
|
346
|
+
// Set environment variables
|
|
347
|
+
const env = {
|
|
348
|
+
...process.env,
|
|
349
|
+
[this.dbUrlVarName]: configService.get('db_url')
|
|
350
|
+
};
|
|
351
|
+
// Execute prisma db push programmatically
|
|
352
|
+
(0, child_process_1.execSync)(`node ${prismaPath} db push --schema=${schemaPath} --force-reset`, {
|
|
353
|
+
cwd: process.cwd(),
|
|
354
|
+
stdio: 'inherit',
|
|
355
|
+
env
|
|
356
|
+
});
|
|
357
|
+
// await rwsShell.runCommand(`${DbUtils.detectInstaller()} prisma db push --schema=${schemaPath}`, process.cwd(), false, { env: {
|
|
358
|
+
// PRISMA_DB_URL: configService.get('db_url')
|
|
359
|
+
// }});
|
|
344
360
|
}
|
|
345
361
|
}
|
|
346
362
|
exports.SchemaGenerator = SchemaGenerator;
|
|
@@ -140,18 +140,38 @@ class RWSModel {
|
|
|
140
140
|
const data = {};
|
|
141
141
|
const timeSeriesIds = TimeSeriesUtils_1.TimeSeriesUtils.getTimeSeriesModelFields(this);
|
|
142
142
|
const timeSeriesHydrationFields = [];
|
|
143
|
+
// Get relation metadata to determine how to handle each relation
|
|
144
|
+
const classFields = FieldsHelper_1.FieldsHelper.getAllClassFields(this.constructor);
|
|
145
|
+
const relOneData = await this.getRelationOneMeta(classFields);
|
|
143
146
|
for (const key in this) {
|
|
144
147
|
if (await this.hasRelation(key)) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
const relationMeta = relOneData[key];
|
|
149
|
+
if (relationMeta) {
|
|
150
|
+
// Use connect on relations that are either:
|
|
151
|
+
// 1. Required (required: true)
|
|
152
|
+
// 2. Have explicitly set cascade options (metaOpts.cascade)
|
|
153
|
+
const hasExplicitCascade = relationMeta.cascade && Object.keys(relationMeta.cascade).length > 0;
|
|
154
|
+
const shouldUseConnect = relationMeta.required || hasExplicitCascade;
|
|
155
|
+
if (shouldUseConnect) {
|
|
156
|
+
// Relations with required=true or explicit cascade → use connect
|
|
157
|
+
if (this[key] === null) {
|
|
158
|
+
data[key] = { disconnect: true };
|
|
159
|
+
}
|
|
160
|
+
else if (this[key] && this[key].id) {
|
|
161
|
+
data[key] = { connect: { id: this[key].id } };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Simple optional relations → use foreign key field directly
|
|
166
|
+
const foreignKeyField = relationMeta.hydrationField;
|
|
167
|
+
if (this[key] === null) {
|
|
168
|
+
data[foreignKeyField] = null;
|
|
169
|
+
}
|
|
170
|
+
else if (this[key] && this[key].id) {
|
|
171
|
+
data[foreignKeyField] = this[key].id;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
153
174
|
}
|
|
154
|
-
// Don't try to set the foreign key directly anymore
|
|
155
175
|
continue;
|
|
156
176
|
}
|
|
157
177
|
if (!(await this.isDbVariable(key))) {
|
|
@@ -12,6 +12,10 @@ export type RelOneMetaType<T extends IRWSModel> = {
|
|
|
12
12
|
model: OpModelType<T>;
|
|
13
13
|
hydrationField: string;
|
|
14
14
|
foreignKey: string;
|
|
15
|
+
cascade?: {
|
|
16
|
+
onDelete?: string;
|
|
17
|
+
onUpdate?: string;
|
|
18
|
+
};
|
|
15
19
|
};
|
|
16
20
|
};
|
|
17
21
|
export type RelManyMetaType<T extends IRWSModel> = {
|
|
@@ -19,7 +19,8 @@ class RelationUtils {
|
|
|
19
19
|
required: resolvedMetadata.required,
|
|
20
20
|
model: resolvedMetadata.relatedTo,
|
|
21
21
|
hydrationField: resolvedMetadata.relationField,
|
|
22
|
-
foreignKey: resolvedMetadata.relatedToField
|
|
22
|
+
foreignKey: resolvedMetadata.relatedToField,
|
|
23
|
+
cascade: resolvedMetadata.cascade
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
}
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@ import { TypeConverter } from './type-converter';
|
|
|
14
14
|
import { RelationManager } from './relation-manager';
|
|
15
15
|
import { ITrackerMetaOpts } from '../../decorators/TrackType';
|
|
16
16
|
import { IDbOpts } from '../../models/interfaces/IDbOpts';
|
|
17
|
+
import { execSync } from 'child_process';
|
|
17
18
|
|
|
18
19
|
const _EXECUTE_PRISMA_CMD = true;
|
|
19
20
|
const _REMOVE_SCHEMA_FILE = true;
|
|
@@ -444,8 +445,27 @@ datasource db {
|
|
|
444
445
|
static async pushDBModels(configService: IDbConfigHandler, dbService: DBService, leaveFile = false): Promise<void> {
|
|
445
446
|
process.env = { ...process.env, [this.dbUrlVarName]: configService.get('db_url') };
|
|
446
447
|
|
|
448
|
+
console.log({ env: process.env.PRISMA_DB_URL });
|
|
449
|
+
|
|
447
450
|
const [_, schemaPath] = DbUtils.getProcessedSchemaDir();
|
|
448
451
|
|
|
449
|
-
|
|
452
|
+
const prismaPath = require.resolve('prisma/build/index.js');
|
|
453
|
+
|
|
454
|
+
// Set environment variables
|
|
455
|
+
const env = {
|
|
456
|
+
...process.env,
|
|
457
|
+
[this.dbUrlVarName]: configService.get('db_url')
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
// Execute prisma db push programmatically
|
|
461
|
+
execSync(`node ${prismaPath} db push --schema=${schemaPath} --force-reset`, {
|
|
462
|
+
cwd: process.cwd(),
|
|
463
|
+
stdio: 'inherit',
|
|
464
|
+
env
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// await rwsShell.runCommand(`${DbUtils.detectInstaller()} prisma db push --schema=${schemaPath}`, process.cwd(), false, { env: {
|
|
468
|
+
// PRISMA_DB_URL: configService.get('db_url')
|
|
469
|
+
// }});
|
|
450
470
|
}
|
|
451
471
|
}
|
|
@@ -179,19 +179,40 @@ class RWSModel<T> implements IModel {
|
|
|
179
179
|
const data: any = {};
|
|
180
180
|
const timeSeriesIds = TimeSeriesUtils.getTimeSeriesModelFields(this);
|
|
181
181
|
const timeSeriesHydrationFields: string[] = [];
|
|
182
|
+
|
|
183
|
+
// Get relation metadata to determine how to handle each relation
|
|
184
|
+
const classFields = FieldsHelper.getAllClassFields(this.constructor);
|
|
185
|
+
const relOneData = await this.getRelationOneMeta(classFields);
|
|
182
186
|
|
|
183
187
|
for (const key in (this as any)) {
|
|
184
|
-
if (await this.hasRelation(key)) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
if (await this.hasRelation(key)) {
|
|
189
|
+
const relationMeta = relOneData[key];
|
|
190
|
+
|
|
191
|
+
if (relationMeta) {
|
|
192
|
+
// Use connect on relations that are either:
|
|
193
|
+
// 1. Required (required: true)
|
|
194
|
+
// 2. Have explicitly set cascade options (metaOpts.cascade)
|
|
195
|
+
const hasExplicitCascade = relationMeta.cascade && Object.keys(relationMeta.cascade).length > 0;
|
|
196
|
+
const shouldUseConnect = relationMeta.required || hasExplicitCascade;
|
|
197
|
+
|
|
198
|
+
if (shouldUseConnect) {
|
|
199
|
+
// Relations with required=true or explicit cascade → use connect
|
|
200
|
+
if (this[key] === null) {
|
|
201
|
+
data[key] = { disconnect: true };
|
|
202
|
+
} else if (this[key] && this[key].id) {
|
|
203
|
+
data[key] = { connect: { id: this[key].id } };
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
// Simple optional relations → use foreign key field directly
|
|
207
|
+
const foreignKeyField = relationMeta.hydrationField;
|
|
208
|
+
if (this[key] === null) {
|
|
209
|
+
data[foreignKeyField] = null;
|
|
210
|
+
} else if (this[key] && this[key].id) {
|
|
211
|
+
data[foreignKeyField] = this[key].id;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
192
214
|
}
|
|
193
215
|
|
|
194
|
-
// Don't try to set the foreign key directly anymore
|
|
195
216
|
continue;
|
|
196
217
|
}
|
|
197
218
|
|
|
@@ -23,7 +23,8 @@ export class RelationUtils {
|
|
|
23
23
|
required: resolvedMetadata.required,
|
|
24
24
|
model: resolvedMetadata.relatedTo,
|
|
25
25
|
hydrationField: resolvedMetadata.relationField,
|
|
26
|
-
foreignKey: resolvedMetadata.relatedToField
|
|
26
|
+
foreignKey: resolvedMetadata.relatedToField,
|
|
27
|
+
cascade: resolvedMetadata.cascade
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
}
|