@rws-framework/db 3.1.0 → 3.3.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/decorators/IdType.js +6 -0
- package/dist/decorators/InverseRelation.js +3 -4
- package/dist/decorators/Relation.js +4 -3
- package/dist/decorators/TrackType.js +2 -2
- package/dist/helper/DbHelper.d.ts +1 -1
- package/dist/helper/DbHelper.js +4 -4
- package/dist/helper/db/relation-manager.js +1 -1
- package/dist/helper/db/schema-generator.js +73 -26
- package/dist/helper/db/type-converter.d.ts +2 -1
- package/dist/helper/db/type-converter.js +33 -9
- package/dist/helper/db/utils.d.ts +7 -0
- package/dist/helper/db/utils.js +80 -26
- package/dist/models/core/RWSModel.js +29 -32
- package/dist/models/interfaces/IDbOpts.d.ts +3 -0
- package/dist/models/interfaces/IIdTypeOpts.d.ts +2 -0
- package/dist/models/interfaces/ITrackerOpts.d.ts +1 -0
- package/dist/models/utils/HydrateUtils.js +0 -1
- package/dist/models/utils/ModelUtils.js +8 -1
- package/dist/models/utils/PaginationUtils.js +5 -6
- package/dist/services/DBService.js +7 -8
- package/exec/console.js +0 -2
- package/package.json +1 -1
- package/src/decorators/IdType.ts +10 -1
- package/src/decorators/InverseRelation.ts +2 -2
- package/src/decorators/Relation.ts +6 -4
- package/src/helper/DbHelper.ts +1 -1
- package/src/helper/db/schema-generator.ts +104 -36
- package/src/helper/db/type-converter.ts +41 -8
- package/src/helper/db/utils.ts +114 -40
- package/src/models/interfaces/IDbOpts.ts +3 -0
- package/src/models/interfaces/IIdTypeOpts.ts +2 -0
- package/src/models/interfaces/ITrackerOpts.ts +1 -0
- package/src/models/utils/HydrateUtils.ts +0 -2
- package/src/models/utils/ModelUtils.ts +10 -1
- package/tsconfig.json +1 -1
|
@@ -3,6 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
require("reflect-metadata");
|
|
4
4
|
function IdType(type, opts = null, tags = []) {
|
|
5
5
|
const metaOpts = { type, dbOptions: opts && opts.dbOptions ? opts.dbOptions : null };
|
|
6
|
+
if (opts && opts.dbOptions) {
|
|
7
|
+
metaOpts.dbOptions = opts.dbOptions;
|
|
8
|
+
}
|
|
9
|
+
if (opts && opts.noAuto) {
|
|
10
|
+
metaOpts.noAuto = opts.noAuto;
|
|
11
|
+
}
|
|
6
12
|
return function (target, key) {
|
|
7
13
|
Reflect.defineMetadata(`IdType:${key}`, metaOpts, target);
|
|
8
14
|
};
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
require("reflect-metadata");
|
|
4
4
|
const ModelUtils_1 = require("../models/utils/ModelUtils");
|
|
5
5
|
function guessForeignKey(inversionModel, bindingModel, decoratorsData) {
|
|
6
|
-
var _a;
|
|
7
6
|
let key = null;
|
|
8
7
|
let defaultKey = `${bindingModel._collection}_id`;
|
|
9
8
|
const relDecorators = {};
|
|
@@ -21,7 +20,7 @@ function guessForeignKey(inversionModel, bindingModel, decoratorsData) {
|
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
22
|
for (const relKey of Object.keys(relDecorators)) {
|
|
24
|
-
const prodMeta =
|
|
23
|
+
const prodMeta = relDecorators[relKey]?.metadata;
|
|
25
24
|
if (prodMeta && prodMeta.relatedTo._collection === bindingModel._collection) {
|
|
26
25
|
return prodMeta.relationField;
|
|
27
26
|
}
|
|
@@ -41,8 +40,8 @@ function InverseRelation(inversionModel, sourceModel, relationOptions = null) {
|
|
|
41
40
|
foreignKey: relationOptions && relationOptions.foreignKey ? relationOptions.foreignKey : guessForeignKey(model, source, decoratorsData),
|
|
42
41
|
// Generate a unique relation name if one is not provided
|
|
43
42
|
relationName: relationOptions && relationOptions.relationName ?
|
|
44
|
-
relationOptions.relationName
|
|
45
|
-
|
|
43
|
+
relationOptions.relationName :
|
|
44
|
+
null
|
|
46
45
|
};
|
|
47
46
|
return metaOpts;
|
|
48
47
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
require("reflect-metadata");
|
|
4
|
-
const
|
|
4
|
+
const _DEFAULT_CASCADE = { onDelete: 'SetNull', onUpdate: 'Cascade' };
|
|
5
|
+
const _DEFAULTS = { required: false, many: false, embed: false, cascade: null };
|
|
5
6
|
function Relation(theModel, relationOptions = _DEFAULTS) {
|
|
6
7
|
return function (target, key) {
|
|
7
8
|
// Store the promise in metadata immediately
|
|
@@ -15,8 +16,8 @@ function Relation(theModel, relationOptions = _DEFAULTS) {
|
|
|
15
16
|
key,
|
|
16
17
|
// Generate a unique relation name if one is not provided
|
|
17
18
|
relationName: relationOptions.relationName ?
|
|
18
|
-
relationOptions.relationName
|
|
19
|
-
|
|
19
|
+
relationOptions.relationName :
|
|
20
|
+
null
|
|
20
21
|
};
|
|
21
22
|
if (relationOptions.required) {
|
|
22
23
|
metaOpts.cascade.onDelete = 'Restrict';
|
|
@@ -8,10 +8,10 @@ function TrackType(type, opts = null, tags = []) {
|
|
|
8
8
|
isArray: false
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
if (!
|
|
11
|
+
if (!opts?.required) {
|
|
12
12
|
opts.required = false;
|
|
13
13
|
}
|
|
14
|
-
if (!
|
|
14
|
+
if (!opts?.isArray) {
|
|
15
15
|
opts.isArray = false;
|
|
16
16
|
}
|
|
17
17
|
const required = opts.required;
|
|
@@ -60,7 +60,7 @@ export declare class DbHelper {
|
|
|
60
60
|
/**
|
|
61
61
|
* Convert a JavaScript type to a Prisma schema type
|
|
62
62
|
*/
|
|
63
|
-
static toConfigCase(modelType: any, dbType?:
|
|
63
|
+
static toConfigCase(modelType: any, dbType?: IDbConfigParams['db_type']): string;
|
|
64
64
|
/**
|
|
65
65
|
* Process type functions metadata to extract database-specific options
|
|
66
66
|
*/
|
package/dist/helper/DbHelper.js
CHANGED
|
@@ -10,6 +10,10 @@ const db_1 = require("./db");
|
|
|
10
10
|
* It delegates to the specialized modules for specific functionality.
|
|
11
11
|
*/
|
|
12
12
|
class DbHelper {
|
|
13
|
+
/**
|
|
14
|
+
* The environment variable name for the Prisma database URL
|
|
15
|
+
*/
|
|
16
|
+
static dbUrlVarName = db_1.SchemaGenerator.dbUrlVarName;
|
|
13
17
|
/**
|
|
14
18
|
* Install Prisma with the generated schema
|
|
15
19
|
* @param configService The configuration service
|
|
@@ -107,7 +111,3 @@ class DbHelper {
|
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
exports.DbHelper = DbHelper;
|
|
110
|
-
/**
|
|
111
|
-
* The environment variable name for the Prisma database URL
|
|
112
|
-
*/
|
|
113
|
-
DbHelper.dbUrlVarName = db_1.SchemaGenerator.dbUrlVarName;
|
|
@@ -5,6 +5,7 @@ exports.RelationManager = void 0;
|
|
|
5
5
|
* Manages database relations for schema generation
|
|
6
6
|
*/
|
|
7
7
|
class RelationManager {
|
|
8
|
+
static allRelations = new Map();
|
|
8
9
|
/**
|
|
9
10
|
* Mark a relation between two models
|
|
10
11
|
* @param relationKey A unique key for the relation
|
|
@@ -102,4 +103,3 @@ class RelationManager {
|
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
exports.RelationManager = RelationManager;
|
|
105
|
-
RelationManager.allRelations = new Map();
|
|
@@ -11,11 +11,13 @@ 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
|
|
14
|
+
const _EXECUTE_PRISMA_CMD = true;
|
|
15
|
+
const _REMOVE_SCHEMA_FILE = true;
|
|
15
16
|
/**
|
|
16
17
|
* Handles Prisma schema generation
|
|
17
18
|
*/
|
|
18
19
|
class SchemaGenerator {
|
|
20
|
+
static dbUrlVarName = 'PRISMA_DB_URL';
|
|
19
21
|
/**
|
|
20
22
|
* Generate the base schema for Prisma
|
|
21
23
|
* @param dbType The database type
|
|
@@ -40,21 +42,31 @@ datasource db {
|
|
|
40
42
|
* @returns The model section
|
|
41
43
|
*/
|
|
42
44
|
static async generateModelSections(model, configService) {
|
|
43
|
-
var _a, _b;
|
|
44
45
|
let section = '';
|
|
45
46
|
const modelMetadatas = await _model_1.RWSModel.getModelAnnotations(model);
|
|
46
47
|
const dbType = configService.get('db_type') || 'mongodb';
|
|
47
48
|
const modelName = model._collection;
|
|
48
49
|
section += `model ${modelName} {\n`;
|
|
49
|
-
|
|
50
|
+
let hasIdType = false;
|
|
51
|
+
let idFieldName;
|
|
52
|
+
for (const someModelMetaKey in modelMetadatas) {
|
|
53
|
+
const isIdTyped = modelMetadatas[someModelMetaKey].annotationType === 'IdType';
|
|
54
|
+
if (isIdTyped) {
|
|
55
|
+
hasIdType = true;
|
|
56
|
+
idFieldName = someModelMetaKey;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
let idGenerated = false;
|
|
60
|
+
if (!model._NO_ID && !hasIdType) {
|
|
50
61
|
section += `\t${utils_1.DbUtils.generateId(dbType, modelMetadatas)}\n`;
|
|
62
|
+
idGenerated = true;
|
|
51
63
|
}
|
|
52
64
|
for (const key in modelMetadatas) {
|
|
53
65
|
const modelMetadata = modelMetadatas[key].metadata;
|
|
54
66
|
let requiredString = modelMetadata.required ? '' : '?';
|
|
55
67
|
const annotationType = modelMetadatas[key].annotationType;
|
|
56
68
|
let indexedId = false;
|
|
57
|
-
if (model._NO_ID) {
|
|
69
|
+
if (model._NO_ID || hasIdType) {
|
|
58
70
|
indexedId = true;
|
|
59
71
|
requiredString = '';
|
|
60
72
|
}
|
|
@@ -66,17 +78,17 @@ datasource db {
|
|
|
66
78
|
const relatedModel = relationMeta.relatedTo;
|
|
67
79
|
const isMany = relationMeta.many;
|
|
68
80
|
const cascadeOpts = [];
|
|
69
|
-
if (
|
|
81
|
+
if (relationMeta.cascade?.onDelete) {
|
|
70
82
|
cascadeOpts.push(`onDelete: ${relationMeta.cascade.onDelete}`);
|
|
71
83
|
}
|
|
72
|
-
if (
|
|
84
|
+
if (relationMeta.cascade?.onUpdate) {
|
|
73
85
|
cascadeOpts.push(`onUpdate: ${relationMeta.cascade.onUpdate}`);
|
|
74
86
|
}
|
|
75
87
|
const relatedModelName = relatedModel._collection;
|
|
76
88
|
const relationKey = [modelName, relatedModelName].join('_');
|
|
77
89
|
const relationIndex = relation_manager_1.RelationManager.getRelationCounter(relationKey);
|
|
78
|
-
const relationName =
|
|
79
|
-
const mapName =
|
|
90
|
+
const relationName = relationMeta.relationName ? relationMeta.relationName : null;
|
|
91
|
+
const mapName = relationMeta.mappingName ? relationMeta.mappingName : null;
|
|
80
92
|
const relatedModelMetadatas = await _model_1.RWSModel.getModelAnnotations(relatedModel);
|
|
81
93
|
const relationFieldName = modelMetadata.relationField ? modelMetadata.relationField : key.toLowerCase() + '_' + modelMetadata.relationField.toLowerCase();
|
|
82
94
|
const relatedToField = modelMetadata.relatedToField || 'id';
|
|
@@ -84,12 +96,13 @@ datasource db {
|
|
|
84
96
|
if (modelMetadata.required === false) {
|
|
85
97
|
requiredString = '?';
|
|
86
98
|
}
|
|
99
|
+
const cascadeStr = cascadeOpts.length ? `, ${cascadeOpts.join(', ')}` : '';
|
|
87
100
|
if (isMany) {
|
|
88
101
|
// Add an inverse field to the related model if it doesn't exist
|
|
89
|
-
section += `\t${key} ${relatedModel._collection}[] @relation("${relationName}", fields: [${relationFieldName}], references: [${relatedToField}]
|
|
102
|
+
section += `\t${key} ${relatedModel._collection}[] @relation(${relationName ? `"${relationName}", ` : ''}fields: [${relationFieldName}], references: [${relatedToField}]${mapName ? `, map: "${mapName}"` : ''}${cascadeStr})\n`;
|
|
90
103
|
}
|
|
91
104
|
else {
|
|
92
|
-
section += `\t${key} ${relatedModel._collection}${requiredString} @relation("${relationName}", fields: [${relationFieldName}], references: [${relatedToField}]
|
|
105
|
+
section += `\t${key} ${relatedModel._collection}${requiredString} @relation(${relationName ? `"${relationName}", ` : ''}fields: [${relationFieldName}], references: [${relatedToField}]${mapName ? `, map: "${mapName}"` : ''}${cascadeStr})\n`;
|
|
93
106
|
if (!bindingFieldExists) {
|
|
94
107
|
const relatedFieldMeta = relatedModelMetadatas[relatedToField];
|
|
95
108
|
if (!relatedFieldMeta.metadata.required) {
|
|
@@ -131,8 +144,11 @@ datasource db {
|
|
|
131
144
|
const relationKey = [relatedModelName, modelName].join('_');
|
|
132
145
|
const relationIndex = relation_manager_1.RelationManager.getRelationCounter(relationKey, true);
|
|
133
146
|
const relationName = relation_manager_1.RelationManager.getShortenedRelationName(relatedModelName, modelName, relationIndex);
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
let relationTag = '';
|
|
148
|
+
if (relationMeta.relationName) {
|
|
149
|
+
relationTag = ` @relation("${relationMeta.relationName}")`;
|
|
150
|
+
}
|
|
151
|
+
section += `\t${key} ${relationMeta.inversionModel._collection}[]${relationTag}\n`;
|
|
136
152
|
relation_manager_1.RelationManager.completeRelation(relationKey, relationIndex, true);
|
|
137
153
|
}
|
|
138
154
|
else if (annotationType === 'InverseTimeSeries') {
|
|
@@ -151,10 +167,16 @@ datasource db {
|
|
|
151
167
|
section += `\t${key} String[]\n`;
|
|
152
168
|
}
|
|
153
169
|
}
|
|
154
|
-
else
|
|
170
|
+
else {
|
|
155
171
|
const trackMeta = modelMetadata;
|
|
156
|
-
const
|
|
157
|
-
|
|
172
|
+
const trackTags = trackMeta.tags || [];
|
|
173
|
+
const tags = trackTags.map((item) => '@' + item);
|
|
174
|
+
const isNoIdBehavior = model._NO_ID || idFieldName;
|
|
175
|
+
const isOverrideBehavior = (hasIdType && annotationType === 'IdType' && key === 'id' && idFieldName === 'id')
|
|
176
|
+
||
|
|
177
|
+
(model._NO_ID && model._SUPER_TAGS.some(a => a.fields.includes('id')) && key === 'id');
|
|
178
|
+
if (key === 'id' &&
|
|
179
|
+
isNoIdBehavior && !isOverrideBehavior) {
|
|
158
180
|
continue;
|
|
159
181
|
}
|
|
160
182
|
if (trackMeta.unique) {
|
|
@@ -173,15 +195,41 @@ datasource db {
|
|
|
173
195
|
// Process any database-specific options from the metadata
|
|
174
196
|
const dbSpecificTags = type_converter_1.TypeConverter.processTypeOptions(trackMeta, dbType);
|
|
175
197
|
tags.push(...dbSpecificTags);
|
|
176
|
-
|
|
177
|
-
|
|
198
|
+
const isIdTypeField = modelMetadatas[key].annotationType === 'IdType';
|
|
199
|
+
const fieldInUniqueSuperTag = model._SUPER_TAGS.some(st => st.tagType === 'unique' && st.fields.includes(key));
|
|
200
|
+
if (isIdTypeField) {
|
|
201
|
+
requiredString = '';
|
|
202
|
+
}
|
|
203
|
+
let trackField = `${key} ${type_converter_1.TypeConverter.toConfigCase(trackMeta, dbType, key === 'id', isOverrideBehavior)}${requiredString} ${tags.join(' ')}`;
|
|
204
|
+
if (isIdTypeField) {
|
|
205
|
+
trackField += utils_1.DbUtils.addIdPart(dbType, utils_1.DbUtils.doesUseUuid(modelMetadatas), trackMeta.noAuto);
|
|
206
|
+
idGenerated = true;
|
|
178
207
|
}
|
|
179
|
-
section += `\t${
|
|
208
|
+
section += `\t${trackField}\n`;
|
|
180
209
|
}
|
|
181
210
|
}
|
|
211
|
+
if (model._SUPER_TAGS.length) {
|
|
212
|
+
section += '\n';
|
|
213
|
+
}
|
|
182
214
|
for (const superTag of model._SUPER_TAGS) {
|
|
183
215
|
const mapStr = superTag.map ? `, map: "${superTag.map}"` : '';
|
|
184
|
-
|
|
216
|
+
const superFields = [];
|
|
217
|
+
for (const superField of superTag.fields) {
|
|
218
|
+
const fieldMetadata = modelMetadatas[superField]['metadata'];
|
|
219
|
+
let pushed = false;
|
|
220
|
+
if (fieldMetadata.dbOptions && fieldMetadata.dbOptions.mysql && fieldMetadata.dbOptions.mysql.useType) {
|
|
221
|
+
switch (fieldMetadata.dbOptions.mysql.useType) {
|
|
222
|
+
case 'db.LongText':
|
|
223
|
+
superFields.push(`${superField}(length: 255)`);
|
|
224
|
+
pushed = true;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (!pushed) {
|
|
229
|
+
superFields.push(superField);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
section += `\t@@${superTag.tagType}([${superFields.join(', ')}]${mapStr})\n`;
|
|
185
233
|
}
|
|
186
234
|
section += '}\n';
|
|
187
235
|
return section;
|
|
@@ -224,7 +272,7 @@ datasource db {
|
|
|
224
272
|
for (const model of dbModels) {
|
|
225
273
|
const modelSection = await SchemaGenerator.generateModelSections(model, configService);
|
|
226
274
|
template += '\n\n' + modelSection;
|
|
227
|
-
log(chalk_1.default.green('[RWS]'), chalk_1.default.blue('Building DB Model'), model.name);
|
|
275
|
+
console.log(chalk_1.default.green('[RWS]'), chalk_1.default.blue('Building DB Model'), model.name);
|
|
228
276
|
}
|
|
229
277
|
const [schemaDir, schemaPath] = utils_1.DbUtils.getSchemaDir();
|
|
230
278
|
if (!fs_1.default.existsSync(schemaDir)) {
|
|
@@ -234,11 +282,11 @@ datasource db {
|
|
|
234
282
|
fs_1.default.unlinkSync(schemaPath);
|
|
235
283
|
}
|
|
236
284
|
fs_1.default.writeFileSync(schemaPath, template);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
log(chalk_1.default.green('[RWS Init]') + ' prisma schema generated from ', schemaPath);
|
|
240
|
-
if (
|
|
241
|
-
|
|
285
|
+
if (_EXECUTE_PRISMA_CMD)
|
|
286
|
+
await console_1.rwsShell.runCommand(`${utils_1.DbUtils.detectInstaller()} prisma generate --schema=${schemaPath}`, process.cwd());
|
|
287
|
+
console.log(chalk_1.default.green('[RWS Init]') + ' prisma schema generated from ', schemaPath);
|
|
288
|
+
if (_REMOVE_SCHEMA_FILE) {
|
|
289
|
+
fs_1.default.unlinkSync(schemaPath);
|
|
242
290
|
}
|
|
243
291
|
}
|
|
244
292
|
}
|
|
@@ -255,4 +303,3 @@ datasource db {
|
|
|
255
303
|
}
|
|
256
304
|
}
|
|
257
305
|
exports.SchemaGenerator = SchemaGenerator;
|
|
258
|
-
SchemaGenerator.dbUrlVarName = 'PRISMA_DB_URL';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IDbOpts } from '../../models/interfaces/IDbOpts';
|
|
2
2
|
import { ITrackerMetaOpts } from '../../models/_model';
|
|
3
3
|
import { IIdMetaOpts } from 'src/decorators/IdType';
|
|
4
|
+
import { IDbConfigParams } from 'src/types/DbConfigHandler';
|
|
4
5
|
/**
|
|
5
6
|
* Handles type conversion for database schema generation
|
|
6
7
|
*/
|
|
@@ -8,7 +9,7 @@ export declare class TypeConverter {
|
|
|
8
9
|
/**
|
|
9
10
|
* Convert a JavaScript type to a Prisma schema type
|
|
10
11
|
*/
|
|
11
|
-
static toConfigCase(modelType: ITrackerMetaOpts | IIdMetaOpts, dbType?:
|
|
12
|
+
static toConfigCase(modelType: ITrackerMetaOpts | IIdMetaOpts, dbType?: IDbConfigParams['db_type'], isId?: boolean, isIdOverride?: boolean): string;
|
|
12
13
|
/**
|
|
13
14
|
* Process type functions metadata to extract database-specific options
|
|
14
15
|
* @param metadata The metadata from a type function
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TypeConverter = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
4
5
|
/**
|
|
5
6
|
* Handles type conversion for database schema generation
|
|
6
7
|
*/
|
|
@@ -8,12 +9,30 @@ class TypeConverter {
|
|
|
8
9
|
/**
|
|
9
10
|
* Convert a JavaScript type to a Prisma schema type
|
|
10
11
|
*/
|
|
11
|
-
static toConfigCase(modelType, dbType = 'mongodb', isId = false) {
|
|
12
|
+
static toConfigCase(modelType, dbType = 'mongodb', isId = false, isIdOverride = false) {
|
|
12
13
|
const type = modelType.type;
|
|
13
14
|
let input = type.name;
|
|
14
15
|
// Handle basic types
|
|
15
16
|
if (input == 'Number') {
|
|
16
|
-
|
|
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;
|
|
23
|
+
}
|
|
24
|
+
if (['db.Decimal'].includes(modelType.dbOptions.mysql.useType)) {
|
|
25
|
+
input = 'Decimal';
|
|
26
|
+
numberOverride = true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!numberOverride) {
|
|
31
|
+
input = 'Int';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (input == 'BigInt') {
|
|
35
|
+
input = 'BigInt';
|
|
17
36
|
}
|
|
18
37
|
if (input == 'Object') {
|
|
19
38
|
input = 'Json';
|
|
@@ -38,8 +57,8 @@ class TypeConverter {
|
|
|
38
57
|
const firstChar = input.charAt(0).toUpperCase();
|
|
39
58
|
const restOfString = input.slice(1);
|
|
40
59
|
let resultField = firstChar + restOfString;
|
|
41
|
-
if (isId) {
|
|
42
|
-
return dbType
|
|
60
|
+
if (isId && !isIdOverride) {
|
|
61
|
+
return utils_1.DbUtils.getDefaultPrismaType(dbType, false);
|
|
43
62
|
}
|
|
44
63
|
const trackerModelType = modelType;
|
|
45
64
|
if (trackerModelType.isArray) {
|
|
@@ -66,20 +85,25 @@ class TypeConverter {
|
|
|
66
85
|
* @returns Array of tags to apply to the field
|
|
67
86
|
*/
|
|
68
87
|
static processTypeOptions(metadata, dbType) {
|
|
69
|
-
var _a, _b;
|
|
70
88
|
const tags = [...(metadata.tags || [])];
|
|
71
89
|
// Extract any database-specific options from the metadata
|
|
72
90
|
// and convert them to appropriate Prisma schema tags
|
|
73
91
|
if (metadata.dbOptions) {
|
|
74
92
|
// Handle MySQL-specific options
|
|
75
93
|
if (dbType === 'mysql' && metadata.dbOptions.mysql) {
|
|
94
|
+
let tag = null;
|
|
95
|
+
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})`;
|
|
99
|
+
}
|
|
76
100
|
if (metadata.dbOptions.mysql.useText) {
|
|
77
101
|
tags.push('@db.Text');
|
|
78
102
|
}
|
|
79
|
-
|
|
80
|
-
tags.push(
|
|
103
|
+
if (tag) {
|
|
104
|
+
tags.push(tag);
|
|
81
105
|
}
|
|
82
|
-
if (metadata.dbOptions.mysql.useUuid &&
|
|
106
|
+
if (metadata.dbOptions.mysql.useUuid && metadata.tags?.includes('id')) {
|
|
83
107
|
tags.push('default(uuid())');
|
|
84
108
|
}
|
|
85
109
|
}
|
|
@@ -88,7 +112,7 @@ class TypeConverter {
|
|
|
88
112
|
if (metadata.dbOptions.postgres.useText) {
|
|
89
113
|
tags.push('@db.Text');
|
|
90
114
|
}
|
|
91
|
-
if (metadata.dbOptions.postgres.useUuid &&
|
|
115
|
+
if (metadata.dbOptions.postgres.useUuid && metadata.tags?.includes('id')) {
|
|
92
116
|
tags.push('@default(uuid())');
|
|
93
117
|
tags.push('@db.Uuid');
|
|
94
118
|
}
|
|
@@ -19,6 +19,13 @@ export declare class DbUtils {
|
|
|
19
19
|
annotationType: string;
|
|
20
20
|
metadata: IIdMetaOpts;
|
|
21
21
|
}>, optional?: boolean): string;
|
|
22
|
+
static getDefaultPrismaType(dbType: IDbConfigParams['db_type'], useUuid: boolean): string;
|
|
23
|
+
static doesUseUuid(modelMeta: Record<string, {
|
|
24
|
+
annotationType: string;
|
|
25
|
+
metadata: IIdMetaOpts;
|
|
26
|
+
}>): boolean;
|
|
27
|
+
static addIdPart(dbType: IDbConfigParams['db_type'], useUuid: boolean, noAuto?: boolean): string;
|
|
28
|
+
static generateIdDefault(dbType: IDbConfigParams['db_type'], useUuid: boolean): string;
|
|
22
29
|
}
|
|
23
30
|
export declare const workspaceRootPath: string;
|
|
24
31
|
export declare const moduleDirPath: string;
|
package/dist/helper/db/utils.js
CHANGED
|
@@ -35,8 +35,7 @@ class DbUtils {
|
|
|
35
35
|
* Generate an ID field based on the database type
|
|
36
36
|
*/
|
|
37
37
|
static generateId(dbType, modelMeta, optional = false) {
|
|
38
|
-
|
|
39
|
-
let useUuid = false;
|
|
38
|
+
let useUuid = this.doesUseUuid(modelMeta);
|
|
40
39
|
let field = 'id';
|
|
41
40
|
const tags = [];
|
|
42
41
|
for (const key in modelMeta) {
|
|
@@ -47,50 +46,105 @@ class DbUtils {
|
|
|
47
46
|
const dbSpecificTags = type_converter_1.TypeConverter.processTypeOptions({ tags: [], dbOptions: modelMetadata.dbOptions }, dbType);
|
|
48
47
|
tags.push(...dbSpecificTags);
|
|
49
48
|
field = key;
|
|
50
|
-
if ((_b = (_a = modelMetadata.dbOptions) === null || _a === void 0 ? void 0 : _a.mysql) === null || _b === void 0 ? void 0 : _b.useUuid) {
|
|
51
|
-
useUuid = true;
|
|
52
|
-
}
|
|
53
|
-
if ((_d = (_c = modelMetadata.dbOptions) === null || _c === void 0 ? void 0 : _c.postgres) === null || _d === void 0 ? void 0 : _d.useUuid) {
|
|
54
|
-
useUuid = true;
|
|
55
|
-
}
|
|
56
|
-
if (modelMetadata.type.name === 'String') {
|
|
57
|
-
useUuid = true;
|
|
58
|
-
}
|
|
59
49
|
}
|
|
60
50
|
}
|
|
61
51
|
}
|
|
62
|
-
|
|
52
|
+
const idPrismaType = this.getDefaultPrismaType(dbType, useUuid);
|
|
63
53
|
let reqStr = '';
|
|
64
54
|
if (optional) {
|
|
65
55
|
reqStr = '?';
|
|
66
56
|
}
|
|
57
|
+
let idString = `${field} ${idPrismaType}${reqStr}`;
|
|
58
|
+
idString += this.addIdPart(dbType, useUuid, modelMeta[field].metadata.noAuto);
|
|
59
|
+
if (dbType === 'mongodb') {
|
|
60
|
+
tags.push('@map("_id")');
|
|
61
|
+
tags.push('@db.ObjectId');
|
|
62
|
+
}
|
|
63
|
+
if (tags.length) {
|
|
64
|
+
idString += ' ' + tags.join(' ');
|
|
65
|
+
}
|
|
66
|
+
if (!idString) {
|
|
67
|
+
throw new Error(`DB type "${dbType}" is not supported!`);
|
|
68
|
+
}
|
|
69
|
+
return idString;
|
|
70
|
+
}
|
|
71
|
+
static getDefaultPrismaType(dbType, useUuid) {
|
|
72
|
+
let idPrismaType = 'String';
|
|
67
73
|
switch (dbType) {
|
|
68
|
-
case 'mongodb':
|
|
69
|
-
idString = `${field} String${reqStr} @id @default(auto()) @map("_id") @db.ObjectId`;
|
|
70
|
-
break;
|
|
71
74
|
case 'mysql':
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
if (useUuid) {
|
|
76
|
+
idPrismaType = 'String';
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
idPrismaType = 'Int';
|
|
80
|
+
}
|
|
75
81
|
break;
|
|
76
82
|
case 'postgresql':
|
|
77
83
|
case 'postgres':
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
if (useUuid) {
|
|
85
|
+
idPrismaType = 'String';
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
idPrismaType = 'Int';
|
|
89
|
+
}
|
|
81
90
|
break;
|
|
82
91
|
case 'sqlite':
|
|
83
|
-
|
|
92
|
+
if (useUuid) {
|
|
93
|
+
idPrismaType = 'String';
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
idPrismaType = 'Int';
|
|
97
|
+
}
|
|
84
98
|
break;
|
|
85
99
|
}
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
return idPrismaType;
|
|
101
|
+
}
|
|
102
|
+
static doesUseUuid(modelMeta) {
|
|
103
|
+
let useUuid = false;
|
|
104
|
+
for (const key in modelMeta) {
|
|
105
|
+
const modelMetadata = modelMeta[key].metadata;
|
|
106
|
+
const annotationType = modelMeta[key].annotationType;
|
|
107
|
+
if (key !== 'id') {
|
|
108
|
+
if (annotationType == 'IdType') {
|
|
109
|
+
if (modelMetadata.dbOptions?.mysql?.useUuid) {
|
|
110
|
+
useUuid = true;
|
|
111
|
+
}
|
|
112
|
+
if (modelMetadata.dbOptions?.postgres?.useUuid) {
|
|
113
|
+
useUuid = true;
|
|
114
|
+
}
|
|
115
|
+
if (modelMetadata.type.name === 'String') {
|
|
116
|
+
useUuid = true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
88
120
|
}
|
|
89
|
-
|
|
90
|
-
|
|
121
|
+
return useUuid;
|
|
122
|
+
}
|
|
123
|
+
static addIdPart(dbType, useUuid, noAuto = false) {
|
|
124
|
+
let idString = ` @id${!noAuto ? ` @default(${this.generateIdDefault(dbType, useUuid)})` : ''}`;
|
|
125
|
+
if (dbType === 'mongodb') {
|
|
126
|
+
idString += ' @map("_id")';
|
|
127
|
+
idString += ' @db.ObjectId';
|
|
91
128
|
}
|
|
92
129
|
return idString;
|
|
93
130
|
}
|
|
131
|
+
static generateIdDefault(dbType, useUuid) {
|
|
132
|
+
switch (dbType) {
|
|
133
|
+
case 'mongodb':
|
|
134
|
+
return `auto()`;
|
|
135
|
+
case 'mysql':
|
|
136
|
+
return useUuid
|
|
137
|
+
? `uuid()`
|
|
138
|
+
: `autoincrement()`;
|
|
139
|
+
case 'postgresql':
|
|
140
|
+
case 'postgres':
|
|
141
|
+
return useUuid
|
|
142
|
+
? `uuid()`
|
|
143
|
+
: `autoincrement()`;
|
|
144
|
+
case 'sqlite':
|
|
145
|
+
return 'autoincrement()';
|
|
146
|
+
}
|
|
147
|
+
}
|
|
94
148
|
}
|
|
95
149
|
exports.DbUtils = DbUtils;
|
|
96
150
|
exports.workspaceRootPath = workspaceRoot;
|