@chihqiang/sql-quicktype 0.0.1 → 0.0.3
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/README.md +33 -30
- package/dist/cli.js +707 -770
- package/dist/index.d.mts +46 -62
- package/dist/index.d.ts +46 -62
- package/dist/index.global.js +96 -96
- package/dist/index.js +649 -810
- package/dist/index.mjs +650 -805
- package/package.json +12 -13
package/dist/index.mjs
CHANGED
|
@@ -1,699 +1,12 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn, res) => function __init() {
|
|
4
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
-
};
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
// src/generator/TypeScriptGenerator.ts
|
|
12
|
-
var TypeScriptGenerator_exports = {};
|
|
13
|
-
__export(TypeScriptGenerator_exports, {
|
|
14
|
-
TypeScriptGenerator: () => TypeScriptGenerator
|
|
15
|
-
});
|
|
16
|
-
var TypeScriptGenerator;
|
|
17
|
-
var init_TypeScriptGenerator = __esm({
|
|
18
|
-
"src/generator/TypeScriptGenerator.ts"() {
|
|
19
|
-
"use strict";
|
|
20
|
-
init_generator();
|
|
21
|
-
TypeScriptGenerator = class extends AGenerator {
|
|
22
|
-
constructor(options = { language: "typescript" }) {
|
|
23
|
-
super();
|
|
24
|
-
this.options = options;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* 格式化字段名称(使用驼峰命名)
|
|
28
|
-
*/
|
|
29
|
-
formatFieldName(name) {
|
|
30
|
-
return name.split("_").map((part, index) => {
|
|
31
|
-
if (index === 0) {
|
|
32
|
-
return part.toLowerCase();
|
|
33
|
-
}
|
|
34
|
-
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
35
|
-
}).join("");
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 生成整个数据库模式的类型定义
|
|
39
|
-
*/
|
|
40
|
-
generateDatabase(database) {
|
|
41
|
-
let result = `// Database: ${database.name}
|
|
42
|
-
`;
|
|
43
|
-
result += `// Dialect: ${database.dialect}
|
|
44
|
-
|
|
45
|
-
`;
|
|
46
|
-
for (const table of database.tables) {
|
|
47
|
-
result += this.generateTable(table);
|
|
48
|
-
result += "\n";
|
|
49
|
-
}
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* 生成单个表的类型定义
|
|
54
|
-
*/
|
|
55
|
-
generateTable(table) {
|
|
56
|
-
let result = `// ${table.name} \u8868\u7ED3\u6784
|
|
57
|
-
`;
|
|
58
|
-
result += `export interface ${this.formatTypeName(table.name)} {
|
|
59
|
-
`;
|
|
60
|
-
for (const column of table.columns) {
|
|
61
|
-
result += this.generateColumn(column);
|
|
62
|
-
}
|
|
63
|
-
result += "}\n";
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* 生成列的类型定义
|
|
68
|
-
*/
|
|
69
|
-
generateColumn(column) {
|
|
70
|
-
const fieldName = this.formatFieldName(column.name);
|
|
71
|
-
const typeName = this.mapSQLType(column.type, column.name);
|
|
72
|
-
const optional = column.nullable ? "?" : "";
|
|
73
|
-
let result = ` ${fieldName}${optional}: ${typeName}`;
|
|
74
|
-
if (column.comment && this.options.generateComments !== false) {
|
|
75
|
-
result += `; // ${column.comment}`;
|
|
76
|
-
}
|
|
77
|
-
result += "\n";
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* 映射 SQL 类型到 TypeScript 类型
|
|
82
|
-
*/
|
|
83
|
-
mapSQLType(type, columnName) {
|
|
84
|
-
switch (type.kind) {
|
|
85
|
-
case "int":
|
|
86
|
-
case "bigint":
|
|
87
|
-
return "number";
|
|
88
|
-
case "float":
|
|
89
|
-
case "decimal":
|
|
90
|
-
return "number";
|
|
91
|
-
case "varchar":
|
|
92
|
-
case "text":
|
|
93
|
-
return "string";
|
|
94
|
-
case "boolean":
|
|
95
|
-
return "boolean";
|
|
96
|
-
case "date":
|
|
97
|
-
case "datetime":
|
|
98
|
-
return "Date";
|
|
99
|
-
case "json":
|
|
100
|
-
return "unknown";
|
|
101
|
-
case "enum":
|
|
102
|
-
if (type.values && type.values.length > 0) {
|
|
103
|
-
const enumValues = type.values.map((v) => `'${v}'`).join(" | ");
|
|
104
|
-
if (columnName) {
|
|
105
|
-
const fieldName = this.formatFieldName(columnName);
|
|
106
|
-
return `${fieldName}: ${enumValues}`;
|
|
107
|
-
}
|
|
108
|
-
return enumValues;
|
|
109
|
-
}
|
|
110
|
-
return "string";
|
|
111
|
-
default:
|
|
112
|
-
return "string";
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// src/generator/GolangGenerator.ts
|
|
120
|
-
var GolangGenerator_exports = {};
|
|
121
|
-
__export(GolangGenerator_exports, {
|
|
122
|
-
GolangGenerator: () => GolangGenerator
|
|
123
|
-
});
|
|
124
|
-
var GolangGenerator;
|
|
125
|
-
var init_GolangGenerator = __esm({
|
|
126
|
-
"src/generator/GolangGenerator.ts"() {
|
|
127
|
-
"use strict";
|
|
128
|
-
init_generator();
|
|
129
|
-
GolangGenerator = class extends AGenerator {
|
|
130
|
-
constructor(options = { language: "go" }) {
|
|
131
|
-
super();
|
|
132
|
-
this.options = options;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* 生成整个数据库模式的类型定义
|
|
136
|
-
*/
|
|
137
|
-
generateDatabase(database) {
|
|
138
|
-
let result = `// Database: ${database.name}
|
|
139
|
-
`;
|
|
140
|
-
result += `// Dialect: ${database.dialect}
|
|
141
|
-
|
|
142
|
-
`;
|
|
143
|
-
if (this.options.namespace) {
|
|
144
|
-
result += `package ${this.options.namespace}
|
|
145
|
-
|
|
146
|
-
`;
|
|
147
|
-
}
|
|
148
|
-
if (this.needsTimeImport(database)) {
|
|
149
|
-
result += `import "time"
|
|
150
|
-
|
|
151
|
-
`;
|
|
152
|
-
}
|
|
153
|
-
for (const table of database.tables) {
|
|
154
|
-
result += this.generateTable(table);
|
|
155
|
-
result += "\n";
|
|
156
|
-
}
|
|
157
|
-
return result;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* 生成单个表的类型定义
|
|
161
|
-
*/
|
|
162
|
-
generateTable(table) {
|
|
163
|
-
let result = `// ${table.name} \u8868\u7ED3\u6784
|
|
164
|
-
`;
|
|
165
|
-
result += `type ${this.formatTypeName(table.name)} struct {
|
|
166
|
-
`;
|
|
167
|
-
for (const column of table.columns) {
|
|
168
|
-
result += this.generateColumn(column);
|
|
169
|
-
}
|
|
170
|
-
result += "}\n";
|
|
171
|
-
return result;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* 生成列的类型定义
|
|
175
|
-
*/
|
|
176
|
-
generateColumn(column) {
|
|
177
|
-
const fieldName = this.formatFieldName(column.name);
|
|
178
|
-
const typeName = this.mapSQLType(column.type);
|
|
179
|
-
const tag = this.generateGoTag(column);
|
|
180
|
-
let result = ` ${fieldName} ${typeName} ${tag}`;
|
|
181
|
-
if (column.comment && this.options.generateComments !== false) {
|
|
182
|
-
result += ` // ${column.comment}`;
|
|
183
|
-
}
|
|
184
|
-
result += "\n";
|
|
185
|
-
return result;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* 映射 SQL 类型到 Go 类型
|
|
189
|
-
*/
|
|
190
|
-
mapSQLType(type) {
|
|
191
|
-
switch (type.kind) {
|
|
192
|
-
case "int":
|
|
193
|
-
return "int";
|
|
194
|
-
case "bigint":
|
|
195
|
-
return "int64";
|
|
196
|
-
case "float":
|
|
197
|
-
return "float64";
|
|
198
|
-
case "decimal":
|
|
199
|
-
return "float64";
|
|
200
|
-
case "varchar":
|
|
201
|
-
case "text":
|
|
202
|
-
return "string";
|
|
203
|
-
case "boolean":
|
|
204
|
-
return "bool";
|
|
205
|
-
case "date":
|
|
206
|
-
case "datetime":
|
|
207
|
-
return "time.Time";
|
|
208
|
-
case "json":
|
|
209
|
-
return "interface{}";
|
|
210
|
-
case "enum":
|
|
211
|
-
return "string";
|
|
212
|
-
default:
|
|
213
|
-
return "string";
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* 生成 Go 结构体标签
|
|
218
|
-
*/
|
|
219
|
-
generateGoTag(column) {
|
|
220
|
-
const tags = [];
|
|
221
|
-
tags.push(`json:"${column.name}"`);
|
|
222
|
-
tags.push(`db:"${column.name}"`);
|
|
223
|
-
return `\`${tags.join(" ")}\``;
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
// src/generator/GormGenerator.ts
|
|
230
|
-
var GormGenerator_exports = {};
|
|
231
|
-
__export(GormGenerator_exports, {
|
|
232
|
-
GormGenerator: () => GormGenerator
|
|
233
|
-
});
|
|
234
|
-
var GormGenerator;
|
|
235
|
-
var init_GormGenerator = __esm({
|
|
236
|
-
"src/generator/GormGenerator.ts"() {
|
|
237
|
-
"use strict";
|
|
238
|
-
init_generator();
|
|
239
|
-
GormGenerator = class extends AGenerator {
|
|
240
|
-
constructor(options = { language: "gorm" }) {
|
|
241
|
-
super();
|
|
242
|
-
this.options = options;
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* 生成整个数据库模式的类型定义
|
|
246
|
-
*/
|
|
247
|
-
generateDatabase(database) {
|
|
248
|
-
let result = `// Database: ${database.name}
|
|
249
|
-
`;
|
|
250
|
-
result += `// Dialect: ${database.dialect}
|
|
251
|
-
|
|
252
|
-
`;
|
|
253
|
-
if (this.options.namespace) {
|
|
254
|
-
result += `package ${this.options.namespace}
|
|
255
|
-
|
|
256
|
-
`;
|
|
257
|
-
}
|
|
258
|
-
if (this.needsTimeImport(database)) {
|
|
259
|
-
result += `import "time"
|
|
260
|
-
|
|
261
|
-
`;
|
|
262
|
-
}
|
|
263
|
-
for (const table of database.tables) {
|
|
264
|
-
result += this.generateTable(table);
|
|
265
|
-
result += "\n";
|
|
266
|
-
}
|
|
267
|
-
return result;
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* 生成单个表的类型定义
|
|
271
|
-
*/
|
|
272
|
-
generateTable(table) {
|
|
273
|
-
let result = `// ${table.name} \u8868\u7ED3\u6784
|
|
274
|
-
`;
|
|
275
|
-
result += `type ${this.formatTypeName(table.name)} struct {
|
|
276
|
-
`;
|
|
277
|
-
for (const column of table.columns) {
|
|
278
|
-
result += this.generateColumn(column);
|
|
279
|
-
}
|
|
280
|
-
result += "}\n";
|
|
281
|
-
return result;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* 生成列的类型定义
|
|
285
|
-
*/
|
|
286
|
-
generateColumn(column) {
|
|
287
|
-
const fieldName = this.formatFieldName(column.name);
|
|
288
|
-
const typeName = this.mapSQLType(column.type);
|
|
289
|
-
const tag = this.generateGormTag(column);
|
|
290
|
-
let result = ` ${fieldName} ${typeName} ${tag}`;
|
|
291
|
-
if (column.comment && this.options.generateComments !== false) {
|
|
292
|
-
result += ` // ${column.comment}`;
|
|
293
|
-
}
|
|
294
|
-
result += "\n";
|
|
295
|
-
return result;
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* 映射 SQL 类型到 GORM 类型
|
|
299
|
-
*/
|
|
300
|
-
mapSQLType(type) {
|
|
301
|
-
switch (type.kind) {
|
|
302
|
-
case "int":
|
|
303
|
-
return "int";
|
|
304
|
-
case "bigint":
|
|
305
|
-
return "int64";
|
|
306
|
-
case "float":
|
|
307
|
-
return "float64";
|
|
308
|
-
case "decimal":
|
|
309
|
-
return "float64";
|
|
310
|
-
case "varchar":
|
|
311
|
-
case "text":
|
|
312
|
-
return "string";
|
|
313
|
-
case "boolean":
|
|
314
|
-
return "bool";
|
|
315
|
-
case "date":
|
|
316
|
-
case "datetime":
|
|
317
|
-
return "time.Time";
|
|
318
|
-
case "json":
|
|
319
|
-
return "interface{}";
|
|
320
|
-
case "enum":
|
|
321
|
-
return "string";
|
|
322
|
-
default:
|
|
323
|
-
return "string";
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* 生成 GORM 结构体标签
|
|
328
|
-
*/
|
|
329
|
-
generateGormTag(column) {
|
|
330
|
-
const tags = [];
|
|
331
|
-
tags.push(`column:${column.name}`);
|
|
332
|
-
let typeTag = "type:";
|
|
333
|
-
switch (column.type.kind) {
|
|
334
|
-
case "int":
|
|
335
|
-
typeTag += "int";
|
|
336
|
-
if (column.type.length) {
|
|
337
|
-
typeTag += `(${column.type.length})`;
|
|
338
|
-
}
|
|
339
|
-
break;
|
|
340
|
-
case "bigint":
|
|
341
|
-
typeTag += "bigint";
|
|
342
|
-
if (column.type.length) {
|
|
343
|
-
typeTag += `(${column.type.length})`;
|
|
344
|
-
}
|
|
345
|
-
break;
|
|
346
|
-
case "float":
|
|
347
|
-
typeTag += "float";
|
|
348
|
-
if (column.type.precision) {
|
|
349
|
-
typeTag += `(${column.type.precision}`;
|
|
350
|
-
if (column.type.scale) {
|
|
351
|
-
typeTag += `,${column.type.scale}`;
|
|
352
|
-
}
|
|
353
|
-
typeTag += ")";
|
|
354
|
-
}
|
|
355
|
-
break;
|
|
356
|
-
case "decimal":
|
|
357
|
-
typeTag += "decimal";
|
|
358
|
-
if (column.type.precision) {
|
|
359
|
-
typeTag += `(${column.type.precision}`;
|
|
360
|
-
if (column.type.scale) {
|
|
361
|
-
typeTag += `,${column.type.scale}`;
|
|
362
|
-
}
|
|
363
|
-
typeTag += ")";
|
|
364
|
-
}
|
|
365
|
-
break;
|
|
366
|
-
case "varchar":
|
|
367
|
-
typeTag += "varchar";
|
|
368
|
-
if (column.type.length) {
|
|
369
|
-
typeTag += `(${column.type.length})`;
|
|
370
|
-
}
|
|
371
|
-
break;
|
|
372
|
-
case "text":
|
|
373
|
-
typeTag += "text";
|
|
374
|
-
break;
|
|
375
|
-
case "boolean":
|
|
376
|
-
typeTag += "bool";
|
|
377
|
-
break;
|
|
378
|
-
case "date":
|
|
379
|
-
typeTag += "date";
|
|
380
|
-
break;
|
|
381
|
-
case "datetime":
|
|
382
|
-
typeTag += "datetime";
|
|
383
|
-
break;
|
|
384
|
-
case "json":
|
|
385
|
-
typeTag += "json";
|
|
386
|
-
break;
|
|
387
|
-
case "enum":
|
|
388
|
-
typeTag += "enum";
|
|
389
|
-
break;
|
|
390
|
-
default:
|
|
391
|
-
typeTag += "string";
|
|
392
|
-
}
|
|
393
|
-
tags.push(typeTag);
|
|
394
|
-
if (column.primaryKey) {
|
|
395
|
-
tags.push("primaryKey");
|
|
396
|
-
}
|
|
397
|
-
if (column.unique) {
|
|
398
|
-
tags.push("unique");
|
|
399
|
-
}
|
|
400
|
-
if (!column.nullable) {
|
|
401
|
-
tags.push("not null");
|
|
402
|
-
}
|
|
403
|
-
if (column.default) {
|
|
404
|
-
tags.push(`default:${column.default}`);
|
|
405
|
-
}
|
|
406
|
-
if (column.generated) {
|
|
407
|
-
tags.push("autoIncrement");
|
|
408
|
-
}
|
|
409
|
-
if (column.comment) {
|
|
410
|
-
tags.push(`comment:${column.comment}`);
|
|
411
|
-
}
|
|
412
|
-
return `\`gorm:"${tags.join(";")}" json:"${column.name}"\``;
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
// src/generator/XormGenerator.ts
|
|
419
|
-
var XormGenerator_exports = {};
|
|
420
|
-
__export(XormGenerator_exports, {
|
|
421
|
-
XormGenerator: () => XormGenerator
|
|
422
|
-
});
|
|
423
|
-
var XormGenerator;
|
|
424
|
-
var init_XormGenerator = __esm({
|
|
425
|
-
"src/generator/XormGenerator.ts"() {
|
|
426
|
-
"use strict";
|
|
427
|
-
init_generator();
|
|
428
|
-
XormGenerator = class extends AGenerator {
|
|
429
|
-
constructor(options = { language: "xorm" }) {
|
|
430
|
-
super();
|
|
431
|
-
this.options = options;
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* 生成整个数据库模式的类型定义
|
|
435
|
-
*/
|
|
436
|
-
generateDatabase(database) {
|
|
437
|
-
let result = `// Database: ${database.name}
|
|
438
|
-
`;
|
|
439
|
-
result += `// Dialect: ${database.dialect}
|
|
440
|
-
|
|
441
|
-
`;
|
|
442
|
-
if (this.options.namespace) {
|
|
443
|
-
result += `package ${this.options.namespace}
|
|
444
|
-
|
|
445
|
-
`;
|
|
446
|
-
}
|
|
447
|
-
if (this.needsTimeImport(database)) {
|
|
448
|
-
result += `import "time"
|
|
449
|
-
|
|
450
|
-
`;
|
|
451
|
-
}
|
|
452
|
-
for (const table of database.tables) {
|
|
453
|
-
result += this.generateTable(table);
|
|
454
|
-
result += "\n";
|
|
455
|
-
}
|
|
456
|
-
return result;
|
|
457
|
-
}
|
|
458
|
-
/**
|
|
459
|
-
* 生成单个表的类型定义
|
|
460
|
-
*/
|
|
461
|
-
generateTable(table) {
|
|
462
|
-
let result = `// ${table.name} \u8868\u7ED3\u6784
|
|
463
|
-
`;
|
|
464
|
-
result += `type ${this.formatTypeName(table.name)} struct {
|
|
465
|
-
`;
|
|
466
|
-
for (const column of table.columns) {
|
|
467
|
-
result += this.generateColumn(column);
|
|
468
|
-
}
|
|
469
|
-
result += "}\n";
|
|
470
|
-
return result;
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* 生成列的类型定义
|
|
474
|
-
*/
|
|
475
|
-
generateColumn(column) {
|
|
476
|
-
const fieldName = this.formatFieldName(column.name);
|
|
477
|
-
const typeName = this.mapSQLType(column.type);
|
|
478
|
-
const tag = this.generateXormTag(column);
|
|
479
|
-
let result = ` ${fieldName} ${typeName} ${tag}`;
|
|
480
|
-
if (column.comment && this.options.generateComments !== false) {
|
|
481
|
-
result += ` // ${column.comment}`;
|
|
482
|
-
}
|
|
483
|
-
result += "\n";
|
|
484
|
-
return result;
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* 映射 SQL 类型到 XORM 类型
|
|
488
|
-
*/
|
|
489
|
-
mapSQLType(type) {
|
|
490
|
-
switch (type.kind) {
|
|
491
|
-
case "int":
|
|
492
|
-
return "int";
|
|
493
|
-
case "bigint":
|
|
494
|
-
return "int64";
|
|
495
|
-
case "float":
|
|
496
|
-
return "float64";
|
|
497
|
-
case "decimal":
|
|
498
|
-
return "float64";
|
|
499
|
-
case "varchar":
|
|
500
|
-
case "text":
|
|
501
|
-
return "string";
|
|
502
|
-
case "boolean":
|
|
503
|
-
return "bool";
|
|
504
|
-
case "date":
|
|
505
|
-
case "datetime":
|
|
506
|
-
return "time.Time";
|
|
507
|
-
case "json":
|
|
508
|
-
return "interface{}";
|
|
509
|
-
case "enum":
|
|
510
|
-
return "string";
|
|
511
|
-
default:
|
|
512
|
-
return "string";
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* 生成 XORM 结构体标签
|
|
517
|
-
*/
|
|
518
|
-
generateXormTag(column) {
|
|
519
|
-
const tags = [];
|
|
520
|
-
tags.push(`${column.name}`);
|
|
521
|
-
let typeTag = "";
|
|
522
|
-
switch (column.type.kind) {
|
|
523
|
-
case "int":
|
|
524
|
-
typeTag = "int";
|
|
525
|
-
if (column.type.length) {
|
|
526
|
-
typeTag += `(${column.type.length})`;
|
|
527
|
-
}
|
|
528
|
-
break;
|
|
529
|
-
case "bigint":
|
|
530
|
-
typeTag = "bigint";
|
|
531
|
-
if (column.type.length) {
|
|
532
|
-
typeTag += `(${column.type.length})`;
|
|
533
|
-
}
|
|
534
|
-
break;
|
|
535
|
-
case "float":
|
|
536
|
-
typeTag = "float";
|
|
537
|
-
if (column.type.precision) {
|
|
538
|
-
typeTag += `(${column.type.precision}`;
|
|
539
|
-
if (column.type.scale) {
|
|
540
|
-
typeTag += `,${column.type.scale}`;
|
|
541
|
-
}
|
|
542
|
-
typeTag += ")";
|
|
543
|
-
}
|
|
544
|
-
break;
|
|
545
|
-
case "decimal":
|
|
546
|
-
typeTag = "decimal";
|
|
547
|
-
if (column.type.precision) {
|
|
548
|
-
typeTag += `(${column.type.precision}`;
|
|
549
|
-
if (column.type.scale) {
|
|
550
|
-
typeTag += `,${column.type.scale}`;
|
|
551
|
-
}
|
|
552
|
-
typeTag += ")";
|
|
553
|
-
}
|
|
554
|
-
break;
|
|
555
|
-
case "varchar":
|
|
556
|
-
typeTag = "varchar";
|
|
557
|
-
if (column.type.length) {
|
|
558
|
-
typeTag += `(${column.type.length})`;
|
|
559
|
-
}
|
|
560
|
-
break;
|
|
561
|
-
case "text":
|
|
562
|
-
typeTag = "text";
|
|
563
|
-
break;
|
|
564
|
-
case "boolean":
|
|
565
|
-
typeTag = "bool";
|
|
566
|
-
break;
|
|
567
|
-
case "date":
|
|
568
|
-
typeTag = "date";
|
|
569
|
-
break;
|
|
570
|
-
case "datetime":
|
|
571
|
-
typeTag = "datetime";
|
|
572
|
-
break;
|
|
573
|
-
case "json":
|
|
574
|
-
typeTag = "json";
|
|
575
|
-
break;
|
|
576
|
-
case "enum":
|
|
577
|
-
typeTag = "enum";
|
|
578
|
-
break;
|
|
579
|
-
default:
|
|
580
|
-
typeTag = "string";
|
|
581
|
-
}
|
|
582
|
-
if (typeTag) {
|
|
583
|
-
tags.push(typeTag);
|
|
584
|
-
}
|
|
585
|
-
if (column.primaryKey) {
|
|
586
|
-
tags.push("pk");
|
|
587
|
-
}
|
|
588
|
-
if (column.unique) {
|
|
589
|
-
tags.push("unique");
|
|
590
|
-
}
|
|
591
|
-
if (!column.nullable) {
|
|
592
|
-
tags.push("notnull");
|
|
593
|
-
}
|
|
594
|
-
if (column.default) {
|
|
595
|
-
tags.push(`default(${column.default})`);
|
|
596
|
-
}
|
|
597
|
-
if (column.generated) {
|
|
598
|
-
tags.push("autoincr");
|
|
599
|
-
}
|
|
600
|
-
if (column.comment) {
|
|
601
|
-
tags.push(`comment(${column.comment})`);
|
|
602
|
-
}
|
|
603
|
-
return `\`xorm:"${tags.join(" ")}" json:"${column.name}"\``;
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
}
|
|
607
|
-
});
|
|
608
|
-
|
|
609
|
-
// src/generator/generator.ts
|
|
610
|
-
var AGenerator, GeneratorFactory;
|
|
611
|
-
var init_generator = __esm({
|
|
612
|
-
"src/generator/generator.ts"() {
|
|
613
|
-
"use strict";
|
|
614
|
-
AGenerator = class {
|
|
615
|
-
/**
|
|
616
|
-
* 格式化类型名称(如驼峰命名、帕斯卡命名等)
|
|
617
|
-
*/
|
|
618
|
-
formatTypeName(name) {
|
|
619
|
-
return name.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* 格式化字段名称
|
|
623
|
-
*/
|
|
624
|
-
formatFieldName(name) {
|
|
625
|
-
return name.split("_").map((part) => {
|
|
626
|
-
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
627
|
-
}).join("");
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* 生成默认值
|
|
631
|
-
*/
|
|
632
|
-
generateDefaultValue(column) {
|
|
633
|
-
if (!column.default) {
|
|
634
|
-
return "";
|
|
635
|
-
}
|
|
636
|
-
return column.default;
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* 检查是否需要导入 time 包
|
|
640
|
-
*/
|
|
641
|
-
needsTimeImport(database) {
|
|
642
|
-
for (const table of database.tables) {
|
|
643
|
-
for (const column of table.columns) {
|
|
644
|
-
if (column.type.kind === "date" || column.type.kind === "datetime") {
|
|
645
|
-
return true;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return false;
|
|
650
|
-
}
|
|
651
|
-
};
|
|
652
|
-
GeneratorFactory = class {
|
|
653
|
-
/**
|
|
654
|
-
* 创建语言生成器实例
|
|
655
|
-
* @param language 目标语言
|
|
656
|
-
* @param options 生成器配置选项
|
|
657
|
-
* @returns 语言生成器实例
|
|
658
|
-
*/
|
|
659
|
-
static async createGenerator(language, options = { language }) {
|
|
660
|
-
switch (language) {
|
|
661
|
-
case "typescript":
|
|
662
|
-
const { TypeScriptGenerator: TypeScriptGenerator2 } = await Promise.resolve().then(() => (init_TypeScriptGenerator(), TypeScriptGenerator_exports));
|
|
663
|
-
return new TypeScriptGenerator2(options);
|
|
664
|
-
case "go":
|
|
665
|
-
const { GolangGenerator: GolangGenerator2 } = await Promise.resolve().then(() => (init_GolangGenerator(), GolangGenerator_exports));
|
|
666
|
-
return new GolangGenerator2(options);
|
|
667
|
-
case "gorm":
|
|
668
|
-
const { GormGenerator: GormGenerator2 } = await Promise.resolve().then(() => (init_GormGenerator(), GormGenerator_exports));
|
|
669
|
-
return new GormGenerator2(options);
|
|
670
|
-
case "xorm":
|
|
671
|
-
const { XormGenerator: XormGenerator2 } = await Promise.resolve().then(() => (init_XormGenerator(), XormGenerator_exports));
|
|
672
|
-
return new XormGenerator2(options);
|
|
673
|
-
default:
|
|
674
|
-
throw new Error(`Unsupported language: ${language}`);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
|
|
681
1
|
// src/sql-parser.ts
|
|
682
2
|
import { Parser } from "node-sql-parser";
|
|
683
|
-
var parserCache = /* @__PURE__ */ new Map();
|
|
684
|
-
function getParser(dialect) {
|
|
685
|
-
if (!parserCache.has(dialect)) {
|
|
686
|
-
parserCache.set(dialect, new Parser());
|
|
687
|
-
}
|
|
688
|
-
return parserCache.get(dialect);
|
|
689
|
-
}
|
|
690
3
|
function parseSQL(sql, options = { dialect: "mysql" }) {
|
|
691
4
|
if (!sql || typeof sql !== "string") {
|
|
692
5
|
throw new Error("SQL string is required and must be a string");
|
|
693
6
|
}
|
|
694
7
|
try {
|
|
695
|
-
const parser =
|
|
696
|
-
const processedSql = sql.trim().replace(/\s+/g, " ").replace(
|
|
8
|
+
const parser = new Parser();
|
|
9
|
+
const processedSql = sql.trim().replace(/\s+/g, " ").replace(/;[\s;]*;/g, ";");
|
|
697
10
|
const ast = parser.astify(processedSql, { database: options.dialect });
|
|
698
11
|
if (!ast) {
|
|
699
12
|
throw new Error("Failed to parse SQL: AST is null or undefined");
|
|
@@ -720,8 +33,8 @@ SQL length: ${sql.length} characters`
|
|
|
720
33
|
var SQLParser = class {
|
|
721
34
|
constructor(options = { dialect: "mysql" }) {
|
|
722
35
|
/**
|
|
723
|
-
*
|
|
724
|
-
*
|
|
36
|
+
* Default type resolver
|
|
37
|
+
* Provides basic SQL type to SQLType mapping logic
|
|
725
38
|
*/
|
|
726
39
|
this.defaultTypeResolver = {
|
|
727
40
|
resolve: (def) => {
|
|
@@ -802,7 +115,7 @@ var SQLParser = class {
|
|
|
802
115
|
if (v.value) {
|
|
803
116
|
value = v.value;
|
|
804
117
|
} else if (v.raw) {
|
|
805
|
-
value = v.raw;
|
|
118
|
+
value = String(v.raw);
|
|
806
119
|
} else {
|
|
807
120
|
value = String(v);
|
|
808
121
|
}
|
|
@@ -821,8 +134,8 @@ var SQLParser = class {
|
|
|
821
134
|
};
|
|
822
135
|
return emptyEnumType;
|
|
823
136
|
/**
|
|
824
|
-
*
|
|
825
|
-
*
|
|
137
|
+
* Unrecognized types fall back to text by default to avoid parse failure
|
|
138
|
+
* In strict mode, unrecognized types throw an error
|
|
826
139
|
*/
|
|
827
140
|
default:
|
|
828
141
|
if (this.options.strictMode) {
|
|
@@ -844,7 +157,7 @@ var SQLParser = class {
|
|
|
844
157
|
this.parser = new Parser();
|
|
845
158
|
}
|
|
846
159
|
/**
|
|
847
|
-
*
|
|
160
|
+
* Traverse AST, extract all CREATE TABLE statements
|
|
848
161
|
*/
|
|
849
162
|
parseDatabase(ast, dbName = this.options.dbName || "db") {
|
|
850
163
|
const db = {
|
|
@@ -857,22 +170,21 @@ var SQLParser = class {
|
|
|
857
170
|
db.tables.push(this.parseTable(node));
|
|
858
171
|
}
|
|
859
172
|
}
|
|
860
|
-
db.tablesMap =
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
db.tablesMap[table.name] = table;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
173
|
+
db.tablesMap = Object.fromEntries(
|
|
174
|
+
db.tables.filter((t) => t.name).map((t) => [t.name, t])
|
|
175
|
+
);
|
|
866
176
|
return db;
|
|
867
177
|
}
|
|
868
178
|
/**
|
|
869
|
-
*
|
|
179
|
+
* Type guard: check if node is a CREATE TABLE statement
|
|
870
180
|
*/
|
|
871
181
|
isCreateTable(node) {
|
|
872
|
-
|
|
182
|
+
if (!node || typeof node !== "object") return false;
|
|
183
|
+
const n = node;
|
|
184
|
+
return n.type === "create" && n.keyword === "table";
|
|
873
185
|
}
|
|
874
186
|
/**
|
|
875
|
-
*
|
|
187
|
+
* Parse single table AST -> TableSchema
|
|
876
188
|
*/
|
|
877
189
|
parseTable(node) {
|
|
878
190
|
var _a, _b, _c, _d;
|
|
@@ -916,9 +228,9 @@ var SQLParser = class {
|
|
|
916
228
|
return table;
|
|
917
229
|
}
|
|
918
230
|
/**
|
|
919
|
-
*
|
|
231
|
+
* Parse column definition AST -> ColumnSchema
|
|
920
232
|
*
|
|
921
|
-
*
|
|
233
|
+
* Note: Field-level primary/unique and table-level definitions will overlap
|
|
922
234
|
*/
|
|
923
235
|
parseColumn(def) {
|
|
924
236
|
var _a, _b, _c;
|
|
@@ -932,18 +244,18 @@ var SQLParser = class {
|
|
|
932
244
|
return {
|
|
933
245
|
name: columnName,
|
|
934
246
|
/**
|
|
935
|
-
*
|
|
247
|
+
* Abstract SQL type mapping
|
|
936
248
|
*/
|
|
937
249
|
type: this.mapSQLType(def.definition),
|
|
938
250
|
/**
|
|
939
|
-
* node-sql-parser
|
|
940
|
-
* nullable
|
|
251
|
+
* In node-sql-parser:
|
|
252
|
+
* nullable is an object; when it exists and type is "not null", it means NOT NULL
|
|
941
253
|
*/
|
|
942
254
|
nullable: !(def.nullable && def.nullable.type === "not null"),
|
|
943
255
|
primaryKey: !!def.primary_key,
|
|
944
256
|
unique: !!def.unique,
|
|
945
257
|
/**
|
|
946
|
-
*
|
|
258
|
+
* Default value needs to be serialized as SQL string
|
|
947
259
|
*/
|
|
948
260
|
default: def.default_val ? this.parseDefault(def.default_val) : void 0,
|
|
949
261
|
comment: (_c = (_b = def.comment) == null ? void 0 : _b.value) == null ? void 0 : _c.value,
|
|
@@ -952,7 +264,7 @@ var SQLParser = class {
|
|
|
952
264
|
};
|
|
953
265
|
}
|
|
954
266
|
/**
|
|
955
|
-
*
|
|
267
|
+
* Parse table-level PRIMARY KEY / UNIQUE / FOREIGN KEY
|
|
956
268
|
*/
|
|
957
269
|
parseTableConstraint(def, table) {
|
|
958
270
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1004,7 +316,7 @@ var SQLParser = class {
|
|
|
1004
316
|
}
|
|
1005
317
|
}
|
|
1006
318
|
/**
|
|
1007
|
-
*
|
|
319
|
+
* Parse regular index
|
|
1008
320
|
*/
|
|
1009
321
|
parseIndex(def, table) {
|
|
1010
322
|
var _a;
|
|
@@ -1018,7 +330,7 @@ var SQLParser = class {
|
|
|
1018
330
|
}
|
|
1019
331
|
}
|
|
1020
332
|
/**
|
|
1021
|
-
* SQL AST
|
|
333
|
+
* SQL AST type -> SQLType (cross-dialect abstraction)
|
|
1022
334
|
*/
|
|
1023
335
|
mapSQLType(def) {
|
|
1024
336
|
const allResolvers = [
|
|
@@ -1035,139 +347,672 @@ var SQLParser = class {
|
|
|
1035
347
|
return textType;
|
|
1036
348
|
}
|
|
1037
349
|
/**
|
|
1038
|
-
*
|
|
350
|
+
* Default value AST -> SQL string
|
|
1039
351
|
*
|
|
1040
|
-
*
|
|
352
|
+
* Uses sqlify to ensure functions/expressions are serialized correctly
|
|
1041
353
|
*/
|
|
1042
354
|
parseDefault(def) {
|
|
1043
|
-
var _a, _b
|
|
1044
|
-
|
|
355
|
+
var _a, _b;
|
|
356
|
+
const val = def.value;
|
|
357
|
+
if ((val == null ? void 0 : val.type) === "null" || val === null) {
|
|
1045
358
|
return null;
|
|
1046
359
|
}
|
|
1047
360
|
try {
|
|
1048
|
-
return this.parser.sqlify(
|
|
1049
|
-
} catch (
|
|
1050
|
-
if ((
|
|
1051
|
-
|
|
1052
|
-
|
|
361
|
+
return this.parser.sqlify(val);
|
|
362
|
+
} catch (e) {
|
|
363
|
+
if ((val == null ? void 0 : val.type) === "function") {
|
|
364
|
+
const name = val.name;
|
|
365
|
+
const firstName = name == null ? void 0 : name.name;
|
|
366
|
+
if ((_a = firstName == null ? void 0 : firstName[0]) == null ? void 0 : _a.value) {
|
|
367
|
+
return String(firstName[0].value);
|
|
1053
368
|
}
|
|
1054
369
|
}
|
|
1055
|
-
|
|
370
|
+
const inner = val;
|
|
371
|
+
return String((_b = inner == null ? void 0 : inner.value) != null ? _b : val);
|
|
1056
372
|
}
|
|
1057
373
|
}
|
|
1058
374
|
};
|
|
1059
375
|
|
|
1060
|
-
// src/generator/
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
376
|
+
// src/generator/base.ts
|
|
377
|
+
var BaseGenerator = class {
|
|
378
|
+
constructor() {
|
|
379
|
+
this.needsTimeCache = null;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Format type name (e.g., PascalCase)
|
|
383
|
+
*/
|
|
384
|
+
formatTypeName(name) {
|
|
385
|
+
return name.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Format field name
|
|
389
|
+
*/
|
|
390
|
+
formatPascalCase(name) {
|
|
391
|
+
return name.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
392
|
+
}
|
|
393
|
+
formatFieldName(name) {
|
|
394
|
+
return this.formatPascalCase(name);
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Generate default value
|
|
398
|
+
*/
|
|
399
|
+
generateDefaultValue(column) {
|
|
400
|
+
if (!column.default) {
|
|
401
|
+
return "";
|
|
402
|
+
}
|
|
403
|
+
return column.default;
|
|
404
|
+
}
|
|
405
|
+
needsTimeImport(database) {
|
|
406
|
+
if (this.needsTimeCache !== null) return this.needsTimeCache;
|
|
407
|
+
for (const table of database.tables) {
|
|
408
|
+
for (const column of table.columns) {
|
|
409
|
+
if (column.type.kind === "date" || column.type.kind === "datetime") {
|
|
410
|
+
this.needsTimeCache = true;
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
this.needsTimeCache = false;
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
var GeneratorFactory = class {
|
|
420
|
+
static register(language, constructor) {
|
|
421
|
+
this.registry[language] = constructor;
|
|
422
|
+
}
|
|
423
|
+
static createGenerator(language, options = { language }) {
|
|
424
|
+
const Generator = this.registry[language];
|
|
425
|
+
if (!Generator) {
|
|
426
|
+
throw new Error(`Unsupported language: ${language}`);
|
|
427
|
+
}
|
|
428
|
+
return new Generator(options);
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
GeneratorFactory.registry = {};
|
|
1066
432
|
|
|
1067
|
-
// src/
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
433
|
+
// src/generator/typescript-generator.ts
|
|
434
|
+
var TypeScriptGenerator = class extends BaseGenerator {
|
|
435
|
+
constructor(options = { language: "typescript" }) {
|
|
436
|
+
super();
|
|
437
|
+
this.options = options;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Format field name (camelCase)
|
|
441
|
+
*/
|
|
442
|
+
formatFieldName(name) {
|
|
443
|
+
return name.split("_").map((part, index) => {
|
|
444
|
+
if (index === 0) {
|
|
445
|
+
return part.toLowerCase();
|
|
446
|
+
}
|
|
447
|
+
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
448
|
+
}).join("");
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Generate type definitions for the entire database schema
|
|
452
|
+
*/
|
|
453
|
+
generateDatabase(database) {
|
|
454
|
+
let result = `// Database: ${database.name}
|
|
455
|
+
`;
|
|
456
|
+
result += `// Dialect: ${database.dialect}
|
|
1085
457
|
|
|
1086
|
-
|
|
1087
|
-
|
|
458
|
+
`;
|
|
459
|
+
for (const table of database.tables) {
|
|
460
|
+
result += this.generateTable(table);
|
|
461
|
+
result += "\n";
|
|
462
|
+
}
|
|
463
|
+
return result;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Generate type definition for a single table
|
|
467
|
+
*/
|
|
468
|
+
generateTable(table) {
|
|
469
|
+
let result = `// ${table.name} table structure
|
|
470
|
+
`;
|
|
471
|
+
result += `export interface ${this.formatTypeName(table.name)} {
|
|
472
|
+
`;
|
|
473
|
+
for (const column of table.columns) {
|
|
474
|
+
result += this.generateColumn(column);
|
|
475
|
+
}
|
|
476
|
+
result += "}\n";
|
|
477
|
+
return result;
|
|
478
|
+
}
|
|
1088
479
|
/**
|
|
1089
|
-
*
|
|
1090
|
-
* @param sql SQL 字符串
|
|
480
|
+
* Generate column type definition
|
|
1091
481
|
*/
|
|
1092
|
-
|
|
1093
|
-
|
|
482
|
+
generateColumn(column) {
|
|
483
|
+
const fieldName = this.formatFieldName(column.name);
|
|
484
|
+
const typeName = this.mapSQLType(column.type, column.name);
|
|
485
|
+
const optional = column.nullable ? "?" : "";
|
|
486
|
+
let result = ` ${fieldName}${optional}: ${typeName}`;
|
|
487
|
+
if (column.comment && this.options.generateComments !== false) {
|
|
488
|
+
result += `; // ${column.comment}`;
|
|
489
|
+
}
|
|
490
|
+
result += "\n";
|
|
491
|
+
return result;
|
|
1094
492
|
}
|
|
1095
493
|
/**
|
|
1096
|
-
*
|
|
1097
|
-
* @returns Promise<string> SQL 内容
|
|
494
|
+
* Map SQL type to TypeScript type
|
|
1098
495
|
*/
|
|
1099
|
-
|
|
1100
|
-
|
|
496
|
+
mapSQLType(type, columnName) {
|
|
497
|
+
switch (type.kind) {
|
|
498
|
+
case "int":
|
|
499
|
+
case "bigint":
|
|
500
|
+
return "number";
|
|
501
|
+
case "float":
|
|
502
|
+
case "decimal":
|
|
503
|
+
return "number";
|
|
504
|
+
case "varchar":
|
|
505
|
+
case "text":
|
|
506
|
+
return "string";
|
|
507
|
+
case "boolean":
|
|
508
|
+
return "boolean";
|
|
509
|
+
case "date":
|
|
510
|
+
case "datetime":
|
|
511
|
+
return "Date";
|
|
512
|
+
case "json":
|
|
513
|
+
return "unknown";
|
|
514
|
+
case "enum":
|
|
515
|
+
if (type.values && type.values.length > 0) {
|
|
516
|
+
const enumValues = type.values.map((v) => `'${v}'`).join(" | ");
|
|
517
|
+
if (columnName) {
|
|
518
|
+
const fieldName = this.formatFieldName(columnName);
|
|
519
|
+
return `${fieldName}: ${enumValues}`;
|
|
520
|
+
}
|
|
521
|
+
return enumValues;
|
|
522
|
+
}
|
|
523
|
+
return "string";
|
|
524
|
+
default:
|
|
525
|
+
return "string";
|
|
526
|
+
}
|
|
1101
527
|
}
|
|
1102
528
|
};
|
|
1103
529
|
|
|
1104
|
-
// src/
|
|
1105
|
-
|
|
1106
|
-
|
|
530
|
+
// src/generator/go-generator.ts
|
|
531
|
+
var GoGenerator = class extends BaseGenerator {
|
|
532
|
+
constructor(options = { language: "go" }) {
|
|
533
|
+
super();
|
|
534
|
+
this.options = options;
|
|
535
|
+
}
|
|
1107
536
|
/**
|
|
1108
|
-
*
|
|
1109
|
-
* @param filePath SQL 文件路径
|
|
537
|
+
* Generate type definitions for the entire database schema
|
|
1110
538
|
*/
|
|
1111
|
-
|
|
1112
|
-
|
|
539
|
+
generateDatabase(database) {
|
|
540
|
+
let result = `// Database: ${database.name}
|
|
541
|
+
`;
|
|
542
|
+
result += `// Dialect: ${database.dialect}
|
|
543
|
+
|
|
544
|
+
`;
|
|
545
|
+
if (this.options.namespace) {
|
|
546
|
+
result += `package ${this.options.namespace}
|
|
547
|
+
|
|
548
|
+
`;
|
|
549
|
+
}
|
|
550
|
+
if (this.needsTimeImport(database)) {
|
|
551
|
+
result += `import "time"
|
|
552
|
+
|
|
553
|
+
`;
|
|
554
|
+
}
|
|
555
|
+
for (const table of database.tables) {
|
|
556
|
+
result += this.generateTable(table);
|
|
557
|
+
result += "\n";
|
|
558
|
+
}
|
|
559
|
+
return result;
|
|
1113
560
|
}
|
|
1114
561
|
/**
|
|
1115
|
-
*
|
|
1116
|
-
* @returns Promise<string> SQL 内容
|
|
1117
|
-
* @throws Error 文件不存在或读取失败
|
|
562
|
+
* Generate type definition for a single table
|
|
1118
563
|
*/
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
564
|
+
generateTable(table) {
|
|
565
|
+
let result = `// ${table.name} table structure
|
|
566
|
+
`;
|
|
567
|
+
result += `type ${this.formatTypeName(table.name)} struct {
|
|
568
|
+
`;
|
|
569
|
+
for (const column of table.columns) {
|
|
570
|
+
result += this.generateColumn(column);
|
|
571
|
+
}
|
|
572
|
+
result += "}\n";
|
|
573
|
+
return result;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Generate column type definition
|
|
577
|
+
*/
|
|
578
|
+
generateColumn(column) {
|
|
579
|
+
const fieldName = this.formatFieldName(column.name);
|
|
580
|
+
const typeName = this.mapSQLType(column.type);
|
|
581
|
+
const tag = this.generateGoTag(column);
|
|
582
|
+
let result = ` ${fieldName} ${typeName} ${tag}`;
|
|
583
|
+
if (column.comment && this.options.generateComments !== false) {
|
|
584
|
+
result += ` // ${column.comment}`;
|
|
585
|
+
}
|
|
586
|
+
result += "\n";
|
|
587
|
+
return result;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Map SQL type to Go type
|
|
591
|
+
*/
|
|
592
|
+
mapSQLType(type) {
|
|
593
|
+
switch (type.kind) {
|
|
594
|
+
case "int":
|
|
595
|
+
return "int";
|
|
596
|
+
case "bigint":
|
|
597
|
+
return "int64";
|
|
598
|
+
case "float":
|
|
599
|
+
return "float64";
|
|
600
|
+
case "decimal":
|
|
601
|
+
return "float64";
|
|
602
|
+
case "varchar":
|
|
603
|
+
case "text":
|
|
604
|
+
return "string";
|
|
605
|
+
case "boolean":
|
|
606
|
+
return "bool";
|
|
607
|
+
case "date":
|
|
608
|
+
case "datetime":
|
|
609
|
+
return "time.Time";
|
|
610
|
+
case "json":
|
|
611
|
+
return "interface{}";
|
|
612
|
+
case "enum":
|
|
613
|
+
return "string";
|
|
614
|
+
default:
|
|
615
|
+
return "string";
|
|
1133
616
|
}
|
|
1134
617
|
}
|
|
618
|
+
/**
|
|
619
|
+
* Generate Go struct tags
|
|
620
|
+
*/
|
|
621
|
+
generateGoTag(column) {
|
|
622
|
+
const tags = [];
|
|
623
|
+
tags.push(`json:"${column.name}"`);
|
|
624
|
+
tags.push(`db:"${column.name}"`);
|
|
625
|
+
return `\`${tags.join(" ")}\``;
|
|
626
|
+
}
|
|
1135
627
|
};
|
|
1136
628
|
|
|
1137
|
-
// src/
|
|
1138
|
-
var
|
|
629
|
+
// src/generator/gorm-generator.ts
|
|
630
|
+
var GormGenerator = class extends BaseGenerator {
|
|
631
|
+
constructor(options = { language: "gorm" }) {
|
|
632
|
+
super();
|
|
633
|
+
this.options = options;
|
|
634
|
+
}
|
|
1139
635
|
/**
|
|
1140
|
-
*
|
|
1141
|
-
* @param options 读取器选项
|
|
1142
|
-
* @returns Reader 实例
|
|
1143
|
-
* @throws Error 不支持的读取器类型
|
|
636
|
+
* Generate type definitions for the entire database schema
|
|
1144
637
|
*/
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
638
|
+
generateDatabase(database) {
|
|
639
|
+
let result = `// Database: ${database.name}
|
|
640
|
+
`;
|
|
641
|
+
result += `// Dialect: ${database.dialect}
|
|
642
|
+
|
|
643
|
+
`;
|
|
644
|
+
if (this.options.namespace) {
|
|
645
|
+
result += `package ${this.options.namespace}
|
|
646
|
+
|
|
647
|
+
`;
|
|
648
|
+
}
|
|
649
|
+
if (this.needsTimeImport(database)) {
|
|
650
|
+
result += `import "time"
|
|
651
|
+
|
|
652
|
+
`;
|
|
653
|
+
}
|
|
654
|
+
for (const table of database.tables) {
|
|
655
|
+
result += this.generateTable(table);
|
|
656
|
+
result += "\n";
|
|
657
|
+
}
|
|
658
|
+
return result;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Generate type definition for a single table
|
|
662
|
+
*/
|
|
663
|
+
generateTable(table) {
|
|
664
|
+
let result = `// ${table.name} table structure
|
|
665
|
+
`;
|
|
666
|
+
result += `type ${this.formatTypeName(table.name)} struct {
|
|
667
|
+
`;
|
|
668
|
+
for (const column of table.columns) {
|
|
669
|
+
result += this.generateColumn(column);
|
|
670
|
+
}
|
|
671
|
+
result += "}\n";
|
|
672
|
+
return result;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Generate column type definition
|
|
676
|
+
*/
|
|
677
|
+
generateColumn(column) {
|
|
678
|
+
const fieldName = this.formatFieldName(column.name);
|
|
679
|
+
const typeName = this.mapSQLType(column.type);
|
|
680
|
+
const tag = this.generateGormTag(column);
|
|
681
|
+
let result = ` ${fieldName} ${typeName} ${tag}`;
|
|
682
|
+
if (column.comment && this.options.generateComments !== false) {
|
|
683
|
+
result += ` // ${column.comment}`;
|
|
684
|
+
}
|
|
685
|
+
result += "\n";
|
|
686
|
+
return result;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Map SQL type to GORM type
|
|
690
|
+
*/
|
|
691
|
+
mapSQLType(type) {
|
|
692
|
+
switch (type.kind) {
|
|
693
|
+
case "int":
|
|
694
|
+
return "int";
|
|
695
|
+
case "bigint":
|
|
696
|
+
return "int64";
|
|
697
|
+
case "float":
|
|
698
|
+
return "float64";
|
|
699
|
+
case "decimal":
|
|
700
|
+
return "float64";
|
|
701
|
+
case "varchar":
|
|
702
|
+
case "text":
|
|
703
|
+
return "string";
|
|
704
|
+
case "boolean":
|
|
705
|
+
return "bool";
|
|
706
|
+
case "date":
|
|
707
|
+
case "datetime":
|
|
708
|
+
return "time.Time";
|
|
709
|
+
case "json":
|
|
710
|
+
return "interface{}";
|
|
711
|
+
case "enum":
|
|
712
|
+
return "string";
|
|
713
|
+
default:
|
|
714
|
+
return "string";
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Generate GORM struct tags
|
|
719
|
+
*/
|
|
720
|
+
generateGormTag(column) {
|
|
721
|
+
const tags = [];
|
|
722
|
+
tags.push(`column:${column.name}`);
|
|
723
|
+
let typeTag = "type:";
|
|
724
|
+
switch (column.type.kind) {
|
|
725
|
+
case "int":
|
|
726
|
+
typeTag += "int";
|
|
727
|
+
if (column.type.length) {
|
|
728
|
+
typeTag += `(${column.type.length})`;
|
|
729
|
+
}
|
|
730
|
+
break;
|
|
731
|
+
case "bigint":
|
|
732
|
+
typeTag += "bigint";
|
|
733
|
+
if (column.type.length) {
|
|
734
|
+
typeTag += `(${column.type.length})`;
|
|
735
|
+
}
|
|
736
|
+
break;
|
|
737
|
+
case "float":
|
|
738
|
+
typeTag += "float";
|
|
739
|
+
if (column.type.precision) {
|
|
740
|
+
typeTag += `(${column.type.precision}`;
|
|
741
|
+
if (column.type.scale) {
|
|
742
|
+
typeTag += `,${column.type.scale}`;
|
|
743
|
+
}
|
|
744
|
+
typeTag += ")";
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
case "decimal":
|
|
748
|
+
typeTag += "decimal";
|
|
749
|
+
if (column.type.precision) {
|
|
750
|
+
typeTag += `(${column.type.precision}`;
|
|
751
|
+
if (column.type.scale) {
|
|
752
|
+
typeTag += `,${column.type.scale}`;
|
|
753
|
+
}
|
|
754
|
+
typeTag += ")";
|
|
755
|
+
}
|
|
756
|
+
break;
|
|
757
|
+
case "varchar":
|
|
758
|
+
typeTag += "varchar";
|
|
759
|
+
if (column.type.length) {
|
|
760
|
+
typeTag += `(${column.type.length})`;
|
|
761
|
+
}
|
|
762
|
+
break;
|
|
763
|
+
case "text":
|
|
764
|
+
typeTag += "text";
|
|
765
|
+
break;
|
|
766
|
+
case "boolean":
|
|
767
|
+
typeTag += "bool";
|
|
768
|
+
break;
|
|
769
|
+
case "date":
|
|
770
|
+
typeTag += "date";
|
|
771
|
+
break;
|
|
772
|
+
case "datetime":
|
|
773
|
+
typeTag += "datetime";
|
|
774
|
+
break;
|
|
775
|
+
case "json":
|
|
776
|
+
typeTag += "json";
|
|
777
|
+
break;
|
|
778
|
+
case "enum":
|
|
779
|
+
typeTag += "enum";
|
|
780
|
+
break;
|
|
781
|
+
default:
|
|
782
|
+
typeTag += "string";
|
|
783
|
+
}
|
|
784
|
+
tags.push(typeTag);
|
|
785
|
+
if (column.primaryKey) {
|
|
786
|
+
tags.push("primaryKey");
|
|
787
|
+
}
|
|
788
|
+
if (column.unique) {
|
|
789
|
+
tags.push("unique");
|
|
790
|
+
}
|
|
791
|
+
if (!column.nullable) {
|
|
792
|
+
tags.push("not null");
|
|
793
|
+
}
|
|
794
|
+
if (column.default) {
|
|
795
|
+
tags.push(`default:${column.default}`);
|
|
796
|
+
}
|
|
797
|
+
if (column.generated) {
|
|
798
|
+
tags.push("autoIncrement");
|
|
799
|
+
}
|
|
800
|
+
if (column.comment) {
|
|
801
|
+
tags.push(`comment:${column.comment}`);
|
|
802
|
+
}
|
|
803
|
+
return `\`gorm:"${tags.join(";")}" json:"${column.name}"\``;
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
// src/generator/xorm-generator.ts
|
|
808
|
+
var XormGenerator = class extends BaseGenerator {
|
|
809
|
+
constructor(options = { language: "xorm" }) {
|
|
810
|
+
super();
|
|
811
|
+
this.options = options;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Generate type definitions for the entire database schema
|
|
815
|
+
*/
|
|
816
|
+
generateDatabase(database) {
|
|
817
|
+
let result = `// Database: ${database.name}
|
|
818
|
+
`;
|
|
819
|
+
result += `// Dialect: ${database.dialect}
|
|
820
|
+
|
|
821
|
+
`;
|
|
822
|
+
if (this.options.namespace) {
|
|
823
|
+
result += `package ${this.options.namespace}
|
|
824
|
+
|
|
825
|
+
`;
|
|
826
|
+
}
|
|
827
|
+
if (this.needsTimeImport(database)) {
|
|
828
|
+
result += `import "time"
|
|
829
|
+
|
|
830
|
+
`;
|
|
831
|
+
}
|
|
832
|
+
for (const table of database.tables) {
|
|
833
|
+
result += this.generateTable(table);
|
|
834
|
+
result += "\n";
|
|
835
|
+
}
|
|
836
|
+
return result;
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Generate type definition for a single table
|
|
840
|
+
*/
|
|
841
|
+
generateTable(table) {
|
|
842
|
+
let result = `// ${table.name} table structure
|
|
843
|
+
`;
|
|
844
|
+
result += `type ${this.formatTypeName(table.name)} struct {
|
|
845
|
+
`;
|
|
846
|
+
for (const column of table.columns) {
|
|
847
|
+
result += this.generateColumn(column);
|
|
848
|
+
}
|
|
849
|
+
result += "}\n";
|
|
850
|
+
return result;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Generate column type definition
|
|
854
|
+
*/
|
|
855
|
+
generateColumn(column) {
|
|
856
|
+
const fieldName = this.formatFieldName(column.name);
|
|
857
|
+
const typeName = this.mapSQLType(column.type);
|
|
858
|
+
const tag = this.generateXormTag(column);
|
|
859
|
+
let result = ` ${fieldName} ${typeName} ${tag}`;
|
|
860
|
+
if (column.comment && this.options.generateComments !== false) {
|
|
861
|
+
result += ` // ${column.comment}`;
|
|
862
|
+
}
|
|
863
|
+
result += "\n";
|
|
864
|
+
return result;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Map SQL type to XORM type
|
|
868
|
+
*/
|
|
869
|
+
mapSQLType(type) {
|
|
870
|
+
switch (type.kind) {
|
|
871
|
+
case "int":
|
|
872
|
+
return "int";
|
|
873
|
+
case "bigint":
|
|
874
|
+
return "int64";
|
|
875
|
+
case "float":
|
|
876
|
+
return "float64";
|
|
877
|
+
case "decimal":
|
|
878
|
+
return "float64";
|
|
879
|
+
case "varchar":
|
|
880
|
+
case "text":
|
|
881
|
+
return "string";
|
|
882
|
+
case "boolean":
|
|
883
|
+
return "bool";
|
|
884
|
+
case "date":
|
|
885
|
+
case "datetime":
|
|
886
|
+
return "time.Time";
|
|
887
|
+
case "json":
|
|
888
|
+
return "interface{}";
|
|
889
|
+
case "enum":
|
|
890
|
+
return "string";
|
|
891
|
+
default:
|
|
892
|
+
return "string";
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Generate XORM struct tags
|
|
897
|
+
*/
|
|
898
|
+
generateXormTag(column) {
|
|
899
|
+
const tags = [];
|
|
900
|
+
tags.push(`${column.name}`);
|
|
901
|
+
let typeTag = "";
|
|
902
|
+
switch (column.type.kind) {
|
|
903
|
+
case "int":
|
|
904
|
+
typeTag = "int";
|
|
905
|
+
if (column.type.length) {
|
|
906
|
+
typeTag += `(${column.type.length})`;
|
|
907
|
+
}
|
|
908
|
+
break;
|
|
909
|
+
case "bigint":
|
|
910
|
+
typeTag = "bigint";
|
|
911
|
+
if (column.type.length) {
|
|
912
|
+
typeTag += `(${column.type.length})`;
|
|
913
|
+
}
|
|
914
|
+
break;
|
|
915
|
+
case "float":
|
|
916
|
+
typeTag = "float";
|
|
917
|
+
if (column.type.precision) {
|
|
918
|
+
typeTag += `(${column.type.precision}`;
|
|
919
|
+
if (column.type.scale) {
|
|
920
|
+
typeTag += `,${column.type.scale}`;
|
|
921
|
+
}
|
|
922
|
+
typeTag += ")";
|
|
923
|
+
}
|
|
924
|
+
break;
|
|
925
|
+
case "decimal":
|
|
926
|
+
typeTag = "decimal";
|
|
927
|
+
if (column.type.precision) {
|
|
928
|
+
typeTag += `(${column.type.precision}`;
|
|
929
|
+
if (column.type.scale) {
|
|
930
|
+
typeTag += `,${column.type.scale}`;
|
|
931
|
+
}
|
|
932
|
+
typeTag += ")";
|
|
933
|
+
}
|
|
934
|
+
break;
|
|
935
|
+
case "varchar":
|
|
936
|
+
typeTag = "varchar";
|
|
937
|
+
if (column.type.length) {
|
|
938
|
+
typeTag += `(${column.type.length})`;
|
|
939
|
+
}
|
|
940
|
+
break;
|
|
941
|
+
case "text":
|
|
942
|
+
typeTag = "text";
|
|
943
|
+
break;
|
|
944
|
+
case "boolean":
|
|
945
|
+
typeTag = "bool";
|
|
946
|
+
break;
|
|
947
|
+
case "date":
|
|
948
|
+
typeTag = "date";
|
|
949
|
+
break;
|
|
950
|
+
case "datetime":
|
|
951
|
+
typeTag = "datetime";
|
|
952
|
+
break;
|
|
953
|
+
case "json":
|
|
954
|
+
typeTag = "json";
|
|
955
|
+
break;
|
|
956
|
+
case "enum":
|
|
957
|
+
typeTag = "enum";
|
|
958
|
+
break;
|
|
1157
959
|
default:
|
|
1158
|
-
|
|
960
|
+
typeTag = "string";
|
|
961
|
+
}
|
|
962
|
+
if (typeTag) {
|
|
963
|
+
tags.push(typeTag);
|
|
964
|
+
}
|
|
965
|
+
if (column.primaryKey) {
|
|
966
|
+
tags.push("pk");
|
|
1159
967
|
}
|
|
968
|
+
if (column.unique) {
|
|
969
|
+
tags.push("unique");
|
|
970
|
+
}
|
|
971
|
+
if (!column.nullable) {
|
|
972
|
+
tags.push("notnull");
|
|
973
|
+
}
|
|
974
|
+
if (column.default) {
|
|
975
|
+
tags.push(`default(${column.default})`);
|
|
976
|
+
}
|
|
977
|
+
if (column.generated) {
|
|
978
|
+
tags.push("autoincr");
|
|
979
|
+
}
|
|
980
|
+
if (column.comment) {
|
|
981
|
+
tags.push(`comment(${column.comment})`);
|
|
982
|
+
}
|
|
983
|
+
return `\`xorm:"${tags.join(" ")}" json:"${column.name}"\``;
|
|
1160
984
|
}
|
|
1161
985
|
};
|
|
986
|
+
|
|
987
|
+
// src/generator/index.ts
|
|
988
|
+
GeneratorFactory.register("typescript", TypeScriptGenerator);
|
|
989
|
+
GeneratorFactory.register("go", GoGenerator);
|
|
990
|
+
GeneratorFactory.register("gorm", GormGenerator);
|
|
991
|
+
GeneratorFactory.register("xorm", XormGenerator);
|
|
992
|
+
|
|
993
|
+
// src/generate.ts
|
|
994
|
+
function generateCode(sql, options) {
|
|
995
|
+
const dbSchema = parseSQL(sql, {
|
|
996
|
+
dialect: options.dialect || "mysql",
|
|
997
|
+
dbName: options.dbName || "my_database"
|
|
998
|
+
});
|
|
999
|
+
const generatorOptions = {
|
|
1000
|
+
language: options.language,
|
|
1001
|
+
namespace: options.namespace,
|
|
1002
|
+
generateComments: true
|
|
1003
|
+
};
|
|
1004
|
+
const generator = GeneratorFactory.createGenerator(
|
|
1005
|
+
options.language,
|
|
1006
|
+
generatorOptions
|
|
1007
|
+
);
|
|
1008
|
+
return generator.generateDatabase(dbSchema);
|
|
1009
|
+
}
|
|
1162
1010
|
export {
|
|
1163
|
-
|
|
1164
|
-
FileReader,
|
|
1011
|
+
BaseGenerator,
|
|
1165
1012
|
GeneratorFactory,
|
|
1166
|
-
|
|
1013
|
+
GoGenerator,
|
|
1167
1014
|
GormGenerator,
|
|
1168
|
-
ReaderFactory,
|
|
1169
1015
|
SQLParser,
|
|
1170
|
-
StringReader,
|
|
1171
1016
|
TypeScriptGenerator,
|
|
1172
1017
|
XormGenerator,
|
|
1173
1018
|
generateCode,
|