@pilat/mcp-datalink 1.0.1

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 (95) hide show
  1. package/README.md +442 -0
  2. package/databases.example.json +18 -0
  3. package/dist/__integration__/global-setup.d.ts +8 -0
  4. package/dist/__integration__/global-setup.d.ts.map +1 -0
  5. package/dist/__integration__/global-setup.js +34 -0
  6. package/dist/__integration__/global-setup.js.map +1 -0
  7. package/dist/__integration__/global-teardown.d.ts +8 -0
  8. package/dist/__integration__/global-teardown.d.ts.map +1 -0
  9. package/dist/__integration__/global-teardown.js +17 -0
  10. package/dist/__integration__/global-teardown.js.map +1 -0
  11. package/dist/__integration__/helpers.d.ts +58 -0
  12. package/dist/__integration__/helpers.d.ts.map +1 -0
  13. package/dist/__integration__/helpers.js +568 -0
  14. package/dist/__integration__/helpers.js.map +1 -0
  15. package/dist/__integration__/setup.d.ts +79 -0
  16. package/dist/__integration__/setup.d.ts.map +1 -0
  17. package/dist/__integration__/setup.js +230 -0
  18. package/dist/__integration__/setup.js.map +1 -0
  19. package/dist/adapters/factory.d.ts +40 -0
  20. package/dist/adapters/factory.d.ts.map +1 -0
  21. package/dist/adapters/factory.js +114 -0
  22. package/dist/adapters/factory.js.map +1 -0
  23. package/dist/adapters/index.d.ts +31 -0
  24. package/dist/adapters/index.d.ts.map +1 -0
  25. package/dist/adapters/index.js +34 -0
  26. package/dist/adapters/index.js.map +1 -0
  27. package/dist/adapters/mysql/adapter.d.ts +61 -0
  28. package/dist/adapters/mysql/adapter.d.ts.map +1 -0
  29. package/dist/adapters/mysql/adapter.js +567 -0
  30. package/dist/adapters/mysql/adapter.js.map +1 -0
  31. package/dist/adapters/postgresql/adapter.d.ts +52 -0
  32. package/dist/adapters/postgresql/adapter.d.ts.map +1 -0
  33. package/dist/adapters/postgresql/adapter.js +429 -0
  34. package/dist/adapters/postgresql/adapter.js.map +1 -0
  35. package/dist/adapters/sqlite/adapter.d.ts +56 -0
  36. package/dist/adapters/sqlite/adapter.d.ts.map +1 -0
  37. package/dist/adapters/sqlite/adapter.js +582 -0
  38. package/dist/adapters/sqlite/adapter.js.map +1 -0
  39. package/dist/adapters/types.d.ts +155 -0
  40. package/dist/adapters/types.d.ts.map +1 -0
  41. package/dist/adapters/types.js +7 -0
  42. package/dist/adapters/types.js.map +1 -0
  43. package/dist/config/loader.d.ts +11 -0
  44. package/dist/config/loader.d.ts.map +1 -0
  45. package/dist/config/loader.js +127 -0
  46. package/dist/config/loader.js.map +1 -0
  47. package/dist/index.d.ts +8 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +38 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/server.d.ts +21 -0
  52. package/dist/server.d.ts.map +1 -0
  53. package/dist/server.js +191 -0
  54. package/dist/server.js.map +1 -0
  55. package/dist/tools/describe-table.d.ts +11 -0
  56. package/dist/tools/describe-table.d.ts.map +1 -0
  57. package/dist/tools/describe-table.js +23 -0
  58. package/dist/tools/describe-table.js.map +1 -0
  59. package/dist/tools/execute.d.ts +22 -0
  60. package/dist/tools/execute.d.ts.map +1 -0
  61. package/dist/tools/execute.js +48 -0
  62. package/dist/tools/execute.js.map +1 -0
  63. package/dist/tools/explain.d.ts +25 -0
  64. package/dist/tools/explain.d.ts.map +1 -0
  65. package/dist/tools/explain.js +81 -0
  66. package/dist/tools/explain.js.map +1 -0
  67. package/dist/tools/list-databases.d.ts +18 -0
  68. package/dist/tools/list-databases.d.ts.map +1 -0
  69. package/dist/tools/list-databases.js +17 -0
  70. package/dist/tools/list-databases.js.map +1 -0
  71. package/dist/tools/list-tables.d.ts +22 -0
  72. package/dist/tools/list-tables.d.ts.map +1 -0
  73. package/dist/tools/list-tables.js +43 -0
  74. package/dist/tools/list-tables.js.map +1 -0
  75. package/dist/tools/query.d.ts +25 -0
  76. package/dist/tools/query.d.ts.map +1 -0
  77. package/dist/tools/query.js +109 -0
  78. package/dist/tools/query.js.map +1 -0
  79. package/dist/types.d.ts +93 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +5 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/utils/errors.d.ts +22 -0
  84. package/dist/utils/errors.d.ts.map +1 -0
  85. package/dist/utils/errors.js +41 -0
  86. package/dist/utils/errors.js.map +1 -0
  87. package/dist/utils/formatter.d.ts +13 -0
  88. package/dist/utils/formatter.d.ts.map +1 -0
  89. package/dist/utils/formatter.js +56 -0
  90. package/dist/utils/formatter.js.map +1 -0
  91. package/dist/utils/truncate.d.ts +37 -0
  92. package/dist/utils/truncate.d.ts.map +1 -0
  93. package/dist/utils/truncate.js +91 -0
  94. package/dist/utils/truncate.js.map +1 -0
  95. package/package.json +65 -0
