@mkven/samples-generation 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +484 -0
  3. package/dist/generator/base-generator.d.ts +39 -0
  4. package/dist/generator/base-generator.d.ts.map +1 -0
  5. package/dist/generator/base-generator.js +72 -0
  6. package/dist/generator/base-generator.js.map +1 -0
  7. package/dist/generator/clickhouse-generator.d.ts +44 -0
  8. package/dist/generator/clickhouse-generator.d.ts.map +1 -0
  9. package/dist/generator/clickhouse-generator.js +452 -0
  10. package/dist/generator/clickhouse-generator.js.map +1 -0
  11. package/dist/generator/escape.d.ts +18 -0
  12. package/dist/generator/escape.d.ts.map +1 -0
  13. package/dist/generator/escape.js +25 -0
  14. package/dist/generator/escape.js.map +1 -0
  15. package/dist/generator/index.d.ts +9 -0
  16. package/dist/generator/index.d.ts.map +1 -0
  17. package/dist/generator/index.js +8 -0
  18. package/dist/generator/index.js.map +1 -0
  19. package/dist/generator/postgres-generator.d.ts +33 -0
  20. package/dist/generator/postgres-generator.d.ts.map +1 -0
  21. package/dist/generator/postgres-generator.js +317 -0
  22. package/dist/generator/postgres-generator.js.map +1 -0
  23. package/dist/generator/sqlite-generator.d.ts +30 -0
  24. package/dist/generator/sqlite-generator.d.ts.map +1 -0
  25. package/dist/generator/sqlite-generator.js +334 -0
  26. package/dist/generator/sqlite-generator.js.map +1 -0
  27. package/dist/generator/trino-generator.d.ts +38 -0
  28. package/dist/generator/trino-generator.d.ts.map +1 -0
  29. package/dist/generator/trino-generator.js +408 -0
  30. package/dist/generator/trino-generator.js.map +1 -0
  31. package/dist/generator/types.d.ts +230 -0
  32. package/dist/generator/types.d.ts.map +1 -0
  33. package/dist/generator/types.js +2 -0
  34. package/dist/generator/types.js.map +1 -0
  35. package/dist/generator/utils.d.ts +14 -0
  36. package/dist/generator/utils.d.ts.map +1 -0
  37. package/dist/generator/utils.js +48 -0
  38. package/dist/generator/utils.js.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +2 -0
  42. package/dist/index.js.map +1 -0
  43. package/package.json +75 -0
