@rws-framework/db 3.7.2 → 3.8.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.
@@ -15,15 +15,40 @@ class TypeConverter {
15
15
  // Handle basic types
16
16
  if (input == 'Number') {
17
17
  let numberOverride = false;
18
- if (modelType.dbOptions && modelType.dbOptions.mysql) {
19
- if (modelType.dbOptions.mysql.useType) {
20
- if (['db.Float'].includes(modelType.dbOptions.mysql.useType)) {
21
- input = 'Float';
22
- numberOverride = true;
18
+ // Check for database-specific number type overrides
19
+ if (modelType.dbOptions) {
20
+ // For PostgreSQL, first check postgres-specific options, then inherit from mysql if available
21
+ if ((dbType === 'postgresql' || dbType === 'postgres')) {
22
+ const pgOptions = modelType.dbOptions.postgres;
23
+ const mysqlOptions = modelType.dbOptions.mysql;
24
+ // Use postgres-specific type if available, otherwise inherit from mysql
25
+ const typeSource = pgOptions?.useType ? pgOptions : mysqlOptions;
26
+ if (typeSource?.useType) {
27
+ if (['db.Float'].includes(typeSource.useType)) {
28
+ input = 'Float';
29
+ numberOverride = true;
30
+ }
31
+ if (['db.Decimal'].includes(typeSource.useType)) {
32
+ input = 'Decimal';
33
+ numberOverride = true;
34
+ }
35
+ if (['db.DoublePrecision'].includes(typeSource.useType)) {
36
+ input = 'Float'; // PostgreSQL DoublePrecision maps to Prisma Float
37
+ numberOverride = true;
38
+ }
23
39
  }
24
- if (['db.Decimal'].includes(modelType.dbOptions.mysql.useType)) {
25
- input = 'Decimal';
26
- numberOverride = true;
40
+ }
41
+ // For MySQL, use mysql-specific options
42
+ else if (dbType === 'mysql' && modelType.dbOptions.mysql) {
43
+ if (modelType.dbOptions.mysql.useType) {
44
+ if (['db.Float'].includes(modelType.dbOptions.mysql.useType)) {
45
+ input = 'Float';
46
+ numberOverride = true;
47
+ }
48
+ if (['db.Decimal'].includes(modelType.dbOptions.mysql.useType)) {
49
+ input = 'Decimal';
50
+ numberOverride = true;
51
+ }
27
52
  }
28
53
  }
29
54
  }
@@ -93,9 +118,34 @@ class TypeConverter {
93
118
  if (dbType === 'mysql' && metadata.dbOptions.mysql) {
94
119
  let tag = null;
95
120
  if (metadata.dbOptions.mysql.useType && !metadata.dbOptions.mysql.useText) {
96
- const tagName = metadata.dbOptions.mysql.useType === 'VarChar' ? 'db.' + metadata.dbOptions.mysql.useType : metadata.dbOptions.mysql.useType;
97
- let tagParams = tagName === 'db.VarChar' && metadata.dbOptions.mysql.maxLength ? metadata.dbOptions.mysql.maxLength : (metadata.dbOptions.mysql?.params?.join(', ') || '');
98
- tag = `@${tagName}(${tagParams})`;
121
+ let tagName = metadata.dbOptions.mysql.useType;
122
+ let tagParams = '';
123
+ // Handle different MySQL type formats - ensure db.something format
124
+ if (tagName === 'db.VarChar') {
125
+ tagName = '@db.VarChar';
126
+ if (metadata.dbOptions.mysql.maxLength) {
127
+ tagParams = `(${metadata.dbOptions.mysql.maxLength})`;
128
+ }
129
+ }
130
+ else if (tagName === 'db.Float') {
131
+ tagName = '@db.Float';
132
+ }
133
+ else if (tagName === 'db.Decimal') {
134
+ tagName = '@db.Decimal';
135
+ const params = metadata.dbOptions.mysql.params;
136
+ if (params && params.length > 0) {
137
+ tagParams = `(${params.join(', ')})`;
138
+ }
139
+ }
140
+ else if (tagName.startsWith('db.')) {
141
+ tagName = `@${tagName}`;
142
+ }
143
+ if (tagParams) {
144
+ tag = `${tagName}${tagParams}`;
145
+ }
146
+ else {
147
+ tag = tagName;
148
+ }
99
149
  }
100
150
  if (metadata.dbOptions.mysql.useText) {
101
151
  tags.push('@db.Text');
@@ -108,11 +158,50 @@ class TypeConverter {
108
158
  }
109
159
  }
110
160
  // Handle PostgreSQL-specific options
111
- if ((dbType === 'postgresql' || dbType === 'postgres') && metadata.dbOptions.postgres) {
112
- if (metadata.dbOptions.postgres.useText) {
161
+ if ((dbType === 'postgresql' || dbType === 'postgres') && metadata.dbOptions) {
162
+ const pgOptions = metadata.dbOptions.postgres;
163
+ const mysqlOptions = metadata.dbOptions.mysql;
164
+ // Use postgres-specific options if available, otherwise inherit from mysql
165
+ const useText = pgOptions?.useText !== undefined ? pgOptions.useText : mysqlOptions?.useText;
166
+ const useUuid = pgOptions?.useUuid !== undefined ? pgOptions.useUuid : mysqlOptions?.useUuid;
167
+ const useType = pgOptions?.useType || mysqlOptions?.useType;
168
+ if (useText) {
113
169
  tags.push('@db.Text');
114
170
  }
115
- if (metadata.dbOptions.postgres.useUuid && metadata.tags?.includes('id')) {
171
+ if (useType && !useText) {
172
+ let tagName = useType;
173
+ let tagParams = '';
174
+ // Map MySQL-specific types to PostgreSQL equivalents - only handle db.something format
175
+ if (useType === 'db.Float') {
176
+ tagName = '@db.Real'; // PostgreSQL Real type
177
+ }
178
+ else if (useType === 'db.Decimal') {
179
+ tagName = '@db.Decimal';
180
+ // Inherit params from the source (postgres or mysql)
181
+ const params = pgOptions?.params || mysqlOptions?.params;
182
+ if (params && params.length > 0) {
183
+ tagParams = `(${params.join(', ')})`;
184
+ }
185
+ }
186
+ else if (useType === 'db.VarChar') {
187
+ tagName = '@db.VarChar';
188
+ // For VarChar, check maxLength from mysql options if not in postgres
189
+ const maxLength = mysqlOptions?.maxLength;
190
+ if (maxLength) {
191
+ tagParams = `(${maxLength})`;
192
+ }
193
+ }
194
+ else if (useType.startsWith('db.')) {
195
+ tagName = `@${useType}`;
196
+ }
197
+ if (tagParams) {
198
+ tags.push(`${tagName}${tagParams}`);
199
+ }
200
+ else if (tagName !== useType) {
201
+ tags.push(tagName);
202
+ }
203
+ }
204
+ if (useUuid && metadata.tags?.includes('id')) {
116
205
  tags.push('@default(uuid())');
117
206
  tags.push('@db.Uuid');
118
207
  }
@@ -142,14 +142,16 @@ class RWSModel {
142
142
  const timeSeriesHydrationFields = [];
143
143
  for (const key in this) {
144
144
  if (await this.hasRelation(key)) {
145
- data[key] = this.bindRelation(key, this[key]);
146
- if (data[key] === null) {
147
- const relationKey = await this.getRelationKey(key);
148
- if (relationKey) {
149
- data[relationKey] = null;
150
- delete data[key];
151
- }
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]);
152
153
  }
154
+ // Don't try to set the foreign key directly anymore
153
155
  continue;
154
156
  }
155
157
  if (!(await this.isDbVariable(key))) {
@@ -8,6 +8,7 @@ export interface IDbOpts {
8
8
  params?: string[];
9
9
  };
10
10
  postgres?: {
11
+ useType?: string;
11
12
  useText?: boolean;
12
13
  useUuid?: boolean;
13
14
  params?: string[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rws-framework/db",
3
3
  "private": false,
4
- "version": "3.7.2",
4
+ "version": "3.8.0",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -19,16 +19,46 @@ export class TypeConverter {
19
19
  // Handle basic types
20
20
  if (input == 'Number') {
21
21
  let numberOverride = false;
22
- if(modelType.dbOptions && modelType.dbOptions.mysql){
23
- if(modelType.dbOptions.mysql.useType){
24
- if(['db.Float'].includes(modelType.dbOptions.mysql.useType)){
25
- input = 'Float';
26
- numberOverride = true;
22
+
23
+ // Check for database-specific number type overrides
24
+ if(modelType.dbOptions) {
25
+ // For PostgreSQL, first check postgres-specific options, then inherit from mysql if available
26
+ if ((dbType === 'postgresql' || dbType === 'postgres')) {
27
+ const pgOptions = modelType.dbOptions.postgres;
28
+ const mysqlOptions = modelType.dbOptions.mysql;
29
+
30
+ // Use postgres-specific type if available, otherwise inherit from mysql
31
+ const typeSource = pgOptions?.useType ? pgOptions : mysqlOptions;
32
+
33
+ if (typeSource?.useType) {
34
+ if(['db.Float'].includes(typeSource.useType)){
35
+ input = 'Float';
36
+ numberOverride = true;
37
+ }
38
+
39
+ if(['db.Decimal'].includes(typeSource.useType)){
40
+ input = 'Decimal';
41
+ numberOverride = true;
42
+ }
43
+
44
+ if(['db.DoublePrecision'].includes(typeSource.useType)){
45
+ input = 'Float'; // PostgreSQL DoublePrecision maps to Prisma Float
46
+ numberOverride = true;
47
+ }
27
48
  }
28
-
29
- if(['db.Decimal'].includes(modelType.dbOptions.mysql.useType)){
30
- input = 'Decimal';
31
- numberOverride = true;
49
+ }
50
+ // For MySQL, use mysql-specific options
51
+ else if (dbType === 'mysql' && modelType.dbOptions.mysql) {
52
+ if(modelType.dbOptions.mysql.useType){
53
+ if(['db.Float'].includes(modelType.dbOptions.mysql.useType)){
54
+ input = 'Float';
55
+ numberOverride = true;
56
+ }
57
+
58
+ if(['db.Decimal'].includes(modelType.dbOptions.mysql.useType)){
59
+ input = 'Decimal';
60
+ numberOverride = true;
61
+ }
32
62
  }
33
63
  }
34
64
  }
@@ -109,9 +139,32 @@ export class TypeConverter {
109
139
  let tag = null;
110
140
 
111
141
  if (metadata.dbOptions.mysql.useType && !metadata.dbOptions.mysql.useText) {
112
- const tagName = metadata.dbOptions.mysql.useType === 'VarChar' ? 'db.' + metadata.dbOptions.mysql.useType : metadata.dbOptions.mysql.useType;
113
- let tagParams = tagName === 'db.VarChar' && metadata.dbOptions.mysql.maxLength ? metadata.dbOptions.mysql.maxLength : (metadata.dbOptions.mysql?.params?.join(', ') || '');
114
- tag = `@${tagName}(${tagParams})`;
142
+ let tagName = metadata.dbOptions.mysql.useType;
143
+ let tagParams = '';
144
+
145
+ // Handle different MySQL type formats - ensure db.something format
146
+ if (tagName === 'db.VarChar') {
147
+ tagName = '@db.VarChar';
148
+ if (metadata.dbOptions.mysql.maxLength) {
149
+ tagParams = `(${metadata.dbOptions.mysql.maxLength})`;
150
+ }
151
+ } else if (tagName === 'db.Float') {
152
+ tagName = '@db.Float';
153
+ } else if (tagName === 'db.Decimal') {
154
+ tagName = '@db.Decimal';
155
+ const params = metadata.dbOptions.mysql.params;
156
+ if (params && params.length > 0) {
157
+ tagParams = `(${params.join(', ')})`;
158
+ }
159
+ } else if (tagName.startsWith('db.')) {
160
+ tagName = `@${tagName}`;
161
+ }
162
+
163
+ if (tagParams) {
164
+ tag = `${tagName}${tagParams}`;
165
+ } else {
166
+ tag = tagName;
167
+ }
115
168
  }
116
169
 
117
170
  if (metadata.dbOptions.mysql.useText) {
@@ -128,12 +181,52 @@ export class TypeConverter {
128
181
  }
129
182
 
130
183
  // Handle PostgreSQL-specific options
131
- if ((dbType === 'postgresql' || dbType === 'postgres') && metadata.dbOptions.postgres) {
132
- if (metadata.dbOptions.postgres.useText) {
184
+ if ((dbType === 'postgresql' || dbType === 'postgres') && metadata.dbOptions) {
185
+ const pgOptions = metadata.dbOptions.postgres;
186
+ const mysqlOptions = metadata.dbOptions.mysql;
187
+
188
+ // Use postgres-specific options if available, otherwise inherit from mysql
189
+ const useText = pgOptions?.useText !== undefined ? pgOptions.useText : mysqlOptions?.useText;
190
+ const useUuid = pgOptions?.useUuid !== undefined ? pgOptions.useUuid : mysqlOptions?.useUuid;
191
+ const useType = pgOptions?.useType || mysqlOptions?.useType;
192
+
193
+ if (useText) {
133
194
  tags.push('@db.Text');
134
195
  }
135
196
 
136
- if (metadata.dbOptions.postgres.useUuid && metadata.tags?.includes('id')) {
197
+ if (useType && !useText) {
198
+ let tagName = useType;
199
+ let tagParams = '';
200
+
201
+ // Map MySQL-specific types to PostgreSQL equivalents - only handle db.something format
202
+ if (useType === 'db.Float') {
203
+ tagName = '@db.Real'; // PostgreSQL Real type
204
+ } else if (useType === 'db.Decimal') {
205
+ tagName = '@db.Decimal';
206
+ // Inherit params from the source (postgres or mysql)
207
+ const params = pgOptions?.params || mysqlOptions?.params;
208
+ if (params && params.length > 0) {
209
+ tagParams = `(${params.join(', ')})`;
210
+ }
211
+ } else if (useType === 'db.VarChar') {
212
+ tagName = '@db.VarChar';
213
+ // For VarChar, check maxLength from mysql options if not in postgres
214
+ const maxLength = mysqlOptions?.maxLength;
215
+ if (maxLength) {
216
+ tagParams = `(${maxLength})`;
217
+ }
218
+ } else if (useType.startsWith('db.')) {
219
+ tagName = `@${useType}`;
220
+ }
221
+
222
+ if (tagParams) {
223
+ tags.push(`${tagName}${tagParams}`);
224
+ } else if (tagName !== useType) {
225
+ tags.push(tagName);
226
+ }
227
+ }
228
+
229
+ if (useUuid && metadata.tags?.includes('id')) {
137
230
  tags.push('@default(uuid())');
138
231
  tags.push('@db.Uuid');
139
232
  }
@@ -137,7 +137,7 @@ class RWSModel<T> implements IModel {
137
137
  // Process regular fields and time series
138
138
  await HydrateUtils.hydrateDataFields(this, collections_to_models, relOneData, seriesHydrationfields, fullDataMode, data);
139
139
 
140
- if(!this.isPostLoadExecuted() && postLoadExecute){
140
+ if(!this.isPostLoadExecuted() && postLoadExecute){
141
141
  await this.postLoad();
142
142
  this.setPostLoadExecuted();
143
143
  }
@@ -182,15 +182,16 @@ class RWSModel<T> implements IModel {
182
182
 
183
183
  for (const key in (this as any)) {
184
184
  if (await this.hasRelation(key)) {
185
- data[key] = this.bindRelation(key, this[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]);
192
+ }
186
193
 
187
- if(data[key] === null){
188
- const relationKey = await this.getRelationKey(key);
189
- if(relationKey){
190
- data[relationKey] = null;
191
- delete data[key];
192
- }
193
- }
194
+ // Don't try to set the foreign key directly anymore
194
195
  continue;
195
196
  }
196
197
 
@@ -8,6 +8,7 @@ export interface IDbOpts {
8
8
  params?: string[]
9
9
  };
10
10
  postgres?: {
11
+ useType?: string;
11
12
  useText?: boolean;
12
13
  useUuid?: boolean;
13
14
  params?: string[]
@@ -113,7 +113,7 @@ export class FindUtils {
113
113
  const instanced: T[] = [];
114
114
 
115
115
  for (const data of dbData) {
116
- const inst: T = new (opModel as { new(): T })();
116
+ const inst: T = new (opModel as { new(): T })();
117
117
  instanced.push((await inst._asyncFill(data, fullData, allowRelations, findParams?.cancelPostLoad ? false : true)) as T);
118
118
  }
119
119