@stonyx/orm 0.2.1-beta.33 → 0.2.1-beta.35
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/package.json +1 -1
- package/src/belongs-to.js +1 -4
- package/src/has-many.js +2 -5
- package/src/mysql/schema-introspector.js +28 -32
package/package.json
CHANGED
package/src/belongs-to.js
CHANGED
|
@@ -11,7 +11,7 @@ export default function belongsTo(modelName) {
|
|
|
11
11
|
const pendingHasManyQueue = relationships.get('pending');
|
|
12
12
|
const pendingBelongsToQueue = relationships.get('pendingBelongsTo');
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
return (sourceRecord, rawData, options) => {
|
|
15
15
|
if (!rawData) return null;
|
|
16
16
|
|
|
17
17
|
const { __name: sourceModelName } = sourceRecord.__model;
|
|
@@ -60,7 +60,4 @@ export default function belongsTo(modelName) {
|
|
|
60
60
|
|
|
61
61
|
return output;
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
fn.__relatedModelName = modelName;
|
|
65
|
-
return fn;
|
|
66
63
|
}
|
package/src/has-many.js
CHANGED
|
@@ -16,7 +16,7 @@ export default function hasMany(modelName) {
|
|
|
16
16
|
const globalRelationships = relationships.get('global');
|
|
17
17
|
const pendingRelationships = relationships.get('pending');
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
return (sourceRecord, rawData, options) => {
|
|
20
20
|
const { __name: sourceModelName } = sourceRecord.__model;
|
|
21
21
|
const relationshipId = sourceRecord.id;
|
|
22
22
|
const relationship = getRelationships('hasMany', sourceModelName, modelName, relationshipId);
|
|
@@ -49,7 +49,7 @@ export default function hasMany(modelName) {
|
|
|
49
49
|
}).filter(value => value);
|
|
50
50
|
|
|
51
51
|
relationship.set(relationshipId, output);
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
// Assign global relationship
|
|
54
54
|
if (options.global || sourceModelName === dbKey) getOrSet(globalRelationships, modelName, []).push(output);
|
|
55
55
|
|
|
@@ -58,7 +58,4 @@ export default function hasMany(modelName) {
|
|
|
58
58
|
|
|
59
59
|
return output;
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
fn.__relatedModelName = modelName;
|
|
63
|
-
return fn;
|
|
64
61
|
}
|
|
@@ -8,18 +8,13 @@ import { AggregateProperty } from '../aggregates.js';
|
|
|
8
8
|
function getRelationshipInfo(property) {
|
|
9
9
|
if (typeof property !== 'function') return null;
|
|
10
10
|
const fnStr = property.toString();
|
|
11
|
-
const modelName = property.__relatedModelName || null;
|
|
12
11
|
|
|
13
|
-
if (fnStr.includes(`getRelationships('belongsTo',`)) return
|
|
14
|
-
if (fnStr.includes(`getRelationships('hasMany',`)) return
|
|
12
|
+
if (fnStr.includes(`getRelationships('belongsTo',`)) return 'belongsTo';
|
|
13
|
+
if (fnStr.includes(`getRelationships('hasMany',`)) return 'hasMany';
|
|
15
14
|
|
|
16
15
|
return null;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
function sanitizeTableName(name) {
|
|
20
|
-
return name.replace(/[-/]/g, '_');
|
|
21
|
-
}
|
|
22
|
-
|
|
23
18
|
export function introspectModels() {
|
|
24
19
|
const { models } = Orm.instance;
|
|
25
20
|
const schemas = {};
|
|
@@ -40,12 +35,12 @@ export function introspectModels() {
|
|
|
40
35
|
for (const [key, property] of Object.entries(model)) {
|
|
41
36
|
if (key.startsWith('__')) continue;
|
|
42
37
|
|
|
43
|
-
const
|
|
38
|
+
const relType = getRelationshipInfo(property);
|
|
44
39
|
|
|
45
|
-
if (
|
|
46
|
-
relationships.belongsTo[key] =
|
|
47
|
-
} else if (
|
|
48
|
-
relationships.hasMany[key] =
|
|
40
|
+
if (relType === 'belongsTo') {
|
|
41
|
+
relationships.belongsTo[key] = true;
|
|
42
|
+
} else if (relType === 'hasMany') {
|
|
43
|
+
relationships.hasMany[key] = true;
|
|
49
44
|
} else if (property?.constructor?.name === 'ModelProperty') {
|
|
50
45
|
if (key === 'id') {
|
|
51
46
|
idType = property.type;
|
|
@@ -56,16 +51,17 @@ export function introspectModels() {
|
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
// Build foreign keys from belongsTo relationships
|
|
59
|
-
for (const
|
|
54
|
+
for (const relName of Object.keys(relationships.belongsTo)) {
|
|
55
|
+
const modelName = camelCaseToKebabCase(relName);
|
|
60
56
|
const fkColumn = `${relName}_id`;
|
|
61
57
|
foreignKeys[fkColumn] = {
|
|
62
|
-
references:
|
|
58
|
+
references: getPluralName(modelName),
|
|
63
59
|
column: 'id',
|
|
64
60
|
};
|
|
65
61
|
}
|
|
66
62
|
|
|
67
63
|
schemas[name] = {
|
|
68
|
-
table:
|
|
64
|
+
table: getPluralName(name),
|
|
69
65
|
idType,
|
|
70
66
|
columns,
|
|
71
67
|
foreignKeys,
|
|
@@ -78,8 +74,7 @@ export function introspectModels() {
|
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
export function buildTableDDL(name, schema, allSchemas = {}) {
|
|
81
|
-
const { idType, columns, foreignKeys } = schema;
|
|
82
|
-
const table = sanitizeTableName(schema.table);
|
|
77
|
+
const { table, idType, columns, foreignKeys } = schema;
|
|
83
78
|
const lines = [];
|
|
84
79
|
|
|
85
80
|
// Primary key
|
|
@@ -106,8 +101,7 @@ export function buildTableDDL(name, schema, allSchemas = {}) {
|
|
|
106
101
|
|
|
107
102
|
// Foreign key constraints
|
|
108
103
|
for (const [fkCol, fkDef] of Object.entries(foreignKeys)) {
|
|
109
|
-
|
|
110
|
-
lines.push(` FOREIGN KEY (\`${fkCol}\`) REFERENCES \`${refTable}\`(\`${fkDef.column}\`) ON DELETE SET NULL`);
|
|
104
|
+
lines.push(` FOREIGN KEY (\`${fkCol}\`) REFERENCES \`${fkDef.references}\`(\`${fkDef.column}\`) ON DELETE SET NULL`);
|
|
111
105
|
}
|
|
112
106
|
|
|
113
107
|
return `CREATE TABLE IF NOT EXISTS \`${table}\` (\n${lines.join(',\n')}\n)`;
|
|
@@ -137,8 +131,8 @@ export function getTopologicalOrder(schemas) {
|
|
|
137
131
|
if (!schema) return;
|
|
138
132
|
|
|
139
133
|
// Visit dependencies (belongsTo targets) first
|
|
140
|
-
for (const
|
|
141
|
-
visit(
|
|
134
|
+
for (const relName of Object.keys(schema.relationships.belongsTo)) {
|
|
135
|
+
visit(camelCaseToKebabCase(relName));
|
|
142
136
|
}
|
|
143
137
|
|
|
144
138
|
order.push(name);
|
|
@@ -178,17 +172,18 @@ export function introspectViews() {
|
|
|
178
172
|
continue;
|
|
179
173
|
}
|
|
180
174
|
|
|
181
|
-
const
|
|
175
|
+
const relType = getRelationshipInfo(property);
|
|
182
176
|
|
|
183
|
-
if (
|
|
184
|
-
relationships.belongsTo[key] =
|
|
177
|
+
if (relType === 'belongsTo') {
|
|
178
|
+
relationships.belongsTo[key] = true;
|
|
179
|
+
const modelName = camelCaseToKebabCase(key);
|
|
185
180
|
const fkColumn = `${key}_id`;
|
|
186
181
|
foreignKeys[fkColumn] = {
|
|
187
|
-
references:
|
|
182
|
+
references: getPluralName(modelName),
|
|
188
183
|
column: 'id',
|
|
189
184
|
};
|
|
190
|
-
} else if (
|
|
191
|
-
relationships.hasMany[key] =
|
|
185
|
+
} else if (relType === 'hasMany') {
|
|
186
|
+
relationships.hasMany[key] = true;
|
|
192
187
|
} else if (property?.constructor?.name === 'ModelProperty') {
|
|
193
188
|
const transforms = Orm.instance.transforms;
|
|
194
189
|
columns[key] = getMysqlType(property.type, transforms[property.type]);
|
|
@@ -196,7 +191,7 @@ export function introspectViews() {
|
|
|
196
191
|
}
|
|
197
192
|
|
|
198
193
|
schemas[name] = {
|
|
199
|
-
viewName:
|
|
194
|
+
viewName: getPluralName(name),
|
|
200
195
|
source,
|
|
201
196
|
groupBy: viewClass.groupBy || undefined,
|
|
202
197
|
columns,
|
|
@@ -218,9 +213,9 @@ export function buildViewDDL(name, viewSchema, modelSchemas = {}) {
|
|
|
218
213
|
|
|
219
214
|
const sourceModelName = viewSchema.source;
|
|
220
215
|
const sourceSchema = modelSchemas[sourceModelName];
|
|
221
|
-
const sourceTable =
|
|
216
|
+
const sourceTable = sourceSchema
|
|
222
217
|
? sourceSchema.table
|
|
223
|
-
: getPluralName(sourceModelName)
|
|
218
|
+
: getPluralName(sourceModelName);
|
|
224
219
|
|
|
225
220
|
const selectColumns = [];
|
|
226
221
|
const joins = [];
|
|
@@ -246,7 +241,8 @@ export function buildViewDDL(name, viewSchema, modelSchemas = {}) {
|
|
|
246
241
|
} else {
|
|
247
242
|
// Relationship aggregate
|
|
248
243
|
const relName = aggProp.relationship;
|
|
249
|
-
const
|
|
244
|
+
const relModelName = camelCaseToKebabCase(relName);
|
|
245
|
+
const relTable = getPluralName(relModelName);
|
|
250
246
|
|
|
251
247
|
if (aggProp.aggregateType === 'count') {
|
|
252
248
|
selectColumns.push(`${aggProp.mysqlFunction}(\`${relTable}\`.\`id\`) AS \`${key}\``);
|
|
@@ -285,7 +281,7 @@ export function buildViewDDL(name, viewSchema, modelSchemas = {}) {
|
|
|
285
281
|
groupBy = `\nGROUP BY \`${sourceTable}\`.\`id\``;
|
|
286
282
|
}
|
|
287
283
|
|
|
288
|
-
const viewName =
|
|
284
|
+
const viewName = viewSchema.viewName;
|
|
289
285
|
const sql = `CREATE OR REPLACE VIEW \`${viewName}\` AS\nSELECT\n ${selectColumns.join(',\n ')}\nFROM \`${sourceTable}\`${joinClauses ? '\n ' + joinClauses : ''}${groupBy}`;
|
|
290
286
|
|
|
291
287
|
return sql;
|