@an5/adapters 0.2.5 → 0.2.9

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 (99) hide show
  1. package/README.md +283 -305
  2. package/dist/an5Adapter.d.ts +142 -7
  3. package/dist/an5Adapter.js +998 -68
  4. package/dist/base/metadata.d.ts +10 -0
  5. package/dist/base/metadata.js +107 -0
  6. package/dist/base/sql.d.ts +19 -1
  7. package/dist/base/sql.js +152 -24
  8. package/dist/base/types.d.ts +10 -1
  9. package/dist/browser.d.ts +4 -1
  10. package/dist/browser.js +9 -2
  11. package/dist/googlesheets/adapter.d.ts +1 -0
  12. package/dist/googlesheets/adapter.js +9 -2
  13. package/dist/googlesheets/config.d.ts +4 -4
  14. package/dist/googlesheets/helpers.js +2 -0
  15. package/dist/googlesheets/parseConnectionString.js +5 -2
  16. package/dist/googlesheets/sqlExecutor.js +29 -24
  17. package/dist/googlesheets/tableClient.js +14 -5
  18. package/dist/index.d.ts +5 -1
  19. package/dist/index.js +15 -1
  20. package/dist/mssql/engine.js +8 -4
  21. package/dist/mysql/engine.js +1 -1
  22. package/dist/nbase/client.d.ts +92 -0
  23. package/dist/nbase/client.js +147 -0
  24. package/dist/nbase/index.d.ts +47 -0
  25. package/dist/nbase/index.js +80 -0
  26. package/dist/postgres/engine.js +1 -1
  27. package/dist/sqlite/browserEngine.d.ts +27 -0
  28. package/dist/sqlite/browserEngine.js +161 -0
  29. package/dist/sqlite/engine.js +15 -3
  30. package/dist/sqlite/index.d.ts +1 -0
  31. package/dist/sqlite/index.js +1 -0
  32. package/dist/typed.d.ts +5 -0
  33. package/dist/typed.js +2 -0
  34. package/dotnet/An5Adapter.cs +1112 -275
  35. package/dotnet/Base/Core.cs +380 -82
  36. package/dotnet/Mssql/MssqlEngine.cs +145 -144
  37. package/dotnet/Postgres/PostgresEngine.cs +149 -121
  38. package/dotnet/Sqlite/SqliteEngine.cs +214 -0
  39. package/golang/an5_adapter.go +314 -0
  40. package/golang/base/base.go +100 -0
  41. package/golang/base/metadata.go +116 -0
  42. package/golang/base/where.go +311 -0
  43. package/golang/go.mod +3 -0
  44. package/golang/mssql/mssql.go +32 -0
  45. package/golang/postgres/postgres.go +37 -0
  46. package/golang/sqlite/sqlite.go +14 -0
  47. package/golang/sqlite_test.go +42 -0
  48. package/golang/table_client.go +1329 -0
  49. package/package.json +26 -9
  50. package/python/an5_adapter.py +184 -97
  51. package/python/base/__init__.py +3 -3
  52. package/python/base/dialects.py +11 -8
  53. package/python/base/metadata.py +59 -10
  54. package/python/base/sql.py +202 -121
  55. package/python/mssql/__init__.py +1 -1
  56. package/python/mssql/provider.py +62 -62
  57. package/python/postgres/__init__.py +1 -1
  58. package/python/postgres/provider.py +15 -15
  59. package/python/sqlite/__init__.py +3 -0
  60. package/python/sqlite/provider.py +83 -0
  61. package/python/table_client.py +636 -216
  62. package/rust/Cargo.toml +31 -0
  63. package/rust/README.md +71 -0
  64. package/rust/src/adapter.rs +1312 -0
  65. package/rust/src/base/dialect.rs +172 -0
  66. package/rust/src/base/metadata.rs +134 -0
  67. package/rust/src/base/mod.rs +17 -0
  68. package/rust/src/base/where_builder.rs +405 -0
  69. package/rust/src/lib.rs +75 -0
  70. package/typescript/src/an5Adapter.ts +1515 -505
  71. package/typescript/src/base/index.ts +3 -3
  72. package/typescript/src/base/metadata.ts +148 -28
  73. package/typescript/src/base/sql.ts +264 -98
  74. package/typescript/src/base/types.ts +33 -24
  75. package/typescript/src/browser.ts +10 -6
  76. package/typescript/src/config.ts +95 -95
  77. package/typescript/src/googlesheets/adapter.ts +269 -259
  78. package/typescript/src/googlesheets/an5SheetsAdapter.ts +3 -3
  79. package/typescript/src/googlesheets/config.ts +47 -47
  80. package/typescript/src/googlesheets/helpers.ts +144 -143
  81. package/typescript/src/googlesheets/index.ts +3 -3
  82. package/typescript/src/googlesheets/parseConnectionString.ts +48 -46
  83. package/typescript/src/googlesheets/retry.ts +126 -126
  84. package/typescript/src/googlesheets/sqlExecutor.ts +304 -301
  85. package/typescript/src/googlesheets/tableClient.ts +461 -455
  86. package/typescript/src/googlesheets/types.ts +6 -6
  87. package/typescript/src/index.ts +48 -27
  88. package/typescript/src/mssql/engine.ts +134 -132
  89. package/typescript/src/mssql/index.ts +1 -1
  90. package/typescript/src/mysql/engine.ts +80 -80
  91. package/typescript/src/mysql/index.ts +1 -1
  92. package/typescript/src/nbase/client.ts +214 -0
  93. package/typescript/src/nbase/index.ts +104 -0
  94. package/typescript/src/postgres/engine.ts +87 -87
  95. package/typescript/src/postgres/index.ts +1 -1
  96. package/typescript/src/sqlite/browserEngine.ts +192 -0
  97. package/typescript/src/sqlite/engine.ts +66 -55
  98. package/typescript/src/sqlite/index.ts +3 -1
  99. package/typescript/src/typed.ts +52 -0