@@ -0,0 +1,568 @@
1
+ /**
2
+ * Integration test helpers
3
+ *
4
+ * Provides test configuration factory and database utilities.
5
+ */
6
+ import { execSql, execSqliteSql, getSqliteTestDb, execMySql, execMySqlBatch, getPostgresUrl, getMySqlUrl } from './setup.js';
7
+ const TEST_SQLITE_DB_PATH = './test-data/test.db';
8
+ /**
9
+ * Create a test configuration with optional overrides
10
+ */
11
+ export function createTestConfig(overrides) {
12
+ const postgresUrl = getPostgresUrl();
13
+ const base = {
14
+ databases: {
15
+ testdb: {
16
+ url: postgresUrl,
17
+ readonly: false,
18
+ },
19
+ readonlydb: {
20
+ url: postgresUrl,
21
+ readonly: true,
22
+ },
23
+ },
24
+ defaults: {
25
+ maxRows: 100,
26
+ maxCellLength: 500,
27
+ maxTotalSize: 65536,
28
+ maxColumns: 50,
29
+ maxTables: 200,
30
+ maxIndexes: 20,
31
+ timeout: 30000,
32
+ },
33
+ };
34
+ if (!overrides) {
35
+ return base;
36
+ }
37
+ // Handle databases override - if explicitly provided, use it directly
38
+ const databases = 'databases' in overrides
39
+ ? overrides.databases ?? base.databases
40
+ : base.databases;
41
+ // Handle defaults override - merge with base
42
+ const defaults = 'defaults' in overrides
43
+ ? { ...base.defaults, ...overrides.defaults }
44
+ : base.defaults;
45
+ return { databases, defaults };
46
+ }
47
+ /**
48
+ * Initialize the test database schema
49
+ */
50
+ export async function initializeSchema() {
51
+ const schema = `
52
+ -- Drop existing tables in reverse FK order
53
+ DROP TABLE IF EXISTS order_items CASCADE;
54
+ DROP TABLE IF EXISTS orders CASCADE;
55
+ DROP TABLE IF EXISTS products CASCADE;
56
+ DROP TABLE IF EXISTS users CASCADE;
57
+ DROP TABLE IF EXISTS wide_table CASCADE;
58
+ DROP VIEW IF EXISTS user_order_summary CASCADE;
59
+ DROP SCHEMA IF EXISTS test_schema CASCADE;
60
+
61
+ -- Users table with various column types
62
+ CREATE TABLE users (
63
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
64
+ email VARCHAR(255) NOT NULL UNIQUE,
65
+ name VARCHAR(100),
66
+ age INTEGER,
67
+ balance DECIMAL(10, 2) DEFAULT 0.00,
68
+ metadata JSONB,
69
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
70
+ updated_at TIMESTAMPTZ,
71
+ is_active BOOLEAN DEFAULT true
72
+ );
73
+
74
+ -- Indexes for testing
75
+ CREATE INDEX users_created_at_idx ON users(created_at);
76
+ CREATE INDEX users_name_email_idx ON users(name, email);
77
+
78
+ -- Products table
79
+ CREATE TABLE products (
80
+ id SERIAL PRIMARY KEY,
81
+ name VARCHAR(255) NOT NULL,
82
+ price DECIMAL(10, 2) NOT NULL,
83
+ stock INTEGER DEFAULT 0,
84
+ category VARCHAR(100)
85
+ );
86
+
87
+ -- Orders table with foreign key
88
+ CREATE TABLE orders (
89
+ id SERIAL PRIMARY KEY,
90
+ user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
91
+ total DECIMAL(10, 2) NOT NULL,
92
+ status VARCHAR(50) DEFAULT 'pending',
93
+ items JSONB NOT NULL DEFAULT '[]',
94
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
95
+ );
96
+
97
+ CREATE INDEX orders_user_id_idx ON orders(user_id);
98
+ CREATE INDEX orders_status_idx ON orders(status);
99
+
100
+ -- Order items junction table
101
+ CREATE TABLE order_items (
102
+ order_id INTEGER NOT NULL REFERENCES orders(id),
103
+ product_id INTEGER NOT NULL REFERENCES products(id),
104
+ quantity INTEGER NOT NULL DEFAULT 1,
105
+ price_at_time DECIMAL(10, 2) NOT NULL,
106
+ PRIMARY KEY (order_id, product_id)
107
+ );
108
+
109
+ -- View for testing view detection
110
+ CREATE VIEW user_order_summary AS
111
+ SELECT
112
+ u.id as user_id,
113
+ u.email,
114
+ COUNT(o.id) as order_count,
115
+ COALESCE(SUM(o.total), 0) as total_spent
116
+ FROM users u
117
+ LEFT JOIN orders o ON u.id = o.user_id
118
+ GROUP BY u.id, u.email;
119
+
120
+ -- Wide table for truncation testing
121
+ CREATE TABLE wide_table (
122
+ id SERIAL PRIMARY KEY,
123
+ col_01 TEXT, col_02 TEXT, col_03 TEXT, col_04 TEXT, col_05 TEXT,
124
+ col_06 TEXT, col_07 TEXT, col_08 TEXT, col_09 TEXT, col_10 TEXT,
125
+ col_11 TEXT, col_12 TEXT, col_13 TEXT, col_14 TEXT, col_15 TEXT,
126
+ col_16 TEXT, col_17 TEXT, col_18 TEXT, col_19 TEXT, col_20 TEXT,
127
+ col_21 TEXT, col_22 TEXT, col_23 TEXT, col_24 TEXT, col_25 TEXT,
128
+ col_26 TEXT, col_27 TEXT, col_28 TEXT, col_29 TEXT, col_30 TEXT,
129
+ col_31 TEXT, col_32 TEXT, col_33 TEXT, col_34 TEXT, col_35 TEXT,
130
+ col_36 TEXT, col_37 TEXT, col_38 TEXT, col_39 TEXT, col_40 TEXT,
131
+ col_41 TEXT, col_42 TEXT, col_43 TEXT, col_44 TEXT, col_45 TEXT,
132
+ col_46 TEXT, col_47 TEXT, col_48 TEXT, col_49 TEXT, col_50 TEXT,
133
+ col_51 TEXT, col_52 TEXT, col_53 TEXT, col_54 TEXT, col_55 TEXT
134
+ );
135
+
136
+ -- Test schema for non-public schema testing
137
+ CREATE SCHEMA test_schema;
138
+
139
+ CREATE TABLE test_schema.special_table (
140
+ id SERIAL PRIMARY KEY,
141
+ data TEXT
142
+ );
143
+ `;
144
+ await execSql(schema);
145
+ }
146
+ /**
147
+ * Seed the test database with sample data
148
+ * Uses TRUNCATE CASCADE for fast, atomic cleanup then re-insert
149
+ */
150
+ export async function seedTestData() {
151
+ // Use TRUNCATE CASCADE for fast, atomic cleanup
152
+ await execSql('TRUNCATE users, products, orders, order_items RESTART IDENTITY CASCADE');
153
+ const seed = `
154
+ -- Seed users
155
+ INSERT INTO users (id, email, name, age, balance, metadata, is_active) VALUES
156
+ ('11111111-1111-1111-1111-111111111111', 'alice@example.com', 'Alice Smith', 30, 1000.50, '{"role": "admin"}', true),
157
+ ('22222222-2222-2222-2222-222222222222', 'bob@example.com', 'Bob Jones', 25, 500.00, '{"role": "user"}', true),
158
+ ('33333333-3333-3333-3333-333333333333', 'charlie@example.com', 'Charlie Brown', 35, 0.00, null, false);
159
+
160
+ -- Seed products
161
+ INSERT INTO products (id, name, price, stock, category) VALUES
162
+ (1, 'Widget', 9.99, 100, 'gadgets'),
163
+ (2, 'Gadget', 19.99, 50, 'gadgets'),
164
+ (3, 'Thingamajig', 29.99, 25, 'misc');
165
+
166
+ -- Reset sequence after explicit ID inserts
167
+ SELECT setval('products_id_seq', 3);
168
+
169
+ -- Seed orders
170
+ INSERT INTO orders (id, user_id, total, status, items) VALUES
171
+ (1, '11111111-1111-1111-1111-111111111111', 29.98, 'completed', '[{"product_id": 1, "qty": 2}]'),
172
+ (2, '11111111-1111-1111-1111-111111111111', 19.99, 'pending', '[{"product_id": 2, "qty": 1}]'),
173
+ (3, '22222222-2222-2222-2222-222222222222', 9.99, 'completed', '[{"product_id": 1, "qty": 1}]');
174
+
175
+ SELECT setval('orders_id_seq', 3);
176
+
177
+ -- Seed order items
178
+ INSERT INTO order_items (order_id, product_id, quantity, price_at_time) VALUES
179
+ (1, 1, 2, 9.99),
180
+ (2, 2, 1, 19.99),
181
+ (3, 1, 1, 9.99);
182
+
183
+ -- Seed test_schema
184
+ DELETE FROM test_schema.special_table;
185
+ INSERT INTO test_schema.special_table (id, data) VALUES (1, 'test data');
186
+
187
+ -- Force stats update for row estimates
188
+ ANALYZE;
189
+ `;
190
+ await execSql(seed);
191
+ }
192
+ /**
193
+ * Clean up test data between tests
194
+ */
195
+ export async function cleanupTestData() {
196
+ await execSql(`
197
+ TRUNCATE order_items, orders, products, users RESTART IDENTITY CASCADE;
198
+ TRUNCATE test_schema.special_table RESTART IDENTITY CASCADE;
199
+ `);
200
+ }
201
+ // ============================================================================
202
+ // SQLite Test Configuration and Helpers
203
+ // ============================================================================
204
+ /**
205
+ * Create a SQLite test configuration with optional overrides
206
+ */
207
+ export function createSqliteTestConfig(overrides) {
208
+ const base = {
209
+ databases: {
210
+ sqlitedb: {
211
+ url: `sqlite://${TEST_SQLITE_DB_PATH}`,
212
+ readonly: false,
213
+ },
214
+ sqlitedb_readonly: {
215
+ url: `sqlite://${TEST_SQLITE_DB_PATH}`,
216
+ readonly: true,
217
+ },
218
+ },
219
+ defaults: {
220
+ maxRows: 100,
221
+ maxCellLength: 500,
222
+ maxTotalSize: 65536,
223
+ maxColumns: 50,
224
+ maxTables: 200,
225
+ maxIndexes: 20,
226
+ timeout: 30000,
227
+ },
228
+ };
229
+ if (!overrides) {
230
+ return base;
231
+ }
232
+ // Handle databases override - if explicitly provided, use it directly
233
+ const databases = 'databases' in overrides
234
+ ? overrides.databases ?? base.databases
235
+ : base.databases;
236
+ // Handle defaults override - merge with base
237
+ const defaults = 'defaults' in overrides
238
+ ? { ...base.defaults, ...overrides.defaults }
239
+ : base.defaults;
240
+ return { databases, defaults };
241
+ }
242
+ /**
243
+ * Initialize the SQLite test database schema
244
+ */
245
+ export async function initializeSqliteSchema() {
246
+ // Drop existing tables in reverse FK order
247
+ await execSqliteSql('DROP TABLE IF EXISTS order_items');
248
+ await execSqliteSql('DROP TABLE IF EXISTS orders');
249
+ await execSqliteSql('DROP TABLE IF EXISTS products');
250
+ await execSqliteSql('DROP TABLE IF EXISTS users');
251
+ await execSqliteSql('DROP TABLE IF EXISTS wide_table');
252
+ await execSqliteSql('DROP VIEW IF EXISTS user_order_summary');
253
+ // Users table with SQLite-compatible types
254
+ await execSqliteSql(`
255
+ CREATE TABLE users (
256
+ id TEXT PRIMARY KEY,
257
+ email TEXT NOT NULL UNIQUE,
258
+ name TEXT,
259
+ age INTEGER,
260
+ balance REAL DEFAULT 0.00,
261
+ metadata TEXT,
262
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
263
+ updated_at TEXT,
264
+ is_active INTEGER DEFAULT 1
265
+ )
266
+ `);
267
+ // Create indexes for testing
268
+ await execSqliteSql('CREATE INDEX users_created_at_idx ON users(created_at)');
269
+ await execSqliteSql('CREATE INDEX users_name_email_idx ON users(name, email)');
270
+ // Products table
271
+ await execSqliteSql(`
272
+ CREATE TABLE products (
273
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
274
+ name TEXT NOT NULL,
275
+ price REAL NOT NULL,
276
+ stock INTEGER DEFAULT 0,
277
+ category TEXT
278
+ )
279
+ `);
280
+ // Orders table with foreign key
281
+ await execSqliteSql(`
282
+ CREATE TABLE orders (
283
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
284
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
285
+ total REAL NOT NULL,
286
+ status TEXT DEFAULT 'pending',
287
+ items TEXT NOT NULL DEFAULT '[]',
288
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
289
+ )
290
+ `);
291
+ await execSqliteSql('CREATE INDEX orders_user_id_idx ON orders(user_id)');
292
+ await execSqliteSql('CREATE INDEX orders_status_idx ON orders(status)');
293
+ // Order items junction table
294
+ await execSqliteSql(`
295
+ CREATE TABLE order_items (
296
+ order_id INTEGER NOT NULL REFERENCES orders(id),
297
+ product_id INTEGER NOT NULL REFERENCES products(id),
298
+ quantity INTEGER NOT NULL DEFAULT 1,
299
+ price_at_time REAL NOT NULL,
300
+ PRIMARY KEY (order_id, product_id)
301
+ )
302
+ `);
303
+ // View for testing view detection
304
+ await execSqliteSql(`
305
+ CREATE VIEW user_order_summary AS
306
+ SELECT
307
+ u.id as user_id,
308
+ u.email,
309
+ COUNT(o.id) as order_count,
310
+ COALESCE(SUM(o.total), 0) as total_spent
311
+ FROM users u
312
+ LEFT JOIN orders o ON u.id = o.user_id
313
+ GROUP BY u.id, u.email
314
+ `);
315
+ // Wide table for truncation testing
316
+ const wideCols = Array.from({ length: 55 }, (_, i) => `col_${String(i + 1).padStart(2, '0')} TEXT`).join(', ');
317
+ await execSqliteSql(`
318
+ CREATE TABLE wide_table (
319
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
320
+ ${wideCols}
321
+ )
322
+ `);
323
+ }
324
+ /**
325
+ * Seed the SQLite test database with sample data
326
+ * Uses full cleanup + re-insert to ensure consistent state
327
+ */
328
+ export async function seedSqliteTestData() {
329
+ // Run cleanup in a single connection with FKs disabled
330
+ // getSqliteTestDb() auto-enables FKs, so we disable them first
331
+ const db = getSqliteTestDb();
332
+ try {
333
+ db.exec(`
334
+ PRAGMA foreign_keys = OFF;
335
+ DELETE FROM order_items;
336
+ DELETE FROM orders;
337
+ DELETE FROM products;
338
+ DELETE FROM users;
339
+ PRAGMA foreign_keys = ON;
340
+ `);
341
+ }
342
+ finally {
343
+ db.close();
344
+ }
345
+ // Seed users
346
+ await execSqliteSql(`
347
+ INSERT INTO users (id, email, name, age, balance, metadata, is_active) VALUES
348
+ ('11111111-1111-1111-1111-111111111111', 'alice@example.com', 'Alice Smith', 30, 1000.50, '{"role": "admin"}', 1),
349
+ ('22222222-2222-2222-2222-222222222222', 'bob@example.com', 'Bob Jones', 25, 500.00, '{"role": "user"}', 1),
350
+ ('33333333-3333-3333-3333-333333333333', 'charlie@example.com', 'Charlie Brown', 35, 0.00, null, 0)
351
+ `);
352
+ // Seed products
353
+ await execSqliteSql(`
354
+ INSERT INTO products (id, name, price, stock, category) VALUES
355
+ (1, 'Widget', 9.99, 100, 'gadgets'),
356
+ (2, 'Gadget', 19.99, 50, 'gadgets'),
357
+ (3, 'Thingamajig', 29.99, 25, 'misc')
358
+ `);
359
+ // Seed orders
360
+ await execSqliteSql(`
361
+ INSERT INTO orders (id, user_id, total, status, items) VALUES
362
+ (1, '11111111-1111-1111-1111-111111111111', 29.98, 'completed', '[{"product_id": 1, "qty": 2}]'),
363
+ (2, '11111111-1111-1111-1111-111111111111', 19.99, 'pending', '[{"product_id": 2, "qty": 1}]'),
364
+ (3, '22222222-2222-2222-2222-222222222222', 9.99, 'completed', '[{"product_id": 1, "qty": 1}]')
365
+ `);
366
+ // Seed order items
367
+ await execSqliteSql(`
368
+ INSERT INTO order_items (order_id, product_id, quantity, price_at_time) VALUES
369
+ (1, 1, 2, 9.99),
370
+ (2, 2, 1, 19.99),
371
+ (3, 1, 1, 9.99)
372
+ `);
373
+ }
374
+ /**
375
+ * Clean up SQLite test data between tests
376
+ */
377
+ export async function cleanupSqliteTestData() {
378
+ await execSqliteSql('DELETE FROM order_items');
379
+ await execSqliteSql('DELETE FROM orders');
380
+ await execSqliteSql('DELETE FROM products');
381
+ await execSqliteSql('DELETE FROM users');
382
+ }
383
+ // ============================================================================
384
+ // MySQL Test Configuration and Helpers
385
+ // ============================================================================
386
+ /**
387
+ * Create a MySQL test configuration with optional overrides
388
+ */
389
+ export function createMySqlTestConfig(overrides) {
390
+ const mysqlUrl = getMySqlUrl();
391
+ const base = {
392
+ databases: {
393
+ mysqldb: {
394
+ url: mysqlUrl,
395
+ readonly: false,
396
+ },
397
+ mysqldb_readonly: {
398
+ url: mysqlUrl,
399
+ readonly: true,
400
+ },
401
+ },
402
+ defaults: {
403
+ maxRows: 100,
404
+ maxCellLength: 500,
405
+ maxTotalSize: 65536,
406
+ maxColumns: 50,
407
+ maxTables: 200,
408
+ maxIndexes: 20,
409
+ timeout: 30000,
410
+ },
411
+ };
412
+ if (!overrides) {
413
+ return base;
414
+ }
415
+ // Handle databases override - if explicitly provided, use it directly
416
+ const databases = 'databases' in overrides
417
+ ? overrides.databases ?? base.databases
418
+ : base.databases;
419
+ // Handle defaults override - merge with base
420
+ const defaults = 'defaults' in overrides
421
+ ? { ...base.defaults, ...overrides.defaults }
422
+ : base.defaults;
423
+ return { databases, defaults };
424
+ }
425
+ /**
426
+ * Initialize the MySQL test database schema
427
+ */
428
+ export async function initializeMySqlSchema() {
429
+ // Drop existing tables in reverse FK order
430
+ // MySQL requires disabling foreign key checks to drop tables with FK dependencies
431
+ await execMySql('SET FOREIGN_KEY_CHECKS = 0');
432
+ await execMySql('DROP TABLE IF EXISTS order_items');
433
+ await execMySql('DROP TABLE IF EXISTS orders');
434
+ await execMySql('DROP TABLE IF EXISTS products');
435
+ await execMySql('DROP TABLE IF EXISTS users');
436
+ await execMySql('DROP TABLE IF EXISTS wide_table');
437
+ await execMySql('DROP VIEW IF EXISTS user_order_summary');
438
+ await execMySql('SET FOREIGN_KEY_CHECKS = 1');
439
+ // Users table with MySQL-compatible types
440
+ await execMySql(`
441
+ CREATE TABLE users (
442
+ id CHAR(36) PRIMARY KEY,
443
+ email VARCHAR(255) NOT NULL UNIQUE,
444
+ name VARCHAR(100),
445
+ age INT,
446
+ balance DECIMAL(10, 2) DEFAULT 0.00,
447
+ metadata JSON,
448
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
449
+ updated_at TIMESTAMP NULL,
450
+ is_active BOOLEAN DEFAULT TRUE
451
+ )
452
+ `);
453
+ // Create indexes for testing
454
+ await execMySql('CREATE INDEX users_created_at_idx ON users(created_at)');
455
+ await execMySql('CREATE INDEX users_name_email_idx ON users(name, email)');
456
+ // Products table
457
+ await execMySql(`
458
+ CREATE TABLE products (
459
+ id INT AUTO_INCREMENT PRIMARY KEY,
460
+ name VARCHAR(255) NOT NULL,
461
+ price DECIMAL(10, 2) NOT NULL,
462
+ stock INT DEFAULT 0,
463
+ category VARCHAR(100)
464
+ )
465
+ `);
466
+ // Orders table with foreign key
467
+ await execMySql(`
468
+ CREATE TABLE orders (
469
+ id INT AUTO_INCREMENT PRIMARY KEY,
470
+ user_id CHAR(36) NOT NULL,
471
+ total DECIMAL(10, 2) NOT NULL,
472
+ status VARCHAR(50) DEFAULT 'pending',
473
+ items JSON NOT NULL,
474
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
475
+ CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
476
+ )
477
+ `);
478
+ await execMySql('CREATE INDEX orders_user_id_idx ON orders(user_id)');
479
+ await execMySql('CREATE INDEX orders_status_idx ON orders(status)');
480
+ // Order items junction table
481
+ await execMySql(`
482
+ CREATE TABLE order_items (
483
+ order_id INT NOT NULL,
484
+ product_id INT NOT NULL,
485
+ quantity INT NOT NULL DEFAULT 1,
486
+ price_at_time DECIMAL(10, 2) NOT NULL,
487
+ PRIMARY KEY (order_id, product_id),
488
+ CONSTRAINT fk_order_items_order FOREIGN KEY (order_id) REFERENCES orders(id),
489
+ CONSTRAINT fk_order_items_product FOREIGN KEY (product_id) REFERENCES products(id)
490
+ )
491
+ `);
492
+ // View for testing view detection
493
+ await execMySql(`
494
+ CREATE VIEW user_order_summary AS
495
+ SELECT
496
+ u.id as user_id,
497
+ u.email,
498
+ COUNT(o.id) as order_count,
499
+ COALESCE(SUM(o.total), 0) as total_spent
500
+ FROM users u
501
+ LEFT JOIN orders o ON u.id = o.user_id
502
+ GROUP BY u.id, u.email
503
+ `);
504
+ // Wide table for truncation testing
505
+ const wideCols = Array.from({ length: 55 }, (_, i) => `col_${String(i + 1).padStart(2, '0')} TEXT`).join(', ');
506
+ await execMySql(`
507
+ CREATE TABLE wide_table (
508
+ id INT AUTO_INCREMENT PRIMARY KEY,
509
+ ${wideCols}
510
+ )
511
+ `);
512
+ }
513
+ /**
514
+ * Seed the MySQL test database with sample data
515
+ * Uses TRUNCATE for fast cleanup then re-insert
516
+ */
517
+ export async function seedMySqlTestData() {
518
+ // Use execMySqlBatch for atomic cleanup with FK checks disabled
519
+ await execMySqlBatch([
520
+ 'SET FOREIGN_KEY_CHECKS = 0',
521
+ 'TRUNCATE TABLE order_items',
522
+ 'TRUNCATE TABLE orders',
523
+ 'TRUNCATE TABLE products',
524
+ 'TRUNCATE TABLE users',
525
+ 'SET FOREIGN_KEY_CHECKS = 1',
526
+ ]);
527
+ // Seed data in correct order (respecting FK constraints)
528
+ await execMySql(`
529
+ INSERT INTO users (id, email, name, age, balance, metadata, is_active) VALUES
530
+ ('11111111-1111-1111-1111-111111111111', 'alice@example.com', 'Alice Smith', 30, 1000.50, '{"role": "admin"}', TRUE),
531
+ ('22222222-2222-2222-2222-222222222222', 'bob@example.com', 'Bob Jones', 25, 500.00, '{"role": "user"}', TRUE),
532
+ ('33333333-3333-3333-3333-333333333333', 'charlie@example.com', 'Charlie Brown', 35, 0.00, NULL, FALSE)
533
+ `);
534
+ await execMySql(`
535
+ INSERT INTO products (id, name, price, stock, category) VALUES
536
+ (1, 'Widget', 9.99, 100, 'gadgets'),
537
+ (2, 'Gadget', 19.99, 50, 'gadgets'),
538
+ (3, 'Thingamajig', 29.99, 25, 'misc')
539
+ `);
540
+ await execMySql(`
541
+ INSERT INTO orders (id, user_id, total, status, items) VALUES
542
+ (1, '11111111-1111-1111-1111-111111111111', 29.98, 'completed', '[{"product_id": 1, "qty": 2}]'),
543
+ (2, '11111111-1111-1111-1111-111111111111', 19.99, 'pending', '[{"product_id": 2, "qty": 1}]'),
544
+ (3, '22222222-2222-2222-2222-222222222222', 9.99, 'completed', '[{"product_id": 1, "qty": 1}]')
545
+ `);
546
+ await execMySql(`
547
+ INSERT INTO order_items (order_id, product_id, quantity, price_at_time) VALUES
548
+ (1, 1, 2, 9.99),
549
+ (2, 2, 1, 19.99),
550
+ (3, 1, 1, 9.99)
551
+ `);
552
+ // Update table statistics for row estimates
553
+ await execMySql('ANALYZE TABLE users, products, orders, order_items');
554
+ }
555
+ /**
556
+ * Clean up MySQL test data between tests
557
+ */
558
+ export async function cleanupMySqlTestData() {
559
+ await execMySqlBatch([
560
+ 'SET FOREIGN_KEY_CHECKS = 0',
561
+ 'TRUNCATE TABLE order_items',
562
+ 'TRUNCATE TABLE orders',
563
+ 'TRUNCATE TABLE products',
564
+ 'TRUNCATE TABLE users',
565
+ 'SET FOREIGN_KEY_CHECKS = 1',
566
+ ]);
567
+ }
568
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/__integration__/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Integration test setup utilities
3
+ *
4
+ * Manages PostgreSQL and MySQL Docker containers using Testcontainers, and SQLite file database for integration tests.
5
+ */
6
+ import pg from 'pg';
7
+ import * as mysql from 'mysql2/promise';
8
+ import Database from 'better-sqlite3';
9
+ declare const TEST_SQLITE_DB_PATH = "./test-data/test.db";
10
+ /**
11
+ * Start the test containers (PostgreSQL and MySQL) using Testcontainers
12
+ */
13
+ export declare function startContainers(): Promise<void>;
14
+ /**
15
+ * Start the test PostgreSQL container (backward compatibility)
16
+ */
17
+ export declare function startPostgres(): Promise<void>;
18
+ /**
19
+ * Stop the test containers
20
+ */
21
+ export declare function stopContainers(): Promise<void>;
22
+ /**
23
+ * Stop the test PostgreSQL container (backward compatibility)
24
+ */
25
+ export declare function stopPostgres(): Promise<void>;
26
+ /**
27
+ * Get the PostgreSQL connection URL (set after containers start)
28
+ */
29
+ export declare function getPostgresUrl(): string;
30
+ /**
31
+ * Get the MySQL connection URL (set after containers start)
32
+ */
33
+ export declare function getMySqlUrl(): string;
34
+ /**
35
+ * Get a direct PostgreSQL database client for test verification
36
+ */
37
+ export declare function getTestClient(): Promise<pg.Client>;
38
+ /**
39
+ * Execute SQL directly for test setup/verification (PostgreSQL)
40
+ */
41
+ export declare function execSql(sql: string, params?: unknown[]): Promise<pg.QueryResult>;
42
+ /**
43
+ * Get a direct MySQL database connection for test verification
44
+ */
45
+ export declare function getMySqlTestConnection(): Promise<mysql.Connection>;
46
+ /**
47
+ * Execute SQL directly for test setup/verification (MySQL)
48
+ */
49
+ export declare function execMySql(sql: string, params?: unknown[]): Promise<mysql.QueryResult>;
50
+ /**
51
+ * Execute multiple SQL statements in a single connection (MySQL)
52
+ * Useful when session state needs to persist (e.g., FOREIGN_KEY_CHECKS)
53
+ */
54
+ export declare function execMySqlBatch(statements: string[]): Promise<void>;
55
+ /**
56
+ * Create the SQLite test database directory and file
57
+ */
58
+ export declare function createSqliteTestDb(): void;
59
+ /**
60
+ * Delete the SQLite test database file
61
+ */
62
+ export declare function deleteSqliteTestDb(): void;
63
+ /**
64
+ * Get a SQLite database connection for test setup/verification
65
+ */
66
+ export declare function getSqliteTestDb(): Database.Database;
67
+ /**
68
+ * Execute SQL directly for test setup/verification (SQLite)
69
+ */
70
+ export declare function execSqliteSql(sql: string): Promise<void>;
71
+ /**
72
+ * Execute a query and return results (SQLite)
73
+ */
74
+ export declare function querySqliteSql(sql: string): Promise<unknown[]>;
75
+ /**
76
+ * Export SQLite path for use in helpers
77
+ */
78
+ export { TEST_SQLITE_DB_PATH };
79
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__integration__/setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,QAAA,MAAM,mBAAmB,wBAAwB,CAAC;AAUlD;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAgCrD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAcpD;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAElD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAOpC;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAIxD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,CAOtF;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAExE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAQ3F;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CASxE;AAOD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAiBzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAgBzC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,QAAQ,CAAC,QAAQ,CAKnD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAOpE;AAED;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,CAAC"}