@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 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
- - spin up test environment: `docker-compose up -d`
51
- - run tests: `docker-compose exec test yarn test`
50
+ - `yarn test`
52
51
 
53
- - `yarn test:prepare`
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 prettier = require("prettier");
9
- const changeCase = require("change-case");
10
- const fse = require("fs-extra");
11
- const _ = require("lodash/fp");
12
- const uuid_1 = require("uuid");
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 artifactsSource = await getArtifactsSource(tables, includeMappedFields, specialCaseUuidColumn);
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(), `dsg-${(0, uuid_1.v4)()}`);
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, IRuntimeFilename), fs.readFileSync(sourceIRuntimeFilePath));
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
- const { nullability, ...otherOpts } = opts.otherOpts ?? {};
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
- async function getArtifactsSource(tables, includeMappedFields, specialCaseUuidColumn) {
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 getTableMeta(table);
1176
- const primaryKey = await getPrimaryColumn(table).then((x) => x.name);
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
- const src = `
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.getIsList = exports.getFakeData = exports.traverseFieldArgs = exports.SDKBadWhereError = exports.SDKNotFoundError = exports.generate = void 0;
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; } });