@@ -1,6 +1,6 @@
1
- // ─── Cache ────────────────────────────────────────────────────────────────────
2
-
3
- export interface SheetMeta {
4
- sheetId: number;
5
- title: string;
6
- }
1
+ // ─── Cache ────────────────────────────────────────────────────────────────────
2
+
3
+ export interface SheetMeta {
4
+ sheetId: number;
5
+ title: string;
6
+ }
@@ -1,28 +1,49 @@
1
- export {
2
- An5Adapter,
3
- AdapterTableClient,
4
- createAn5Adapter,
5
- setAdapterMetadata,
6
- } from './an5Adapter';
7
- export type {
8
- An5AdapterConfig,
9
- AdapterMetadata,
10
- Dialect,
11
- } from './an5Adapter';
12
- export {
13
- getLlmConfig, setLlmConfig,
14
- getEmbeddingConfig, setEmbeddingConfig,
15
- resetAdapter,
16
- } from './config';
17
- export type {
18
- LlmConfigData, EmbeddingConfigData,
19
- } from './config';
20
- export {
21
- An5SheetsAdapter,
22
- SheetsTableClient,
23
- createAn5SheetsAdapter,
24
- parseSheetsConnectionString,
25
- } from './googlesheets';
26
- export type {
27
- An5SheetsAdapterConfig,
1
+ export {
2
+ An5Adapter,
3
+ AdapterTableClient,
4
+ createAn5Adapter,
5
+ createAdapterProxy,
6
+ executorFromAdapter,
7
+ setAdapterMetadata,
8
+ } from './an5Adapter';
9
+ export { parseWhere, buildOrderBy, quote } from './base/sql';
10
+ export {
11
+ NBaseVectorClient,
12
+ NBaseError,
13
+ createNBaseVectorClient,
14
+ createNBaseClient,
15
+ parseNBaseConnectionString,
16
+ buildVectorId,
17
+ parseVectorId,
18
+ } from './nbase';
19
+ export type {
20
+ NBaseAdapterConfig,
21
+ NBaseClientConfig,
22
+ NBaseVector,
23
+ NBaseSearchOptions,
24
+ NBaseSearchResult,
25
+ NBaseStats,
26
+ } from './nbase';
27
+ export type {
28
+ An5AdapterConfig,
29
+ AdapterMetadata,
30
+ Dialect,
31
+ } from './an5Adapter';
32
+ export type { TypedAn5Adapter, AdapterAPI } from './typed';
33
+ export {
34
+ getLlmConfig, setLlmConfig,
35
+ getEmbeddingConfig, setEmbeddingConfig,
36
+ resetAdapter,
37
+ } from './config';
38
+ export type {
39
+ LlmConfigData, EmbeddingConfigData,
40
+ } from './config';
41
+ export {
42
+ An5SheetsAdapter,
43
+ SheetsTableClient,
44
+ createAn5SheetsAdapter,
45
+ parseSheetsConnectionString,
46
+ } from './googlesheets';
47
+ export type {
48
+ An5SheetsAdapterConfig,
28
49
  } from './googlesheets';
@@ -1,132 +1,134 @@
1
- import sql from 'mssql';
2
- import type { An5AdapterConfig, Dialect, QueryEngine, TransactionHandle } from '../base/types';
3
-
4
- // ─── MSSQL Connection Config ───────────────────────────────────────────────────────
5
-
6
- export function parseMssqlConnectionString(url: string): sql.config {
7
- let cleanUrl = (url || '').trim();
8
- // Strip scheme prefix
9
- cleanUrl = cleanUrl.replace(/^(?:sqlserver|mssql):\/\//i, '');
10
-
11
- const parts = cleanUrl.split(';');
12
- const firstPart = parts[0].trim();
13
-
14
- // host:port or host,port (SQL Server native style)
15
- let server = firstPart;
16
- let port = 1433;
17
- const commaIdx = firstPart.lastIndexOf(',');
18
- const colonIdx = firstPart.lastIndexOf(':');
19
- if (commaIdx !== -1) {
20
- server = firstPart.slice(0, commaIdx).trim();
21
- port = parseInt(firstPart.slice(commaIdx + 1), 10) || 1433;
22
- } else if (colonIdx !== -1 && !firstPart.includes('=')) {
23
- server = firstPart.slice(0, colonIdx).trim();
24
- port = parseInt(firstPart.slice(colonIdx + 1), 10) || 1433;
25
- }
26
-
27
- const config: any = {
28
- server,
29
- port,
30
- options: { encrypt: true, trustServerCertificate: true },
31
- pool: { max: 10, min: 0, idleTimeoutMillis: 30000 },
32
- requestTimeout: 60000,
33
- connectionTimeout: 15000,
34
- };
35
-
36
- for (let i = 1; i < parts.length; i++) {
37
- const part = parts[i].trim();
38
- if (!part) continue;
39
- const eqIdx = part.indexOf('=');
40
- if (eqIdx === -1) continue;
41
- const key = part.slice(0, eqIdx).trim().toLowerCase();
42
- const value = decodeURIComponent(part.slice(eqIdx + 1).trim());
43
- if (key === 'database' || key === 'initial catalog') config.database = value;
44
- else if (key === 'user' || key === 'uid' || key === 'user id') config.user = value;
45
- else if (key === 'password' || key === 'pwd') config.password = value;
46
- else if (key === 'server' || key === 'data source') {
47
- // SERVER=host,port style (key-value form)
48
- const [s, p] = value.split(',');
49
- config.server = s.trim();
50
- if (p) config.port = parseInt(p.trim(), 10) || 1433;
51
- }
52
- else if (key === 'encrypt') config.options.encrypt = value.toLowerCase() === 'true';
53
- else if (key === 'trustservercertificate') config.options.trustServerCertificate = value.toLowerCase() === 'true';
54
- else if (key === 'connection timeout') config.connectionTimeout = parseInt(value, 10) * 1000;
55
- }
56
- return config;
57
- }
58
-
59
- // ─── MSSQL Engine ──────────────────────────────────────────────────────────────────
60
-
61
- export class MssqlEngine implements QueryEngine {
62
- dialect: Dialect = 'mssql';
63
- private pool: Promise<sql.ConnectionPool> | null = null;
64
- private config: sql.config;
65
-
66
- constructor(adapterConfig: An5AdapterConfig) {
67
- this.config = parseMssqlConnectionString(adapterConfig.connectionString);
68
- if (adapterConfig.poolMax) this.config.pool = { ...this.config.pool, max: adapterConfig.poolMax };
69
- if (adapterConfig.requestTimeout) this.config.requestTimeout = adapterConfig.requestTimeout;
70
- if (adapterConfig.connectionTimeout) this.config.connectionTimeout = adapterConfig.connectionTimeout;
71
- }
72
-
73
- private async getPool(): Promise<sql.ConnectionPool> {
74
- if (!this.pool) this.pool = new sql.ConnectionPool(this.config).connect();
75
- return this.pool;
76
- }
77
-
78
- private attachParams(req: sql.Request, params?: Record<string, any>): void {
79
- if (params) for (const [k, v] of Object.entries(params)) req.input(k, v ?? null);
80
- }
81
-
82
- async exec<T = any>(query: string, params?: Record<string, any>): Promise<T[]> {
83
- const pool = await this.getPool();
84
- const req = new sql.Request(pool);
85
- this.attachParams(req, params);
86
- const result = await req.query(query);
87
- return (result.recordset || []) as T[];
88
- }
89
-
90
- async executeRaw(query: string, params?: Record<string, any>): Promise<number> {
91
- const pool = await this.getPool();
92
- const req = new sql.Request(pool);
93
- this.attachParams(req, params);
94
- const result = await req.query(query);
95
- return result.rowsAffected[0] ?? 0;
96
- }
97
-
98
- async connect(): Promise<void> { await this.getPool(); }
99
-
100
- async disconnect(): Promise<void> {
101
- if (this.pool) {
102
- const p = await this.pool;
103
- await p.close();
104
- this.pool = null;
105
- }
106
- }
107
-
108
- async beginTransaction(): Promise<TransactionHandle> {
109
- const pool = await this.getPool();
110
- const tx = new sql.Transaction(pool);
111
- await tx.begin();
112
-
113
- const buildReq = (params?: Record<string, any>) => {
114
- const req = new sql.Request(tx);
115
- if (params) for (const [k, v] of Object.entries(params)) req.input(k, v ?? null);
116
- return req;
117
- };
118
-
119
- return {
120
- exec: async <T>(q: string, p?: Record<string, any>) => {
121
- const r = await buildReq(p).query(q);
122
- return (r.recordset || []) as T[];
123
- },
124
- executeRaw: async (q: string, p?: Record<string, any>) => {
125
- const r = await buildReq(p).query(q);
126
- return r.rowsAffected[0] ?? 0;
127
- },
128
- commit: () => tx.commit(),
129
- rollback: () => tx.rollback(),
130
- };
131
- }
132
- }
1
+ import sql from 'mssql';
2
+ import type { An5AdapterConfig, Dialect, QueryEngine, TransactionHandle } from '../base/types';
3
+
4
+ // ─── MSSQL Connection Config ───────────────────────────────────────────────────────
5
+
6
+ export function parseMssqlConnectionString(url: string): sql.config {
7
+ let cleanUrl = (url || '').trim();
8
+ // Strip scheme prefix
9
+ cleanUrl = cleanUrl.replace(/^(?:sqlserver|mssql):\/\//i, '');
10
+
11
+ const parts = cleanUrl.split(';');
12
+ const firstPart = (parts[0] ?? '').trim();
13
+
14
+ // host:port or host,port (SQL Server native style)
15
+ let server = firstPart;
16
+ let port = 1433;
17
+ const commaIdx = firstPart.lastIndexOf(',');
18
+ const colonIdx = firstPart.lastIndexOf(':');
19
+ if (commaIdx !== -1) {
20
+ server = firstPart.slice(0, commaIdx).trim();
21
+ port = parseInt(firstPart.slice(commaIdx + 1), 10) || 1433;
22
+ } else if (colonIdx !== -1 && !firstPart.includes('=')) {
23
+ server = firstPart.slice(0, colonIdx).trim();
24
+ port = parseInt(firstPart.slice(colonIdx + 1), 10) || 1433;
25
+ }
26
+
27
+ const config: any = {
28
+ server,
29
+ port,
30
+ options: { encrypt: true, trustServerCertificate: true },
31
+ pool: { max: 10, min: 0, idleTimeoutMillis: 30000 },
32
+ requestTimeout: 60000,
33
+ connectionTimeout: 15000,
34
+ };
35
+
36
+ for (let i = 1; i < parts.length; i++) {
37
+ const rawPart = parts[i];
38
+ if (rawPart === undefined) continue;
39
+ const part = rawPart.trim();
40
+ if (!part) continue;
41
+ const eqIdx = part.indexOf('=');
42
+ if (eqIdx === -1) continue;
43
+ const key = part.slice(0, eqIdx).trim().toLowerCase();
44
+ const value = decodeURIComponent(part.slice(eqIdx + 1).trim());
45
+ if (key === 'database' || key === 'initial catalog') config.database = value;
46
+ else if (key === 'user' || key === 'uid' || key === 'user id') config.user = value;
47
+ else if (key === 'password' || key === 'pwd') config.password = value;
48
+ else if (key === 'server' || key === 'data source') {
49
+ // SERVER=host,port style (key-value form)
50
+ const [s, p] = value.split(',');
51
+ if (s !== undefined) config.server = s.trim();
52
+ if (p) config.port = parseInt(p.trim(), 10) || 1433;
53
+ }
54
+ else if (key === 'encrypt') config.options.encrypt = value.toLowerCase() === 'true';
55
+ else if (key === 'trustservercertificate') config.options.trustServerCertificate = value.toLowerCase() === 'true';
56
+ else if (key === 'connection timeout') config.connectionTimeout = parseInt(value, 10) * 1000;
57
+ }
58
+ return config;
59
+ }
60
+
61
+ // ─── MSSQL Engine ──────────────────────────────────────────────────────────────────
62
+
63
+ export class MssqlEngine implements QueryEngine {
64
+ dialect: Dialect = 'mssql';
65
+ private pool: Promise<sql.ConnectionPool> | null = null;
66
+ private config: sql.config;
67
+
68
+ constructor(adapterConfig: An5AdapterConfig) {
69
+ this.config = parseMssqlConnectionString(adapterConfig.connectionString ?? '');
70
+ if (adapterConfig.poolMax) this.config.pool = { ...this.config.pool, max: adapterConfig.poolMax };
71
+ if (adapterConfig.requestTimeout) this.config.requestTimeout = adapterConfig.requestTimeout;
72
+ if (adapterConfig.connectionTimeout) this.config.connectionTimeout = adapterConfig.connectionTimeout;
73
+ }
74
+
75
+ private async getPool(): Promise<sql.ConnectionPool> {
76
+ if (!this.pool) this.pool = new sql.ConnectionPool(this.config).connect();
77
+ return this.pool;
78
+ }
79
+
80
+ private attachParams(req: sql.Request, params?: Record<string, any>): void {
81
+ if (params) for (const [k, v] of Object.entries(params)) req.input(k, v ?? null);
82
+ }
83
+
84
+ async exec<T = any>(query: string, params?: Record<string, any>): Promise<T[]> {
85
+ const pool = await this.getPool();
86
+ const req = new sql.Request(pool);
87
+ this.attachParams(req, params);
88
+ const result = await req.query(query);
89
+ return (result.recordset || []) as T[];
90
+ }
91
+
92
+ async executeRaw(query: string, params?: Record<string, any>): Promise<number> {
93
+ const pool = await this.getPool();
94
+ const req = new sql.Request(pool);
95
+ this.attachParams(req, params);
96
+ const result = await req.query(query);
97
+ return result.rowsAffected[0] ?? 0;
98
+ }
99
+
100
+ async connect(): Promise<void> { await this.getPool(); }
101
+
102
+ async disconnect(): Promise<void> {
103
+ if (this.pool) {
104
+ const p = await this.pool;
105
+ await p.close();
106
+ this.pool = null;
107
+ }
108
+ }
109
+
110
+ async beginTransaction(): Promise<TransactionHandle> {
111
+ const pool = await this.getPool();
112
+ const tx = new sql.Transaction(pool);
113
+ await tx.begin();
114
+
115
+ const buildReq = (params?: Record<string, any>) => {
116
+ const req = new sql.Request(tx);
117
+ if (params) for (const [k, v] of Object.entries(params)) req.input(k, v ?? null);
118
+ return req;
119
+ };
120
+
121
+ return {
122
+ exec: async <T>(q: string, p?: Record<string, any>) => {
123
+ const r = await buildReq(p).query(q);
124
+ return (r.recordset || []) as T[];
125
+ },
126
+ executeRaw: async (q: string, p?: Record<string, any>) => {
127
+ const r = await buildReq(p).query(q);
128
+ return r.rowsAffected[0] ?? 0;
129
+ },
130
+ commit: () => tx.commit(),
131
+ rollback: () => tx.rollback(),
132
+ };
133
+ }
134
+ }
@@ -1 +1 @@
1
- export * from './engine';
1
+ export * from './engine';
@@ -1,80 +1,80 @@
1
- import type { An5AdapterConfig, Dialect, QueryEngine, TransactionHandle } from '../base/types';
2
-
3
- // ─── MySQL Engine ──────────────────────────────────────────────────────────────────
4
-
5
- let Mysql2: any = null;
6
- try { Mysql2 = require('mysql2/promise'); } catch { }
7
-
8
- export class MysqlEngine implements QueryEngine {
9
- dialect: Dialect = 'mysql';
10
- private pool: any = null;
11
-
12
- constructor(adapterConfig: An5AdapterConfig) {
13
- if (!Mysql2) throw new Error('mysql2 package is required for MySQL support. Run: npm install mysql2');
14
- this.pool = Mysql2.createPool({
15
- uri: adapterConfig.connectionString,
16
- connectionLimit: adapterConfig.poolMax ?? 10,
17
- connectTimeout: adapterConfig.connectionTimeout ?? 15000,
18
- });
19
- }
20
-
21
- /** Convert @name → ? (positional); return ordered values */
22
- private transform(query: string, params?: Record<string, any>): { text: string; values: any[] } {
23
- if (!params || Object.keys(params).length === 0) return { text: query, values: [] };
24
- const values: any[] = [];
25
- const text = query.replace(/@(\w+)/g, (_, name: string) => {
26
- values.push(params[name] ?? null);
27
- return '?';
28
- });
29
- return { text, values };
30
- }
31
-
32
- async exec<T = any>(query: string, params?: Record<string, any>): Promise<T[]> {
33
- const { text, values } = this.transform(query, params);
34
- const [rows] = await this.pool.query(text, values);
35
- return rows as T[];
36
- }
37
-
38
- async executeRaw(query: string, params?: Record<string, any>): Promise<number> {
39
- const { text, values } = this.transform(query, params);
40
- const [result] = await this.pool.query(text, values);
41
- return (result as any).affectedRows ?? 0;
42
- }
43
-
44
- async connect(): Promise<void> {
45
- const conn = await this.pool.getConnection();
46
- conn.release();
47
- }
48
-
49
- async disconnect(): Promise<void> { await this.pool.end(); }
50
-
51
- async beginTransaction(): Promise<TransactionHandle> {
52
- const conn = await this.pool.getConnection();
53
- await conn.beginTransaction();
54
-
55
- const transform = (query: string, params?: Record<string, any>) => {
56
- if (!params || Object.keys(params).length === 0) return { text: query, values: [] };
57
- const values: any[] = [];
58
- const text = query.replace(/@(\w+)/g, (_, name: string) => {
59
- values.push(params[name] ?? null);
60
- return '?';
61
- });
62
- return { text, values };
63
- };
64
-
65
- return {
66
- exec: async <T>(q: string, p?: Record<string, any>) => {
67
- const { text, values } = transform(q, p);
68
- const [rows] = await conn.query(text, values);
69
- return rows as T[];
70
- },
71
- executeRaw: async (q: string, p?: Record<string, any>) => {
72
- const { text, values } = transform(q, p);
73
- const [result] = await conn.query(text, values);
74
- return (result as any).affectedRows ?? 0;
75
- },
76
- commit: async () => { await conn.commit(); conn.release(); },
77
- rollback: async () => { await conn.rollback(); conn.release(); },
78
- };
79
- }
80
- }
1
+ import type { An5AdapterConfig, Dialect, QueryEngine, TransactionHandle } from '../base/types';
2
+
3
+ // ─── MySQL Engine ──────────────────────────────────────────────────────────────────
4
+
5
+ let Mysql2: any = null;
6
+ try { Mysql2 = require('mysql2/promise'); } catch { }
7
+
8
+ export class MysqlEngine implements QueryEngine {
9
+ dialect: Dialect = 'mysql';
10
+ private pool: any = null;
11
+
12
+ constructor(adapterConfig: An5AdapterConfig) {
13
+ if (!Mysql2) throw new Error('mysql2 package is required for MySQL support. Run: npm install mysql2');
14
+ this.pool = Mysql2.createPool({
15
+ uri: adapterConfig.connectionString ?? '',
16
+ connectionLimit: adapterConfig.poolMax ?? 10,
17
+ connectTimeout: adapterConfig.connectionTimeout ?? 15000,
18
+ });
19
+ }
20
+
21
+ /** Convert @name → ? (positional); return ordered values */
22
+ private transform(query: string, params?: Record<string, any>): { text: string; values: any[] } {
23
+ if (!params || Object.keys(params).length === 0) return { text: query, values: [] };
24
+ const values: any[] = [];
25
+ const text = query.replace(/@(\w+)/g, (_, name: string) => {
26
+ values.push(params[name] ?? null);
27
+ return '?';
28
+ });
29
+ return { text, values };
30
+ }
31
+
32
+ async exec<T = any>(query: string, params?: Record<string, any>): Promise<T[]> {
33
+ const { text, values } = this.transform(query, params);
34
+ const [rows] = await this.pool.query(text, values);
35
+ return rows as T[];
36
+ }
37
+
38
+ async executeRaw(query: string, params?: Record<string, any>): Promise<number> {
39
+ const { text, values } = this.transform(query, params);
40
+ const [result] = await this.pool.query(text, values);
41
+ return (result as any).affectedRows ?? 0;
42
+ }
43
+
44
+ async connect(): Promise<void> {
45
+ const conn = await this.pool.getConnection();
46
+ conn.release();
47
+ }
48
+
49
+ async disconnect(): Promise<void> { await this.pool.end(); }
50
+
51
+ async beginTransaction(): Promise<TransactionHandle> {
52
+ const conn = await this.pool.getConnection();
53
+ await conn.beginTransaction();
54
+
55
+ const transform = (query: string, params?: Record<string, any>) => {
56
+ if (!params || Object.keys(params).length === 0) return { text: query, values: [] };
57
+ const values: any[] = [];
58
+ const text = query.replace(/@(\w+)/g, (_, name: string) => {
59
+ values.push(params[name] ?? null);
60
+ return '?';
61
+ });
62
+ return { text, values };
63
+ };
64
+
65
+ return {
66
+ exec: async <T>(q: string, p?: Record<string, any>) => {
67
+ const { text, values } = transform(q, p);
68
+ const [rows] = await conn.query(text, values);
69
+ return rows as T[];
70
+ },
71
+ executeRaw: async (q: string, p?: Record<string, any>) => {
72
+ const { text, values } = transform(q, p);
73
+ const [result] = await conn.query(text, values);
74
+ return (result as any).affectedRows ?? 0;
75
+ },
76
+ commit: async () => { await conn.commit(); conn.release(); },
77
+ rollback: async () => { await conn.rollback(); conn.release(); },
78
+ };
79
+ }
80
+ }
@@ -1 +1 @@
1
- export * from './engine';
1
+ export * from './engine';