@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.
@@ -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
- await console_1.rwsShell.runCommand(`${utils_1.DbUtils.detectInstaller()} prisma db push --schema=${schemaPath}`, process.cwd());
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
- if (this[key] === null) {
146
- // For null relations, use disconnect or set to null
147
- data[key] = {
148
- disconnect: true
149
- };
150
- }
151
- else {
152
- data[key] = this.bindRelation(key, this[key]);
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rws-framework/db",
3
3
  "private": false,
4
- "version": "3.11.0",
4
+ "version": "3.12.0",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -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
- await rwsShell.runCommand(`${DbUtils.detectInstaller()} prisma db push --schema=${schemaPath}`, process.cwd());
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
- if (this[key] === null) {
186
- // For null relations, use disconnect or set to null
187
- data[key] = {
188
- disconnect: true
189
- };
190
- } else {
191
- data[key] = this.bindRelation(key, this[key]);
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
 
@@ -12,7 +12,11 @@ export type RelOneMetaType<T extends IRWSModel> = {
12
12
  key?: string,
13
13
  model: OpModelType<T>,
14
14
  hydrationField: string,
15
- foreignKey: string
15
+ foreignKey: string,
16
+ cascade?: {
17
+ onDelete?: string,
18
+ onUpdate?: string
19
+ }
16
20
  }
17
21
  };
18
22
 
@@ -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
  }