@technicity/data-service-generator 0.12.4 → 0.13.26
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 +9 -4
- package/dist/generation/generate.d.ts +1 -0
- package/dist/generation/generate.js +403 -68
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1 -5
- package/dist/ksql.js +24 -1
- package/dist/runtime/Cache.js +6 -3
- package/dist/runtime/IRuntime.d.ts +4 -2
- package/dist/runtime/RuntimeKSQL.js +25 -2
- package/dist/runtime/RuntimeMySQL.js +29 -3
- package/dist/runtime/RuntimeSQLite.d.ts +38 -0
- package/dist/runtime/RuntimeSQLite.js +135 -0
- package/dist/runtime/lib/MSSQL.js +25 -2
- package/dist/runtime/lib/addNullFallbacks.test.d.ts +1 -0
- package/dist/runtime/lib/addNullFallbacks.test.js +206 -0
- package/dist/runtime/lib/getSqlAst.js +46 -21
- package/dist/runtime/lib/runTransforms.test.d.ts +1 -0
- package/dist/runtime/lib/runTransforms.test.js +112 -0
- package/dist/runtime/lib/shared.js +127 -47
- package/dist/runtime/lib/stringifyWhere.js +38 -11
- package/dist/runtime/lib/stringifyWhere.test.d.ts +1 -0
- package/dist/runtime/lib/stringifyWhere.test.js +236 -0
- package/dist/runtime/lib/typeCastMSSQL.js +24 -1
- package/dist/traverseFieldArgs.test.d.ts +1 -0
- package/dist/traverseFieldArgs.test.js +72 -0
- package/package.json +13 -12
- package/dist/getFakeData.d.ts +0 -12
- package/dist/getFakeData.js +0 -90
- package/dist/getIsList.d.ts +0 -1
- package/dist/getIsList.js +0 -7
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ async function main() {
|
|
|
22
22
|
dialect: "mysql",
|
|
23
23
|
database: "MY_DATABASE",
|
|
24
24
|
user: "MY_USER",
|
|
25
|
-
password: "MY_PASSWORD"
|
|
25
|
+
password: "MY_PASSWORD"
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
```
|
|
@@ -47,7 +47,12 @@ async function main() {
|
|
|
47
47
|
|
|
48
48
|
### Running Tests
|
|
49
49
|
|
|
50
|
-
-
|
|
51
|
-
- run tests: `docker-compose exec test yarn test`
|
|
50
|
+
- `yarn test`
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
#### Unit Tests
|
|
53
|
+
|
|
54
|
+
Comment out `globalSetup` in `jest.config.js`, then:
|
|
55
|
+
|
|
56
|
+
- `yarn test:unit`
|
|
57
|
+
|
|
58
|
+
See comment in `./test/globalSetup.ts` for why this is necessary.
|
|
@@ -15,6 +15,7 @@ declare type IGenerateInput = {
|
|
|
15
15
|
specialCaseUuidColumn?: ISpecialCaseUuidColumn;
|
|
16
16
|
includeMappedFields?: IIncludeMappedFields;
|
|
17
17
|
supplementClientOpts?: ISupplementClientOpts;
|
|
18
|
+
outputSqliteSchema?: boolean;
|
|
18
19
|
};
|
|
19
20
|
export declare function generate(input: IGenerateInput): Promise<void>;
|
|
20
21
|
export {};
|
|
@@ -1,22 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
2
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
29
|
exports.generate = void 0;
|
|
4
|
-
const path = require("path");
|
|
5
|
-
const fs = require("fs");
|
|
6
|
-
const os = require("os");
|
|
7
|
-
const child_process = require("child_process");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const mssql = require("mssql");
|
|
30
|
+
const path = __importStar(require("node:path"));
|
|
31
|
+
const fs = __importStar(require("node:fs"));
|
|
32
|
+
const os = __importStar(require("node:os"));
|
|
33
|
+
const child_process = __importStar(require("node:child_process"));
|
|
34
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
35
|
+
const prettier = __importStar(require("prettier"));
|
|
36
|
+
const changeCase = __importStar(require("change-case"));
|
|
37
|
+
const fse = __importStar(require("fs-extra"));
|
|
38
|
+
const _ = __importStar(require("lodash/fp"));
|
|
39
|
+
const mssql = __importStar(require("mssql"));
|
|
14
40
|
// @ts-ignore
|
|
15
|
-
const TSqlString = require("tsqlstring");
|
|
41
|
+
const TSqlString = __importStar(require("tsqlstring"));
|
|
16
42
|
const json_schema_to_typescript_1 = require("json-schema-to-typescript");
|
|
17
43
|
const getDuplicates_1 = require("../lib/getDuplicates");
|
|
18
44
|
const isNotNullOrUndefined_1 = require("../lib/isNotNullOrUndefined");
|
|
19
45
|
const MySQL_1 = require("../runtime/lib/MySQL");
|
|
46
|
+
const node_util_1 = require("node:util");
|
|
47
|
+
const spawn = (0, node_util_1.promisify)(child_process.spawn);
|
|
20
48
|
// json-schema-to-typescript inlines everything. We don't want that,
|
|
21
49
|
// so use `tsType`, and add imports manually.
|
|
22
50
|
// https://github.com/bcherny/json-schema-to-typescript#custom-schema-properties
|
|
@@ -59,11 +87,15 @@ async function generate(input) {
|
|
|
59
87
|
getDeleteOneData(x),
|
|
60
88
|
getDeleteListData(x)
|
|
61
89
|
]));
|
|
62
|
-
const
|
|
90
|
+
const artifacts = await getArtifacts(tables, includeMappedFields, specialCaseUuidColumn);
|
|
91
|
+
const artifactsSource = getArtifactsSource(artifacts);
|
|
63
92
|
const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts);
|
|
64
93
|
const sdkFilename = "index.ts";
|
|
94
|
+
const sourceIRuntimeFilePath = fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.ts"))
|
|
95
|
+
? path.join(__dirname, "../runtime", "IRuntime.ts")
|
|
96
|
+
: path.join(__dirname, "../runtime", "IRuntime.js");
|
|
97
|
+
const IRuntimeFilename = path.basename(sourceIRuntimeFilePath);
|
|
65
98
|
const artifactsFilename = "artifacts.ts";
|
|
66
|
-
const IRuntimeFilename = "IRuntime.d.ts";
|
|
67
99
|
const tsConfigJSON = {
|
|
68
100
|
compilerOptions: {
|
|
69
101
|
module: "commonjs",
|
|
@@ -84,11 +116,12 @@ async function generate(input) {
|
|
|
84
116
|
typescript: require("../../package.json").devDependencies.typescript
|
|
85
117
|
}
|
|
86
118
|
};
|
|
87
|
-
const tmpDirPath = path.join(os.tmpdir(),
|
|
119
|
+
const tmpDirPath = path.join(os.tmpdir(),
|
|
120
|
+
// _ because - in filename is not supported by mysql2sqlite
|
|
121
|
+
`dsg_${node_crypto_1.default.randomUUID()}`.replace(/-/g, "_"));
|
|
88
122
|
fse.mkdirpSync(tmpDirPath);
|
|
89
123
|
fs.writeFileSync(path.join(tmpDirPath, sdkFilename), sdkSource);
|
|
90
124
|
fs.writeFileSync(path.join(tmpDirPath, artifactsFilename), artifactsSource);
|
|
91
|
-
const sourceIRuntimeFilePath = path.join(__dirname, "../runtime", IRuntimeFilename);
|
|
92
125
|
fse.copyFileSync(sourceIRuntimeFilePath, path.join(tmpDirPath, IRuntimeFilename));
|
|
93
126
|
const typesDirPath = path.join(tmpDirPath, "types");
|
|
94
127
|
fse.mkdirpSync(typesDirPath);
|
|
@@ -128,7 +161,40 @@ async function generate(input) {
|
|
|
128
161
|
.join("\n"));
|
|
129
162
|
// TODO: workaround for IRuntime.d.ts not being included
|
|
130
163
|
// copyFileSync hangs for some reason, so use writeFileSync + readFileSync instead
|
|
131
|
-
fs.writeFileSync(path.join(tmpBuildOutputPath,
|
|
164
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, "IRuntime.d.ts"), fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"))
|
|
165
|
+
? fs.readFileSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"))
|
|
166
|
+
: fs.readFileSync(sourceIRuntimeFilePath));
|
|
167
|
+
if (dialect === "mysql" && input.outputSqliteSchema) {
|
|
168
|
+
// Since mysql2sqlite outputs a malformed string if a column
|
|
169
|
+
// has the name `enum`, temporarily change the name to something else,
|
|
170
|
+
// then change it back.
|
|
171
|
+
const enumMarker = "`" + node_crypto_1.default.randomUUID() + "`";
|
|
172
|
+
const schemaMySql = Object.values(artifacts)
|
|
173
|
+
.reduce((acc, x) => {
|
|
174
|
+
let d = x.dump?.schema;
|
|
175
|
+
if (!d) {
|
|
176
|
+
return acc;
|
|
177
|
+
}
|
|
178
|
+
d = d.replace(/`enum`/g, enumMarker);
|
|
179
|
+
d += ";";
|
|
180
|
+
acc.push(d);
|
|
181
|
+
return acc;
|
|
182
|
+
}, [])
|
|
183
|
+
.join("\n\n");
|
|
184
|
+
const mysql2SqliteSrc = getMysql2sqliteSrc();
|
|
185
|
+
const mysql2SqlitePath = path.join(tmpDirPath, "mysql2sqlite");
|
|
186
|
+
fs.writeFileSync(mysql2SqlitePath, mysql2SqliteSrc);
|
|
187
|
+
fs.chmodSync(mysql2SqlitePath, 0o755);
|
|
188
|
+
const tmpMySqlSchemaFilename = "tmp.sql";
|
|
189
|
+
const tmpMySqlSchemaPath = path.join(tmpDirPath, tmpMySqlSchemaFilename);
|
|
190
|
+
fs.writeFileSync(tmpMySqlSchemaPath, schemaMySql);
|
|
191
|
+
let schemaSqlite = child_process
|
|
192
|
+
.execFileSync(mysql2SqlitePath, [tmpMySqlSchemaFilename], { cwd: tmpDirPath })
|
|
193
|
+
.toString();
|
|
194
|
+
schemaSqlite = schemaSqlite.replace(new RegExp(enumMarker, "g"), "`enum`");
|
|
195
|
+
const src = prettier.format(`module.exports = { schema: \`${schemaSqlite.replace(/`/g, "\\`")}\` }`, { parser: "babel" });
|
|
196
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, "artifacts.sqlite.js"), src);
|
|
197
|
+
}
|
|
132
198
|
if (!fs.existsSync(outdir)) {
|
|
133
199
|
fse.mkdirpSync(outdir);
|
|
134
200
|
}
|
|
@@ -191,21 +257,6 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
|
|
|
191
257
|
.concat(Array.from(set).sort())
|
|
192
258
|
.join(",\n")} } from "./types";`;
|
|
193
259
|
}
|
|
194
|
-
function getTypeNullResponses() {
|
|
195
|
-
return `type TNullResponses = { ${Object.entries(_.groupBy((x) => x.table, input))
|
|
196
|
-
.flatMap(([table, xx]) => {
|
|
197
|
-
const name = table;
|
|
198
|
-
return (`${name}?: {` +
|
|
199
|
-
xx
|
|
200
|
-
.map(({ kind }) => {
|
|
201
|
-
const operation = mapKindToAction(kind);
|
|
202
|
-
return `${operation}?: (input: { args: { select: ${getTypeFieldsName(table)} | undefined, where: ${getTypeWhereName(table)} | undefined }, model: "${table}", operation: "${operation}" }) => Promise<${getTypeReturnBaseName(table)}>`;
|
|
203
|
-
})
|
|
204
|
-
.join(",") +
|
|
205
|
-
" } ");
|
|
206
|
-
})
|
|
207
|
-
.join(",")} }`;
|
|
208
|
-
}
|
|
209
260
|
const src = `import type { IRuntime, TMiddleware, TContext } from "./IRuntime"
|
|
210
261
|
import { artifacts } from "./artifacts";
|
|
211
262
|
|
|
@@ -213,33 +264,19 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
|
|
|
213
264
|
|
|
214
265
|
export class SDK {
|
|
215
266
|
runtime: IRuntime;
|
|
216
|
-
_nullability: TNullResponses | undefined;
|
|
217
267
|
|
|
218
|
-
static create(opts: {
|
|
219
|
-
runtime: any;
|
|
220
|
-
clientOpts: { [k: string]: any; },
|
|
221
|
-
otherOpts?: { [k: string]: any; }
|
|
222
|
-
}) {
|
|
223
|
-
return new this(opts);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
static createNull(opts: {
|
|
227
|
-
runtime: any;
|
|
228
|
-
query?: TNullResponses
|
|
229
|
-
}) {
|
|
230
|
-
return new this({ runtime: opts.runtime, clientOpts: {}, otherOpts: { nullability: opts.query } });
|
|
231
|
-
}
|
|
232
|
-
|
|
233
268
|
constructor(opts: {
|
|
234
269
|
runtime: any;
|
|
235
270
|
clientOpts: { [k: string]: any; },
|
|
236
271
|
otherOpts?: { [k: string]: any; }
|
|
237
272
|
}) {
|
|
238
|
-
|
|
273
|
+
let otherOpts = opts.otherOpts ?? {};
|
|
274
|
+
if (opts.clientOpts.filename === ":memory:") {
|
|
275
|
+
otherOpts = { ...otherOpts, createTablesString: require("./artifacts.sqlite").schema }
|
|
276
|
+
}
|
|
239
277
|
this.runtime = new opts.runtime(opts.clientOpts, ${supplementClientOpts === true
|
|
240
278
|
? "{ supplementClientOpts: true, ...otherOpts }"
|
|
241
279
|
: "otherOpts"}, artifacts);
|
|
242
|
-
this._nullability = nullability;
|
|
243
280
|
}
|
|
244
281
|
|
|
245
282
|
$use(middleware: TMiddleware) {
|
|
@@ -340,7 +377,6 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
|
|
|
340
377
|
}))).join("\n\n")}
|
|
341
378
|
}
|
|
342
379
|
|
|
343
|
-
${getTypeNullResponses()}
|
|
344
380
|
`;
|
|
345
381
|
return prettier.format(src, { parser: "typescript" });
|
|
346
382
|
}
|
|
@@ -373,7 +409,6 @@ function getMethodSourceGetOne(x, findOnes, isTransaction) {
|
|
|
373
409
|
artifacts,
|
|
374
410
|
context: param2?.context,
|
|
375
411
|
skipCache: param2?.skipCache,
|
|
376
|
-
nullability: this._nullability,
|
|
377
412
|
${isTransaction ? "dbCall" : ""}
|
|
378
413
|
}
|
|
379
414
|
);
|
|
@@ -393,7 +428,6 @@ function getMethodSourceGetList(x, isTransaction) {
|
|
|
393
428
|
artifacts,
|
|
394
429
|
context: param2?.context,
|
|
395
430
|
skipCache: param2?.skipCache,
|
|
396
|
-
nullability: this._nullability,
|
|
397
431
|
${isTransaction ? "dbCall" : ""}
|
|
398
432
|
}
|
|
399
433
|
);
|
|
@@ -413,7 +447,6 @@ function getMethodSourceGetListPaginated(x, isTransaction) {
|
|
|
413
447
|
artifacts,
|
|
414
448
|
context: param2?.context,
|
|
415
449
|
skipCache: param2?.skipCache,
|
|
416
|
-
nullability: this._nullability,
|
|
417
450
|
${isTransaction ? "dbCall" : ""}
|
|
418
451
|
}
|
|
419
452
|
);
|
|
@@ -431,7 +464,6 @@ function getMethodSourcePostOne(x, specialCaseUuidColumn, isTransaction) {
|
|
|
431
464
|
artifacts,
|
|
432
465
|
fields: param2?.fields,
|
|
433
466
|
context: {...param2?.context, specialCaseUuidColumn: ${JSON.stringify(specialCaseUuidColumn)}},
|
|
434
|
-
nullability: this._nullability,
|
|
435
467
|
${isTransaction ? "dbCall" : ""}
|
|
436
468
|
});
|
|
437
469
|
}`;
|
|
@@ -452,7 +484,6 @@ return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
|
452
484
|
artifacts,
|
|
453
485
|
fields: param2?.fields,
|
|
454
486
|
context: param2?.context,
|
|
455
|
-
nullability: this._nullability,
|
|
456
487
|
${isTransaction ? "dbCall" : ""}
|
|
457
488
|
});
|
|
458
489
|
}`;
|
|
@@ -471,7 +502,6 @@ function getMethodSourcePatchList(x, isTransaction) {
|
|
|
471
502
|
artifacts,
|
|
472
503
|
fields: param2?.fields,
|
|
473
504
|
context: param2?.context,
|
|
474
|
-
nullability: this._nullability,
|
|
475
505
|
${isTransaction ? "dbCall" : ""}
|
|
476
506
|
});
|
|
477
507
|
}`;
|
|
@@ -489,7 +519,6 @@ function getMethodSourceDeleteOne(x, findOnes, isTransaction) {
|
|
|
489
519
|
args: { $where: param1 },
|
|
490
520
|
artifacts,
|
|
491
521
|
context: param2?.context,
|
|
492
|
-
nullability: this._nullability,
|
|
493
522
|
${isTransaction ? "dbCall" : ""}
|
|
494
523
|
});
|
|
495
524
|
}`;
|
|
@@ -505,7 +534,6 @@ function getMethodSourceDeleteList(x, isTransaction) {
|
|
|
505
534
|
args: param1,
|
|
506
535
|
artifacts,
|
|
507
536
|
context: param2?.context,
|
|
508
|
-
nullability: this._nullability,
|
|
509
537
|
${isTransaction ? "dbCall" : ""}
|
|
510
538
|
});
|
|
511
539
|
}`;
|
|
@@ -1170,10 +1198,21 @@ function getMaybeNullableTsType(type, nullable) {
|
|
|
1170
1198
|
}
|
|
1171
1199
|
return type;
|
|
1172
1200
|
}
|
|
1173
|
-
|
|
1201
|
+
function getArtifactsSource(artifacts) {
|
|
1202
|
+
const src = `
|
|
1203
|
+
import type {IArtifacts} from "./IRuntime";
|
|
1204
|
+
|
|
1205
|
+
export const artifacts: IArtifacts = ${JSON.stringify(artifacts)};
|
|
1206
|
+
`;
|
|
1207
|
+
return prettier.format(src, { parser: "typescript" });
|
|
1208
|
+
}
|
|
1209
|
+
async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn) {
|
|
1174
1210
|
const tableMetaList = await Promise.all(tables.map(async (table) => {
|
|
1175
|
-
const tableMeta = await
|
|
1176
|
-
|
|
1211
|
+
const [tableMeta, primaryKey, dumpSchema] = await Promise.all([
|
|
1212
|
+
getTableMeta(table),
|
|
1213
|
+
getPrimaryColumn(table).then((x) => x.name),
|
|
1214
|
+
getShowCreateTable(table)
|
|
1215
|
+
]);
|
|
1177
1216
|
const scalarFields = tableMeta.map((x) => x.Field);
|
|
1178
1217
|
const relationInfo = await getRelationInfo(table);
|
|
1179
1218
|
const relationFields = relationInfo.reduce((acc, x) => {
|
|
@@ -1266,19 +1305,15 @@ async function getArtifactsSource(tables, includeMappedFields, specialCaseUuidCo
|
|
|
1266
1305
|
uniqueFields,
|
|
1267
1306
|
dateTimeFields,
|
|
1268
1307
|
dateTimeFieldsCount: Object.keys(dateTimeFields).length,
|
|
1269
|
-
fields
|
|
1308
|
+
fields,
|
|
1309
|
+
dump: dumpSchema == null ? null : { schema: dumpSchema }
|
|
1270
1310
|
};
|
|
1271
1311
|
}));
|
|
1272
1312
|
const artifacts = tableMetaList.reduce((acc, x) => {
|
|
1273
1313
|
acc[x.table] = x;
|
|
1274
1314
|
return acc;
|
|
1275
1315
|
}, {});
|
|
1276
|
-
|
|
1277
|
-
import type {IArtifacts} from "./IRuntime";
|
|
1278
|
-
|
|
1279
|
-
export const artifacts: IArtifacts = ${JSON.stringify(artifacts)};
|
|
1280
|
-
`;
|
|
1281
|
-
return prettier.format(src, { parser: "typescript" });
|
|
1316
|
+
return artifacts;
|
|
1282
1317
|
}
|
|
1283
1318
|
const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
1284
1319
|
const relationsManyToOne = await getRelationsManyToOne(table);
|
|
@@ -1550,6 +1585,14 @@ const getTableMeta = _.memoize(async function getTableMeta(table) {
|
|
|
1550
1585
|
}
|
|
1551
1586
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1552
1587
|
});
|
|
1588
|
+
function getShowCreateTable(table) {
|
|
1589
|
+
if (dialect === "mysql") {
|
|
1590
|
+
return query("SHOW CREATE TABLE ??", [table]).then((xs) => xs[0]["Create Table"]
|
|
1591
|
+
// https://github.com/bradzacher/mysqldump/blob/66839a57e572a07c046b0ba98753f30a7026cbd8/src/getSchemaDump.ts#L65
|
|
1592
|
+
.replace(/AUTO_INCREMENT\s*=\s*\d+ /g, ""));
|
|
1593
|
+
}
|
|
1594
|
+
return Promise.resolve(null);
|
|
1595
|
+
}
|
|
1553
1596
|
function getJSONSchemaObjProperties(tableMeta) {
|
|
1554
1597
|
return tableMeta.reduce((acc, m) => {
|
|
1555
1598
|
const baseType = getBaseJSONType(m.Type);
|
|
@@ -1711,3 +1754,295 @@ async function getTableNames() {
|
|
|
1711
1754
|
}
|
|
1712
1755
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1713
1756
|
}
|
|
1757
|
+
function getMysql2sqliteSrc() {
|
|
1758
|
+
return `#!/usr/bin/awk -f
|
|
1759
|
+
|
|
1760
|
+
# Authors: @esperlu, @artemyk, @gkuenning, @dumblob
|
|
1761
|
+
|
|
1762
|
+
# FIXME detect empty input file and issue a warning
|
|
1763
|
+
|
|
1764
|
+
function printerr( s ){ print s | "cat >&2" }
|
|
1765
|
+
|
|
1766
|
+
BEGIN {
|
|
1767
|
+
if( ARGC != 2 ){
|
|
1768
|
+
printerr( \\
|
|
1769
|
+
"USAGE:\\n"\\
|
|
1770
|
+
" mysql2sqlite dump_mysql.sql > dump_sqlite3.sql\\n" \\
|
|
1771
|
+
" OR\\n" \\
|
|
1772
|
+
" mysql2sqlite dump_mysql.sql | sqlite3 sqlite.db\\n" \\
|
|
1773
|
+
"\\n" \\
|
|
1774
|
+
"NOTES:\\n" \\
|
|
1775
|
+
" Dash in filename is not supported, because dash (-) means stdin." )
|
|
1776
|
+
no_END = 1
|
|
1777
|
+
exit 1
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
# Find INT_MAX supported by both this AWK (usually an ISO C signed int)
|
|
1781
|
+
# and SQlite.
|
|
1782
|
+
# On non-8bit-based architectures, the additional bits are safely ignored.
|
|
1783
|
+
|
|
1784
|
+
# 8bit (lower precision should not exist)
|
|
1785
|
+
s="127"
|
|
1786
|
+
# "63" + 0 avoids potential parser misbehavior
|
|
1787
|
+
if( (s + 0) "" == s ){ INT_MAX_HALF = "63" + 0 }
|
|
1788
|
+
# 16bit
|
|
1789
|
+
s="32767"
|
|
1790
|
+
if( (s + 0) "" == s ){ INT_MAX_HALF = "16383" + 0 }
|
|
1791
|
+
# 32bit
|
|
1792
|
+
s="2147483647"
|
|
1793
|
+
if( (s + 0) "" == s ){ INT_MAX_HALF = "1073741823" + 0 }
|
|
1794
|
+
# 64bit (as INTEGER in SQlite3)
|
|
1795
|
+
s="9223372036854775807"
|
|
1796
|
+
if( (s + 0) "" == s ){ INT_MAX_HALF = "4611686018427387904" + 0 }
|
|
1797
|
+
# # 128bit
|
|
1798
|
+
# s="170141183460469231731687303715884105728"
|
|
1799
|
+
# if( (s + 0) "" == s ){ INT_MAX_HALF = "85070591730234615865843651857942052864" + 0 }
|
|
1800
|
+
# # 256bit
|
|
1801
|
+
# s="57896044618658097711785492504343953926634992332820282019728792003956564819968"
|
|
1802
|
+
# if( (s + 0) "" == s ){ INT_MAX_HALF = "28948022309329048855892746252171976963317496166410141009864396001978282409984" + 0 }
|
|
1803
|
+
# # 512bit
|
|
1804
|
+
# s="6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048"
|
|
1805
|
+
# if( (s + 0) "" == s ){ INT_MAX_HALF = "3351951982485649274893506249551461531869841455148098344430890360930441007518386744200468574541725856922507964546621512713438470702986642486608412251521024" + 0 }
|
|
1806
|
+
# # 1024bit
|
|
1807
|
+
# s="89884656743115795386465259539451236680898848947115328636715040578866337902750481566354238661203768010560056939935696678829394884407208311246423715319737062188883946712432742638151109800623047059726541476042502884419075341171231440736956555270413618581675255342293149119973622969239858152417678164812112068608"
|
|
1808
|
+
# if( (s + 0) "" == s ){ INT_MAX_HALF = "44942328371557897693232629769725618340449424473557664318357520289433168951375240783177119330601884005280028469967848339414697442203604155623211857659868531094441973356216371319075554900311523529863270738021251442209537670585615720368478277635206809290837627671146574559986811484619929076208839082406056034304" + 0 }
|
|
1809
|
+
# # higher precision probably not needed
|
|
1810
|
+
|
|
1811
|
+
FS=",$"
|
|
1812
|
+
print "PRAGMA synchronous = OFF;"
|
|
1813
|
+
print "PRAGMA journal_mode = MEMORY;"
|
|
1814
|
+
print "BEGIN TRANSACTION;"
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
# historically 3 spaces separate non-argument local variables
|
|
1818
|
+
function bit_to_int( str_bit, powtwo, i, res, bit, overflow ){
|
|
1819
|
+
powtwo = 1
|
|
1820
|
+
overflow = 0
|
|
1821
|
+
# 011101 = 1*2^0 + 0*2^1 + 1*2^2 ...
|
|
1822
|
+
for( i = length( str_bit ); i > 0; --i ){
|
|
1823
|
+
bit = substr( str_bit, i, 1 )
|
|
1824
|
+
if( overflow || ( bit == 1 && res > INT_MAX_HALF ) ){
|
|
1825
|
+
printerr( \\
|
|
1826
|
+
NR ": WARN Bit field overflow, number truncated (LSBs saved, MSBs ignored)." )
|
|
1827
|
+
break
|
|
1828
|
+
}
|
|
1829
|
+
res = res + bit * powtwo
|
|
1830
|
+
# no warning here as it might be the last iteration
|
|
1831
|
+
if( powtwo > INT_MAX_HALF ){ overflow = 1; continue }
|
|
1832
|
+
powtwo = powtwo * 2
|
|
1833
|
+
}
|
|
1834
|
+
return res
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
# CREATE TRIGGER statements have funny commenting. Remember we are in trigger.
|
|
1838
|
+
/^\\/\\*.*(CREATE.*TRIGGER|create.*trigger)/ {
|
|
1839
|
+
gsub( /^.*(TRIGGER|trigger)/, "CREATE TRIGGER" )
|
|
1840
|
+
print
|
|
1841
|
+
inTrigger = 1
|
|
1842
|
+
next
|
|
1843
|
+
}
|
|
1844
|
+
# The end of CREATE TRIGGER has a stray comment terminator
|
|
1845
|
+
/(END|end) \\*\\/;;/ { gsub( /\\*\\//, "" ); print; inTrigger = 0; next }
|
|
1846
|
+
# The rest of triggers just get passed through
|
|
1847
|
+
inTrigger != 0 { print; next }
|
|
1848
|
+
|
|
1849
|
+
# CREATE VIEW looks like a TABLE in comments
|
|
1850
|
+
/^\\/\\*.*(CREATE.*TABLE|create.*table)/ {
|
|
1851
|
+
inView = 1
|
|
1852
|
+
next
|
|
1853
|
+
}
|
|
1854
|
+
# end of CREATE VIEW
|
|
1855
|
+
/^(\\).*(ENGINE|engine).*\\*\\/;)/ {
|
|
1856
|
+
inView = 0
|
|
1857
|
+
next
|
|
1858
|
+
}
|
|
1859
|
+
# content of CREATE VIEW
|
|
1860
|
+
inView != 0 { next }
|
|
1861
|
+
|
|
1862
|
+
# skip comments
|
|
1863
|
+
/^\\/\\*/ { next }
|
|
1864
|
+
|
|
1865
|
+
# skip PARTITION statements
|
|
1866
|
+
/^ *[(]?(PARTITION|partition) +[^ ]+/ { next }
|
|
1867
|
+
|
|
1868
|
+
# print all INSERT lines
|
|
1869
|
+
( /^ *\\(/ && /\\) *[,;] *$/ ) || /^(INSERT|insert|REPLACE|replace)/ {
|
|
1870
|
+
prev = ""
|
|
1871
|
+
|
|
1872
|
+
# first replace \\\\ by \\_ that mysqldump never generates to deal with
|
|
1873
|
+
# sequnces like \\\\n that should be translated into \\n, not \\<LF>.
|
|
1874
|
+
# After we convert all escapes we replace \\_ by backslashes.
|
|
1875
|
+
gsub( /\\\\\\\\/, "\\\\_" )
|
|
1876
|
+
|
|
1877
|
+
# single quotes are escaped by another single quote
|
|
1878
|
+
gsub( /\\\\'/, "''" )
|
|
1879
|
+
gsub( /\\\\n/, "\\n" )
|
|
1880
|
+
gsub( /\\\\r/, "\\r" )
|
|
1881
|
+
gsub( /\\\\"/, "\\"" )
|
|
1882
|
+
gsub( /\\\\\\032/, "\\032" ) # substitute char
|
|
1883
|
+
|
|
1884
|
+
gsub( /\\\\_/, "\\\\" )
|
|
1885
|
+
|
|
1886
|
+
# sqlite3 is limited to 16 significant digits of precision
|
|
1887
|
+
while( match( $0, /0x[0-9a-fA-F]{17}/ ) ){
|
|
1888
|
+
hexIssue = 1
|
|
1889
|
+
sub( /0x[0-9a-fA-F]+/, substr( $0, RSTART, RLENGTH-1 ), $0 )
|
|
1890
|
+
}
|
|
1891
|
+
if( hexIssue ){
|
|
1892
|
+
printerr( \\
|
|
1893
|
+
NR ": WARN Hex number trimmed (length longer than 16 chars)." )
|
|
1894
|
+
hexIssue = 0
|
|
1895
|
+
}
|
|
1896
|
+
print
|
|
1897
|
+
next
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
# CREATE DATABASE is not supported
|
|
1901
|
+
/^(CREATE DATABASE|create database)/ { next }
|
|
1902
|
+
|
|
1903
|
+
# print the CREATE line as is and capture the table name
|
|
1904
|
+
/^(CREATE|create)/ {
|
|
1905
|
+
if( $0 ~ /IF NOT EXISTS|if not exists/ || $0 ~ /TEMPORARY|temporary/ ){
|
|
1906
|
+
caseIssue = 1
|
|
1907
|
+
printerr( \\
|
|
1908
|
+
NR ": WARN Potential case sensitivity issues with table/column naming\\n" \\
|
|
1909
|
+
" (see INFO at the end)." )
|
|
1910
|
+
}
|
|
1911
|
+
if( match( $0, /\`[^\`]+/ ) ){
|
|
1912
|
+
tableName = substr( $0, RSTART+1, RLENGTH-1 )
|
|
1913
|
+
}
|
|
1914
|
+
aInc = 0
|
|
1915
|
+
prev = ""
|
|
1916
|
+
firstInTable = 1
|
|
1917
|
+
print
|
|
1918
|
+
next
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
# Replace \`FULLTEXT KEY\` (probably other \`XXXXX KEY\`)
|
|
1922
|
+
/^ (FULLTEXT KEY|fulltext key)/ { gsub( /[A-Za-z ]+(KEY|key)/, " KEY" ) }
|
|
1923
|
+
|
|
1924
|
+
# Get rid of field lengths in KEY lines
|
|
1925
|
+
/ (PRIMARY |primary )?(KEY|key)/ { gsub( /\\([0-9]+\\)/, "" ) }
|
|
1926
|
+
|
|
1927
|
+
aInc == 1 && /PRIMARY KEY|primary key/ { next }
|
|
1928
|
+
|
|
1929
|
+
# Replace COLLATE xxx_xxxx_xx statements with COLLATE BINARY
|
|
1930
|
+
/ (COLLATE|collate) [a-z0-9_]*/ { gsub( /(COLLATE|collate) [a-z0-9_]*/, "COLLATE BINARY" ) }
|
|
1931
|
+
|
|
1932
|
+
# Print all fields definition lines except the \`KEY\` lines.
|
|
1933
|
+
/^ / && !/^( (KEY|key)|\\);)/ {
|
|
1934
|
+
if( match( $0, /[^"\`]AUTO_INCREMENT|auto_increment[^"\`]/) ){
|
|
1935
|
+
aInc = 1
|
|
1936
|
+
gsub( /AUTO_INCREMENT|auto_increment/, "PRIMARY KEY AUTOINCREMENT" )
|
|
1937
|
+
}
|
|
1938
|
+
gsub( /(UNIQUE KEY|unique key) (\`.*\`|".*") /, "UNIQUE " )
|
|
1939
|
+
gsub( /(CHARACTER SET|character set) [^ ]+[ ,]/, "" )
|
|
1940
|
+
# FIXME
|
|
1941
|
+
# CREATE TRIGGER [UpdateLastTime]
|
|
1942
|
+
# AFTER UPDATE
|
|
1943
|
+
# ON Package
|
|
1944
|
+
# FOR EACH ROW
|
|
1945
|
+
# BEGIN
|
|
1946
|
+
# UPDATE Package SET LastUpdate = CURRENT_TIMESTAMP WHERE ActionId = old.ActionId;
|
|
1947
|
+
# END
|
|
1948
|
+
gsub( /(ON|on) (UPDATE|update) (CURRENT_TIMESTAMP|current_timestamp)(\\(\\))?/, "" )
|
|
1949
|
+
gsub( /(DEFAULT|default) (CURRENT_TIMESTAMP|current_timestamp)(\\(\\))?/, "DEFAULT current_timestamp")
|
|
1950
|
+
gsub( /(COLLATE|collate) [^ ]+ /, "" )
|
|
1951
|
+
gsub( /(ENUM|enum)[^)]+\\)/, "text " )
|
|
1952
|
+
gsub( /(SET|set)\\([^)]+\\)/, "text " )
|
|
1953
|
+
gsub( /UNSIGNED|unsigned/, "" )
|
|
1954
|
+
gsub( /_utf8mb3/, "" )
|
|
1955
|
+
gsub( /\` [^ ]*(INT|int|BIT|bit)[^ ]*/, "\` integer" )
|
|
1956
|
+
gsub( /" [^ ]*(INT|int|BIT|bit)[^ ]*/, "\\" integer" )
|
|
1957
|
+
ere_bit_field = "[bB]'[10]+'"
|
|
1958
|
+
if( match($0, ere_bit_field) ){
|
|
1959
|
+
sub( ere_bit_field, bit_to_int( substr( $0, RSTART +2, RLENGTH -2 -1 ) ) )
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
# remove USING BTREE and other suffixes for USING, for example: "UNIQUE KEY
|
|
1963
|
+
# \`hostname_domain\` (\`hostname\`,\`domain\`) USING BTREE,"
|
|
1964
|
+
gsub( / USING [^, ]+/, "" )
|
|
1965
|
+
|
|
1966
|
+
# field comments are not supported
|
|
1967
|
+
gsub( / (COMMENT|comment).+$/, "" )
|
|
1968
|
+
# Get commas off end of line
|
|
1969
|
+
gsub( /,.?$/, "" )
|
|
1970
|
+
if( prev ){
|
|
1971
|
+
if( firstInTable ){
|
|
1972
|
+
print prev
|
|
1973
|
+
firstInTable = 0
|
|
1974
|
+
}
|
|
1975
|
+
else {
|
|
1976
|
+
print "," prev
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
else {
|
|
1980
|
+
# FIXME check if this is correct in all cases
|
|
1981
|
+
if( match( $1,
|
|
1982
|
+
/(CONSTRAINT|constraint) ["].*["] (FOREIGN KEY|foreign key)/ ) ){
|
|
1983
|
+
print ","
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
prev = $1
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
/ ENGINE| engine/ {
|
|
1990
|
+
if( prev ){
|
|
1991
|
+
if( firstInTable ){
|
|
1992
|
+
print prev
|
|
1993
|
+
firstInTable = 0
|
|
1994
|
+
}
|
|
1995
|
+
else {
|
|
1996
|
+
print "," prev
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
prev=""
|
|
2000
|
+
print ");"
|
|
2001
|
+
next
|
|
2002
|
+
}
|
|
2003
|
+
# \`KEY\` lines are extracted from the \`CREATE\` block and stored in array for later print
|
|
2004
|
+
# in a separate \`CREATE KEY\` command. The index name is prefixed by the table name to
|
|
2005
|
+
# avoid a sqlite error for duplicate index name.
|
|
2006
|
+
/^( (KEY|key)|\\);)/ {
|
|
2007
|
+
if( prev ){
|
|
2008
|
+
if( firstInTable ){
|
|
2009
|
+
print prev
|
|
2010
|
+
firstInTable = 0
|
|
2011
|
+
}
|
|
2012
|
+
else {
|
|
2013
|
+
print "," prev
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
prev = ""
|
|
2017
|
+
if( $0 == ");" ){
|
|
2018
|
+
print
|
|
2019
|
+
}
|
|
2020
|
+
else {
|
|
2021
|
+
if( match( $0, /\`[^\`]+/ ) ){
|
|
2022
|
+
indexName = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2023
|
+
}
|
|
2024
|
+
if( match( $0, /\\([^()]+/ ) ){
|
|
2025
|
+
indexKey = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2026
|
+
}
|
|
2027
|
+
# idx_ prefix to avoid name clashes (they really happen!)
|
|
2028
|
+
key[tableName] = key[tableName] "CREATE INDEX \\"idx_" \\
|
|
2029
|
+
tableName "_" indexName "\\" ON \\"" tableName "\\" (" indexKey ");\\n"
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
END {
|
|
2034
|
+
if( no_END ){ exit 1}
|
|
2035
|
+
# print all KEY creation lines.
|
|
2036
|
+
for( table in key ){ printf key[table] }
|
|
2037
|
+
|
|
2038
|
+
print "END TRANSACTION;"
|
|
2039
|
+
|
|
2040
|
+
if( caseIssue ){
|
|
2041
|
+
printerr( \\
|
|
2042
|
+
"INFO Pure sqlite identifiers are case insensitive (even if quoted\\n" \\
|
|
2043
|
+
" or if ASCII) and doesnt cross-check TABLE and TEMPORARY TABLE\\n" \\
|
|
2044
|
+
" identifiers. Thus expect errors like \\"table T has no column named F\\".")
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
`;
|
|
2048
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,3 @@ export { generate } from "./generation/generate";
|
|
|
2
2
|
export { SDKNotFoundError } from "./runtime/lib/SDKNotFoundError";
|
|
3
3
|
export { SDKBadWhereError } from "./runtime/lib/SDKBadWhereError";
|
|
4
4
|
export { traverseFieldArgs } from "./traverseFieldArgs";
|
|
5
|
-
export { getFakeData } from "./getFakeData";
|
|
6
|
-
export { getIsList } from "./getIsList";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.traverseFieldArgs = exports.SDKBadWhereError = exports.SDKNotFoundError = exports.generate = void 0;
|
|
4
4
|
var generate_1 = require("./generation/generate");
|
|
5
5
|
Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_1.generate; } });
|
|
6
6
|
var SDKNotFoundError_1 = require("./runtime/lib/SDKNotFoundError");
|
|
@@ -9,7 +9,3 @@ var SDKBadWhereError_1 = require("./runtime/lib/SDKBadWhereError");
|
|
|
9
9
|
Object.defineProperty(exports, "SDKBadWhereError", { enumerable: true, get: function () { return SDKBadWhereError_1.SDKBadWhereError; } });
|
|
10
10
|
var traverseFieldArgs_1 = require("./traverseFieldArgs");
|
|
11
11
|
Object.defineProperty(exports, "traverseFieldArgs", { enumerable: true, get: function () { return traverseFieldArgs_1.traverseFieldArgs; } });
|
|
12
|
-
var getFakeData_1 = require("./getFakeData");
|
|
13
|
-
Object.defineProperty(exports, "getFakeData", { enumerable: true, get: function () { return getFakeData_1.getFakeData; } });
|
|
14
|
-
var getIsList_1 = require("./getIsList");
|
|
15
|
-
Object.defineProperty(exports, "getIsList", { enumerable: true, get: function () { return getIsList_1.getIsList; } });
|