@@ -0,0 +1,317 @@
1
+ import postgres from "postgres";
2
+ import { BaseDataGenerator } from "./base-generator.js";
3
+ import { escapePostgresIdentifier } from "./escape.js";
4
+ import { getLookupTableName } from "./utils.js";
5
+ function columnTypeToPostgres(column) {
6
+ switch (column.type) {
7
+ case "integer":
8
+ return "INTEGER";
9
+ case "bigint":
10
+ return "BIGINT";
11
+ case "float":
12
+ return "DOUBLE PRECISION";
13
+ case "string":
14
+ return "TEXT";
15
+ case "boolean":
16
+ return "BOOLEAN";
17
+ case "datetime":
18
+ return "TIMESTAMP";
19
+ case "date":
20
+ return "DATE";
21
+ }
22
+ }
23
+ /**
24
+ * Wrap an expression to return NULL with given probability (Postgres)
25
+ */
26
+ function wrapWithNullCheck(expr, nullProbability) {
27
+ if (nullProbability <= 0)
28
+ return expr;
29
+ if (nullProbability >= 1)
30
+ return "NULL";
31
+ return `CASE WHEN random() < ${String(nullProbability)} THEN NULL ELSE ${expr} END`;
32
+ }
33
+ /**
34
+ * Convert a generator config to a Postgres SQL expression
35
+ */
36
+ export function generatorToPostgresExpr(gen, seqExpr) {
37
+ switch (gen.kind) {
38
+ case "sequence": {
39
+ const start = gen.start ?? 1;
40
+ const step = gen.step ?? 1;
41
+ return `(${String(start)} - 1 + ${seqExpr} * ${String(step)})`;
42
+ }
43
+ case "randomInt":
44
+ return `floor(random() * (${String(gen.max)} - ${String(gen.min)} + 1) + ${String(gen.min)})::int`;
45
+ case "randomFloat": {
46
+ const precision = gen.precision ?? 2;
47
+ return `round((random() * (${String(gen.max)} - ${String(gen.min)}) + ${String(gen.min)})::numeric, ${String(precision)})`;
48
+ }
49
+ case "randomString": {
50
+ const len = gen.length;
51
+ // Use md5 for random strings, repeat and substr for length
52
+ return `substr(md5(random()::text || ${seqExpr}::text), 1, ${String(len)})`;
53
+ }
54
+ case "choice": {
55
+ const values = gen.values;
56
+ const arr = values.map((v) => typeof v === "string" ? `'${v}'` : String(v));
57
+ return `(ARRAY[${arr.join(", ")}])[floor(random() * ${String(arr.length)} + 1)::int]`;
58
+ }
59
+ case "choiceByLookup": {
60
+ // Reference the CTE that will be added by generateNative
61
+ const cteName = getLookupTableName(gen.values);
62
+ return `${cteName}.arr[floor(random() * array_length(${cteName}.arr, 1) + 1)::int]`;
63
+ }
64
+ case "constant": {
65
+ const val = gen.value;
66
+ return typeof val === "string" ? `'${val}'` : String(val);
67
+ }
68
+ case "datetime": {
69
+ const from = gen.from ?? new Date("2020-01-01");
70
+ const to = gen.to ?? new Date();
71
+ const fromTs = Math.floor(from.getTime() / 1000);
72
+ const toTs = Math.floor(to.getTime() / 1000);
73
+ return `to_timestamp(${String(fromTs)} + floor(random() * ${String(toTs - fromTs)})::int)`;
74
+ }
75
+ case "uuid":
76
+ return "gen_random_uuid()";
77
+ }
78
+ }
79
+ export class PostgresDataGenerator extends BaseDataGenerator {
80
+ config;
81
+ name = "postgres";
82
+ sql = null;
83
+ constructor(config) {
84
+ super();
85
+ this.config = config;
86
+ }
87
+ connect() {
88
+ this.sql = postgres({
89
+ host: this.config.host,
90
+ port: this.config.port,
91
+ database: this.config.database,
92
+ username: this.config.username,
93
+ password: this.config.password,
94
+ });
95
+ return Promise.resolve();
96
+ }
97
+ async disconnect() {
98
+ if (this.sql) {
99
+ await this.sql.end();
100
+ this.sql = null;
101
+ }
102
+ }
103
+ getSql() {
104
+ if (!this.sql) {
105
+ throw new Error("Not connected to Postgres");
106
+ }
107
+ return this.sql;
108
+ }
109
+ async createTable(table) {
110
+ const sql = this.getSql();
111
+ const columnDefs = table.columns
112
+ .map((col) => {
113
+ const colType = columnTypeToPostgres(col);
114
+ const nullable = col.nullable ? "" : " NOT NULL";
115
+ return `${escapePostgresIdentifier(col.name)} ${colType}${nullable}`;
116
+ })
117
+ .join(", ");
118
+ const escapedTableName = escapePostgresIdentifier(table.name);
119
+ await sql.unsafe(`CREATE TABLE IF NOT EXISTS ${escapedTableName} (${columnDefs})`);
120
+ }
121
+ async truncateTable(tableName) {
122
+ const sql = this.getSql();
123
+ await sql `TRUNCATE TABLE ${sql(tableName)}`;
124
+ }
125
+ async dropTable(tableName) {
126
+ const sql = this.getSql();
127
+ await sql `DROP TABLE IF EXISTS ${sql(tableName)}`;
128
+ }
129
+ async generateNative(table, rowCount, startSequence) {
130
+ const sql = this.getSql();
131
+ const escapedTableName = escapePostgresIdentifier(table.name);
132
+ // Collect choiceByLookup generators to create CTEs
133
+ const lookupCtes = [];
134
+ for (const col of table.columns) {
135
+ if (col.generator.kind === "choiceByLookup") {
136
+ const gen = col.generator;
137
+ const cteName = getLookupTableName(gen.values);
138
+ const valuesLiteral = gen.values
139
+ .map((v) => `'${v.replace(/'/g, "''")}'`)
140
+ .join(", ");
141
+ lookupCtes.push(`${cteName} AS (SELECT ARRAY[${valuesLiteral}] AS arr)`);
142
+ }
143
+ }
144
+ // Build column list and expressions
145
+ const columns = table.columns.map((c) => escapePostgresIdentifier(c.name));
146
+ const seqExpr = `(n + ${String(startSequence - 1)})`;
147
+ const expressions = table.columns.map((col) => {
148
+ let expr = generatorToPostgresExpr(col.generator, seqExpr);
149
+ // Cast to proper type if needed
150
+ if (col.type === "integer")
151
+ expr = `(${expr})::integer`;
152
+ else if (col.type === "bigint")
153
+ expr = `(${expr})::bigint`;
154
+ else if (col.type === "boolean")
155
+ expr = `(${expr})::boolean`;
156
+ // Apply null probability if specified
157
+ if (col.nullable && col.nullProbability && col.nullProbability > 0) {
158
+ expr = wrapWithNullCheck(expr, col.nullProbability);
159
+ }
160
+ return expr;
161
+ });
162
+ // Build CTE prefix if we have lookup tables
163
+ const ctePrefix = lookupCtes.length > 0 ? `WITH ${lookupCtes.join(", ")} ` : "";
164
+ // Cross join with lookup CTEs to make them available
165
+ const lookupJoins = lookupCtes.length > 0
166
+ ? ", " +
167
+ [
168
+ ...new Set(table.columns
169
+ .filter((c) => c.generator.kind === "choiceByLookup")
170
+ .map((c) => getLookupTableName(c.generator.values))),
171
+ ].join(", ")
172
+ : "";
173
+ const insertSql = `
174
+ ${ctePrefix}INSERT INTO ${escapedTableName} (${columns.join(", ")})
175
+ SELECT ${expressions.join(", ")}
176
+ FROM generate_series(1, ${String(rowCount)}) AS n${lookupJoins}
177
+ `;
178
+ await sql.unsafe(insertSql);
179
+ }
180
+ async queryRows(tableName, limit = 100) {
181
+ const sql = this.getSql();
182
+ const result = await sql `SELECT * FROM ${sql(tableName)} LIMIT ${limit}`;
183
+ return result;
184
+ }
185
+ async countRows(tableName) {
186
+ const sql = this.getSql();
187
+ const result = await sql `SELECT COUNT(*) as count FROM ${sql(tableName)}`;
188
+ const firstRow = result[0];
189
+ if (!firstRow) {
190
+ return 0;
191
+ }
192
+ return Number(firstRow.count);
193
+ }
194
+ async getMaxValue(tableName, columnName) {
195
+ const sql = this.getSql();
196
+ const result = await sql `SELECT MAX(${sql(columnName)}) as max_val FROM ${sql(tableName)}`;
197
+ const firstRow = result[0];
198
+ if (!firstRow?.max_val) {
199
+ return null;
200
+ }
201
+ return Number(firstRow.max_val);
202
+ }
203
+ async getTableSize(tableName) {
204
+ const sql = this.getSql();
205
+ const result = await sql `SELECT pg_total_relation_size(${tableName}::regclass) as size`;
206
+ const firstRow = result[0];
207
+ if (!firstRow) {
208
+ return null;
209
+ }
210
+ return Number(firstRow.size);
211
+ }
212
+ async optimize(tableName) {
213
+ const sql = this.getSql();
214
+ // VACUUM reclaims storage and ANALYZE updates statistics
215
+ await sql.unsafe(`VACUUM ANALYZE ${escapePostgresIdentifier(tableName)}`);
216
+ }
217
+ async applyTransformations(tableName, transformations) {
218
+ if (transformations.length === 0)
219
+ return;
220
+ const sql = this.getSql();
221
+ const escapedTable = escapePostgresIdentifier(tableName);
222
+ const setClauses = [];
223
+ for (const t of transformations) {
224
+ switch (t.kind) {
225
+ case "template": {
226
+ const escapedCol = escapePostgresIdentifier(t.column);
227
+ // Replace {column_name} with column references
228
+ let expr = `'${t.template.replace(/'/g, "''")}'`;
229
+ const refs = t.template.match(/\{([^}]+)\}/g) ?? [];
230
+ for (const ref of refs) {
231
+ const colName = ref.slice(1, -1);
232
+ const colRef = escapePostgresIdentifier(colName);
233
+ // Replace {col} with concatenation: ... || col || ...
234
+ expr = expr.replace(`'{${colName}}'`, `' || ${colRef} || '`);
235
+ expr = expr.replace(`{${colName}}`, `' || ${colRef} || '`);
236
+ }
237
+ // Clean up empty string concatenations
238
+ expr = expr.replace(/^'' \|\| /, "").replace(/ \|\| ''$/, "");
239
+ expr = expr.replace(/' \|\| '' \|\| '/g, "' || '");
240
+ if (t.lowercase) {
241
+ expr = `lower(${expr})`;
242
+ }
243
+ setClauses.push(`${escapedCol} = ${expr}`);
244
+ break;
245
+ }
246
+ case "mutate": {
247
+ const escapedCol = escapePostgresIdentifier(t.column);
248
+ // Random string mutation
249
+ const { probability, operations } = t;
250
+ // Build mutation expressions for each operation
251
+ const mutationExprs = {
252
+ replace: `overlay(${escapedCol} placing 'X' from (floor(random() * length(${escapedCol})) + 1)::int for 1)`,
253
+ delete: `left(${escapedCol}, (floor(random() * length(${escapedCol})))::int) || right(${escapedCol}, length(${escapedCol}) - (floor(random() * length(${escapedCol})) + 1)::int)`,
254
+ insert: `left(${escapedCol}, (floor(random() * length(${escapedCol})))::int) || 'X' || right(${escapedCol}, length(${escapedCol}) - (floor(random() * length(${escapedCol})))::int)`,
255
+ };
256
+ // Build expression that randomly picks from available operations
257
+ let mutateExpr;
258
+ if (operations.length === 1) {
259
+ // We know operations[0] exists since length === 1
260
+ mutateExpr = mutationExprs[operations[0]]; // eslint-disable-line @typescript-eslint/no-non-null-assertion
261
+ }
262
+ else {
263
+ // Use CASE with random() to pick operation
264
+ const cases = operations.map((op, i) => {
265
+ const threshold = (i + 1) / operations.length;
266
+ if (i === operations.length - 1) {
267
+ return `ELSE ${mutationExprs[op]}`;
268
+ }
269
+ return `WHEN random() < ${String(threshold)} THEN ${mutationExprs[op]}`;
270
+ });
271
+ mutateExpr = `(CASE ${cases.join(" ")} END)`;
272
+ }
273
+ setClauses.push(`${escapedCol} = CASE WHEN random() < ${String(probability)} THEN ${mutateExpr} ELSE ${escapedCol} END`);
274
+ break;
275
+ }
276
+ case "lookup": {
277
+ const escapedCol = escapePostgresIdentifier(t.column);
278
+ // Lookup value from another table via join
279
+ // PostgreSQL supports UPDATE ... FROM ... WHERE syntax
280
+ const fromTable = escapePostgresIdentifier(t.fromTable);
281
+ const fromCol = escapePostgresIdentifier(t.fromColumn);
282
+ const targetJoinCol = escapePostgresIdentifier(t.joinOn.targetColumn);
283
+ const lookupJoinCol = escapePostgresIdentifier(t.joinOn.lookupColumn);
284
+ // Use subquery for simplicity (works with multiple lookups in same batch)
285
+ setClauses.push(`${escapedCol} = (SELECT ${fromCol} FROM ${fromTable} WHERE ${lookupJoinCol} = ${escapedTable}.${targetJoinCol})`);
286
+ break;
287
+ }
288
+ case "swap": {
289
+ // Swap handled separately - needs both columns in one UPDATE
290
+ // Skip here, will be handled after the loop
291
+ break;
292
+ }
293
+ }
294
+ }
295
+ // Handle swap transformations separately (need atomic swap with same random)
296
+ const swapTransformations = transformations.filter((t) => t.kind === "swap");
297
+ for (const swap of swapTransformations) {
298
+ const col1 = escapePostgresIdentifier(swap.column1);
299
+ const col2 = escapePostgresIdentifier(swap.column2);
300
+ const prob = String(swap.probability);
301
+ // Use a subquery to ensure same random value for both columns
302
+ // PostgreSQL evaluates SET expressions using old values, so a = b, b = a works
303
+ const swapSql = `
304
+ UPDATE ${escapedTable} SET
305
+ ${col1} = ${col2},
306
+ ${col2} = ${col1}
307
+ WHERE random() < ${prob}
308
+ `;
309
+ await sql.unsafe(swapSql);
310
+ }
311
+ if (setClauses.length === 0)
312
+ return;
313
+ const updateSql = `UPDATE ${escapedTable} SET ${setClauses.join(", ")}`;
314
+ await sql.unsafe(updateSql);
315
+ }
316
+ }
317
+ //# sourceMappingURL=postgres-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-generator.js","sourceRoot":"","sources":["../../src/generator/postgres-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { TableConfig, GeneratedRow, GeneratorConfig, Transformation } from "./types.js";
2
+ import { BaseDataGenerator } from "./base-generator.js";
3
+ export interface SQLiteConfig {
4
+ path: string;
5
+ }
6
+ /**
7
+ * Convert a generator config to a SQLite SQL expression
8
+ * SQLite uses 'n' as the row number from the recursive CTE (1-based)
9
+ */
10
+ export declare function generatorToSqliteExpr(gen: GeneratorConfig, seqExpr: string): string;
11
+ export declare class SQLiteDataGenerator extends BaseDataGenerator {
12
+ private config;
13
+ readonly name = "sqlite";
14
+ private db;
15
+ constructor(config: SQLiteConfig);
16
+ connect(): Promise<void>;
17
+ disconnect(): Promise<void>;
18
+ private getDb;
19
+ createTable(table: TableConfig): Promise<void>;
20
+ truncateTable(tableName: string): Promise<void>;
21
+ dropTable(tableName: string): Promise<void>;
22
+ protected generateNative(table: TableConfig, rowCount: number, startSequence: number): Promise<void>;
23
+ queryRows(tableName: string, limit?: number): Promise<GeneratedRow[]>;
24
+ countRows(tableName: string): Promise<number>;
25
+ getMaxValue(tableName: string, columnName: string): Promise<number | null>;
26
+ getTableSize(tableName: string): Promise<number | null>;
27
+ optimize(_tableName: string): Promise<void>;
28
+ protected applyTransformations(tableName: string, transformations: Transformation[]): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=sqlite-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-generator.d.ts","sourceRoot":"","sources":["../../src/generator/sqlite-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EAEZ,eAAe,EAEf,cAAc,EAGf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AA6BD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAsDR;AAED,qBAAa,mBAAoB,SAAQ,iBAAiB;IAI5C,OAAO,CAAC,MAAM;IAH1B,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,EAAE,CAAkC;gBAExB,MAAM,EAAE,YAAY;IAIxC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,OAAO,CAAC,KAAK;IAOb,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,SAAS,CAAC,cAAc,CACtB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IAoEhB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAQlE,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ7C,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQ1E,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsBvD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,SAAS,CAAC,oBAAoB,CAC5B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,cAAc,EAAE,GAChC,OAAO,CAAC,IAAI,CAAC;CAqHjB"}