@hedystia/db 2.0.0 → 2.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 (146) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +13 -0
  2. package/dist/_virtual/_rolldown/runtime.mjs +17 -0
  3. package/dist/cache/manager.cjs +137 -0
  4. package/dist/cache/manager.cjs.map +1 -0
  5. package/dist/cache/manager.d.cts +72 -0
  6. package/dist/cache/manager.d.mts +72 -0
  7. package/dist/cache/manager.mjs +140 -0
  8. package/dist/cache/manager.mjs.map +1 -0
  9. package/dist/cache/memory-store.cjs +122 -0
  10. package/dist/cache/memory-store.cjs.map +1 -0
  11. package/dist/cache/memory-store.mjs +122 -0
  12. package/dist/cache/memory-store.mjs.map +1 -0
  13. package/dist/cli/commands/migration.cjs +22 -0
  14. package/dist/cli/commands/migration.cjs.map +1 -0
  15. package/dist/cli/commands/migration.mjs +32 -0
  16. package/dist/cli/commands/migration.mjs.map +1 -0
  17. package/dist/cli/commands/schema.cjs +21 -0
  18. package/dist/cli/commands/schema.cjs.map +1 -0
  19. package/dist/cli/commands/schema.mjs +30 -0
  20. package/dist/cli/commands/schema.mjs.map +1 -0
  21. package/dist/cli.cjs +50 -0
  22. package/dist/cli.cjs.map +1 -0
  23. package/dist/cli.d.cts +1 -0
  24. package/dist/cli.d.mts +1 -0
  25. package/dist/cli.mjs +57 -0
  26. package/dist/cli.mjs.map +1 -0
  27. package/dist/constants.cjs +16 -0
  28. package/dist/constants.cjs.map +1 -0
  29. package/dist/constants.mjs +16 -0
  30. package/dist/constants.mjs.map +1 -0
  31. package/dist/core/database.cjs +158 -0
  32. package/dist/core/database.cjs.map +1 -0
  33. package/dist/core/database.d.cts +74 -0
  34. package/dist/core/database.d.mts +74 -0
  35. package/dist/core/database.mjs +159 -0
  36. package/dist/core/database.mjs.map +1 -0
  37. package/dist/core/repository.cjs +362 -0
  38. package/dist/core/repository.cjs.map +1 -0
  39. package/dist/core/repository.d.cts +100 -0
  40. package/dist/core/repository.d.mts +100 -0
  41. package/dist/core/repository.mjs +362 -0
  42. package/dist/core/repository.mjs.map +1 -0
  43. package/dist/drivers/driver.cjs +11 -0
  44. package/dist/drivers/driver.cjs.map +1 -0
  45. package/dist/drivers/driver.mjs +11 -0
  46. package/dist/drivers/driver.mjs.map +1 -0
  47. package/dist/drivers/file.cjs +336 -0
  48. package/dist/drivers/file.cjs.map +1 -0
  49. package/dist/drivers/file.mjs +337 -0
  50. package/dist/drivers/file.mjs.map +1 -0
  51. package/dist/drivers/index.cjs +28 -0
  52. package/dist/drivers/index.cjs.map +1 -0
  53. package/dist/drivers/index.d.cts +14 -0
  54. package/dist/drivers/index.d.mts +14 -0
  55. package/dist/drivers/index.mjs +28 -0
  56. package/dist/drivers/index.mjs.map +1 -0
  57. package/dist/drivers/mysql.cjs +272 -0
  58. package/dist/drivers/mysql.cjs.map +1 -0
  59. package/dist/drivers/mysql.mjs +272 -0
  60. package/dist/drivers/mysql.mjs.map +1 -0
  61. package/dist/drivers/sql-compiler.cjs +284 -0
  62. package/dist/drivers/sql-compiler.cjs.map +1 -0
  63. package/dist/drivers/sql-compiler.d.cts +66 -0
  64. package/dist/drivers/sql-compiler.d.mts +66 -0
  65. package/dist/drivers/sql-compiler.mjs +276 -0
  66. package/dist/drivers/sql-compiler.mjs.map +1 -0
  67. package/dist/drivers/sqlite.cjs +262 -0
  68. package/dist/drivers/sqlite.cjs.map +1 -0
  69. package/dist/drivers/sqlite.mjs +262 -0
  70. package/dist/drivers/sqlite.mjs.map +1 -0
  71. package/dist/errors.cjs +74 -0
  72. package/dist/errors.cjs.map +1 -0
  73. package/dist/errors.d.cts +46 -0
  74. package/dist/errors.d.mts +46 -0
  75. package/dist/errors.mjs +68 -0
  76. package/dist/errors.mjs.map +1 -0
  77. package/dist/index.cjs +55 -0
  78. package/dist/index.cjs.map +1 -0
  79. package/dist/index.d.cts +15 -0
  80. package/dist/index.d.mts +15 -0
  81. package/dist/index.mjs +21 -0
  82. package/dist/index.mjs.map +1 -0
  83. package/dist/migrations/definition.cjs +20 -0
  84. package/dist/migrations/definition.cjs.map +1 -0
  85. package/dist/migrations/definition.d.cts +18 -0
  86. package/dist/migrations/definition.d.mts +18 -0
  87. package/dist/migrations/definition.mjs +23 -0
  88. package/dist/migrations/definition.mjs.map +1 -0
  89. package/dist/migrations/index.mjs +12 -0
  90. package/dist/migrations/index.mjs.map +1 -0
  91. package/dist/migrations/templates.cjs +39 -0
  92. package/dist/migrations/templates.cjs.map +1 -0
  93. package/dist/migrations/templates.d.cts +16 -0
  94. package/dist/migrations/templates.d.mts +16 -0
  95. package/dist/migrations/templates.mjs +41 -0
  96. package/dist/migrations/templates.mjs.map +1 -0
  97. package/dist/schema/column.cjs +129 -0
  98. package/dist/schema/column.cjs.map +1 -0
  99. package/dist/schema/column.d.cts +96 -0
  100. package/dist/schema/column.d.mts +96 -0
  101. package/dist/schema/column.mjs +129 -0
  102. package/dist/schema/column.mjs.map +1 -0
  103. package/dist/schema/columns/index.cjs +110 -0
  104. package/dist/schema/columns/index.cjs.map +1 -0
  105. package/dist/schema/columns/index.d.cts +91 -0
  106. package/dist/schema/columns/index.d.mts +91 -0
  107. package/dist/schema/columns/index.mjs +104 -0
  108. package/dist/schema/columns/index.mjs.map +1 -0
  109. package/dist/schema/registry.cjs +101 -0
  110. package/dist/schema/registry.cjs.map +1 -0
  111. package/dist/schema/registry.d.cts +52 -0
  112. package/dist/schema/registry.d.mts +52 -0
  113. package/dist/schema/registry.mjs +101 -0
  114. package/dist/schema/registry.mjs.map +1 -0
  115. package/dist/schema/table.cjs +36 -0
  116. package/dist/schema/table.cjs.map +1 -0
  117. package/dist/schema/table.d.cts +17 -0
  118. package/dist/schema/table.d.mts +17 -0
  119. package/dist/schema/table.mjs +36 -0
  120. package/dist/schema/table.mjs.map +1 -0
  121. package/dist/sync/synchronizer.cjs +43 -0
  122. package/dist/sync/synchronizer.cjs.map +1 -0
  123. package/dist/sync/synchronizer.d.cts +22 -0
  124. package/dist/sync/synchronizer.d.mts +22 -0
  125. package/dist/sync/synchronizer.mjs +43 -0
  126. package/dist/sync/synchronizer.mjs.map +1 -0
  127. package/dist/types.d.cts +227 -0
  128. package/dist/types.d.mts +227 -0
  129. package/dist/utils/fs.cjs +24 -0
  130. package/dist/utils/fs.cjs.map +1 -0
  131. package/dist/utils/fs.mjs +26 -0
  132. package/dist/utils/fs.mjs.map +1 -0
  133. package/dist/utils/index.mjs +14 -0
  134. package/dist/utils/index.mjs.map +1 -0
  135. package/dist/utils/naming.cjs +13 -0
  136. package/dist/utils/naming.cjs.map +1 -0
  137. package/dist/utils/naming.mjs +16 -0
  138. package/dist/utils/naming.mjs.map +1 -0
  139. package/dist/utils/stable-stringify.cjs +19 -0
  140. package/dist/utils/stable-stringify.cjs.map +1 -0
  141. package/dist/utils/stable-stringify.mjs +22 -0
  142. package/dist/utils/stable-stringify.mjs.map +1 -0
  143. package/package.json +64 -27
  144. package/readme.md +86 -106
  145. package/index.d.ts +0 -65
  146. package/index.js +0 -1
@@ -0,0 +1,276 @@
1
+ //#region src/drivers/sql-compiler.ts
2
+ /**
3
+ * Compile column type to SQL string for a specific database dialect
4
+ * @param {ColumnMetadata} col - Column metadata
5
+ * @param {DatabaseType} dialect - Database dialect
6
+ * @returns {string} SQL column type string
7
+ */
8
+ function compileColumnType(col, dialect) {
9
+ const name = typeof dialect === "string" ? dialect : dialect.name;
10
+ return {
11
+ integer: {
12
+ mysql: "INT",
13
+ mariadb: "INT",
14
+ sqlite: "INTEGER",
15
+ file: "INTEGER"
16
+ },
17
+ bigint: {
18
+ mysql: "BIGINT",
19
+ mariadb: "BIGINT",
20
+ sqlite: "INTEGER",
21
+ file: "BIGINT"
22
+ },
23
+ varchar: {
24
+ mysql: `VARCHAR(${col.length ?? 255})`,
25
+ mariadb: `VARCHAR(${col.length ?? 255})`,
26
+ sqlite: "TEXT",
27
+ file: "VARCHAR"
28
+ },
29
+ char: {
30
+ mysql: `CHAR(${col.length ?? 1})`,
31
+ mariadb: `CHAR(${col.length ?? 1})`,
32
+ sqlite: "TEXT",
33
+ file: "CHAR"
34
+ },
35
+ text: {
36
+ mysql: "TEXT",
37
+ mariadb: "TEXT",
38
+ sqlite: "TEXT",
39
+ file: "TEXT"
40
+ },
41
+ boolean: {
42
+ mysql: "TINYINT(1)",
43
+ mariadb: "TINYINT(1)",
44
+ sqlite: "INTEGER",
45
+ file: "BOOLEAN"
46
+ },
47
+ json: {
48
+ mysql: "JSON",
49
+ mariadb: "JSON",
50
+ sqlite: "TEXT",
51
+ file: "JSON"
52
+ },
53
+ datetime: {
54
+ mysql: "DATETIME",
55
+ mariadb: "DATETIME",
56
+ sqlite: "TEXT",
57
+ file: "DATETIME"
58
+ },
59
+ timestamp: {
60
+ mysql: "TIMESTAMP",
61
+ mariadb: "TIMESTAMP",
62
+ sqlite: "TEXT",
63
+ file: "TIMESTAMP"
64
+ },
65
+ decimal: {
66
+ mysql: `DECIMAL(${col.precision ?? 10},${col.scale ?? 2})`,
67
+ mariadb: `DECIMAL(${col.precision ?? 10},${col.scale ?? 2})`,
68
+ sqlite: "REAL",
69
+ file: "DECIMAL"
70
+ },
71
+ float: {
72
+ mysql: "FLOAT",
73
+ mariadb: "FLOAT",
74
+ sqlite: "REAL",
75
+ file: "FLOAT"
76
+ },
77
+ blob: {
78
+ mysql: "BLOB",
79
+ mariadb: "BLOB",
80
+ sqlite: "BLOB",
81
+ file: "BLOB"
82
+ }
83
+ }[col.type]?.[name] ?? "TEXT";
84
+ }
85
+ /**
86
+ * Compile a column definition to a SQL fragment
87
+ * @param {ColumnMetadata} col - Column metadata
88
+ * @param {DatabaseType} dialect - Database dialect
89
+ * @returns {string} SQL column definition
90
+ */
91
+ function compileColumnDef(col, dialect) {
92
+ const parts = [`\`${col.name}\``, compileColumnType(col, dialect)];
93
+ if (col.primaryKey) parts.push("PRIMARY KEY");
94
+ if (col.autoIncrement) parts.push(dialect === "mysql" ? "AUTO_INCREMENT" : "AUTOINCREMENT");
95
+ if (col.notNull && !col.primaryKey) parts.push("NOT NULL");
96
+ if (col.unique && !col.primaryKey) parts.push("UNIQUE");
97
+ if (col.defaultValue !== void 0) if (typeof col.defaultValue === "string") parts.push(`DEFAULT '${col.defaultValue}'`);
98
+ else if (col.defaultValue === null) parts.push("DEFAULT NULL");
99
+ else parts.push(`DEFAULT ${col.defaultValue}`);
100
+ return parts.join(" ");
101
+ }
102
+ /**
103
+ * Compile a CREATE TABLE statement from table metadata
104
+ * @param {TableMetadata} table - Table metadata
105
+ * @param {DatabaseType} dialect - Database dialect
106
+ * @returns {string} CREATE TABLE SQL statement
107
+ */
108
+ function compileCreateTable(table, dialect) {
109
+ const columnDefs = [];
110
+ const constraints = [];
111
+ for (const col of table.columns) {
112
+ columnDefs.push(compileColumnDef(col, dialect));
113
+ if (col.references) {
114
+ const onDelete = col.references.onDelete ? ` ON DELETE ${col.references.onDelete}` : "";
115
+ const onUpdate = col.references.onUpdate ? ` ON UPDATE ${col.references.onUpdate}` : "";
116
+ constraints.push(`FOREIGN KEY (\`${col.name}\`) REFERENCES \`${col.references.table}\`(\`${col.references.column}\`)${onDelete}${onUpdate}`);
117
+ }
118
+ }
119
+ const allDefs = [...columnDefs, ...constraints].join(", ");
120
+ return `CREATE TABLE IF NOT EXISTS \`${table.name}\` (${allDefs})`;
121
+ }
122
+ /**
123
+ * Compile a WHERE clause from a condition object
124
+ * @param {WhereClause} where - Where clause object
125
+ * @param {unknown[]} params - Parameter array to push values into
126
+ * @returns {string} SQL WHERE fragment
127
+ */
128
+ function compileWhere(where, params) {
129
+ const conditions = [];
130
+ for (const [key, value] of Object.entries(where)) {
131
+ if (key === "OR" && Array.isArray(value)) {
132
+ const orParts = value.map((sub) => compileWhere(sub, params));
133
+ if (orParts.length > 0) conditions.push(`(${orParts.join(" OR ")})`);
134
+ continue;
135
+ }
136
+ if (key === "AND" && Array.isArray(value)) {
137
+ const andParts = value.map((sub) => compileWhere(sub, params));
138
+ if (andParts.length > 0) conditions.push(`(${andParts.join(" AND ")})`);
139
+ continue;
140
+ }
141
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
142
+ const cond = value;
143
+ if (cond.eq !== void 0) {
144
+ params.push(cond.eq);
145
+ conditions.push(`\`${key}\` = ?`);
146
+ }
147
+ if (cond.neq !== void 0) {
148
+ params.push(cond.neq);
149
+ conditions.push(`\`${key}\` != ?`);
150
+ }
151
+ if (cond.gt !== void 0) {
152
+ params.push(cond.gt);
153
+ conditions.push(`\`${key}\` > ?`);
154
+ }
155
+ if (cond.gte !== void 0) {
156
+ params.push(cond.gte);
157
+ conditions.push(`\`${key}\` >= ?`);
158
+ }
159
+ if (cond.lt !== void 0) {
160
+ params.push(cond.lt);
161
+ conditions.push(`\`${key}\` < ?`);
162
+ }
163
+ if (cond.lte !== void 0) {
164
+ params.push(cond.lte);
165
+ conditions.push(`\`${key}\` <= ?`);
166
+ }
167
+ if (cond.like !== void 0) {
168
+ params.push(cond.like);
169
+ conditions.push(`\`${key}\` LIKE ?`);
170
+ }
171
+ if (cond.notLike !== void 0) {
172
+ params.push(cond.notLike);
173
+ conditions.push(`\`${key}\` NOT LIKE ?`);
174
+ }
175
+ if (cond.in !== void 0 && Array.isArray(cond.in)) {
176
+ const placeholders = cond.in.map(() => "?").join(", ");
177
+ params.push(...cond.in);
178
+ conditions.push(`\`${key}\` IN (${placeholders})`);
179
+ }
180
+ if (cond.notIn !== void 0 && Array.isArray(cond.notIn)) {
181
+ const placeholders = cond.notIn.map(() => "?").join(", ");
182
+ params.push(...cond.notIn);
183
+ conditions.push(`\`${key}\` NOT IN (${placeholders})`);
184
+ }
185
+ if (cond.isNull === true) conditions.push(`\`${key}\` IS NULL`);
186
+ if (cond.isNull === false) conditions.push(`\`${key}\` IS NOT NULL`);
187
+ if (cond.between !== void 0 && Array.isArray(cond.between)) {
188
+ params.push(cond.between[0], cond.between[1]);
189
+ conditions.push(`\`${key}\` BETWEEN ? AND ?`);
190
+ }
191
+ } else {
192
+ params.push(value);
193
+ conditions.push(`\`${key}\` = ?`);
194
+ }
195
+ }
196
+ return conditions.length > 0 ? conditions.join(" AND ") : "1=1";
197
+ }
198
+ /**
199
+ * Compile a SELECT query from options
200
+ * @param {string} tableName - Table name
201
+ * @param {object} options - Query options
202
+ * @param {unknown[]} params - Parameter array
203
+ * @returns {string} SQL SELECT statement
204
+ */
205
+ function compileSelect(tableName, options, params) {
206
+ let sql = `SELECT ${options.select?.map((c) => `\`${String(c)}\``).join(", ") ?? "*"} FROM \`${tableName}\``;
207
+ if (options.where && Object.keys(options.where).length > 0) sql += ` WHERE ${compileWhere(options.where, params)}`;
208
+ if (options.orderBy) {
209
+ const orderParts = Object.entries(options.orderBy).map(([col, dir]) => `\`${col}\` ${dir.toUpperCase()}`);
210
+ if (orderParts.length > 0) sql += ` ORDER BY ${orderParts.join(", ")}`;
211
+ }
212
+ if (options.take !== void 0) sql += ` LIMIT ${options.take}`;
213
+ if (options.skip !== void 0) sql += ` OFFSET ${options.skip}`;
214
+ return sql;
215
+ }
216
+ /**
217
+ * Compile an INSERT statement
218
+ * @param {string} tableName - Table name
219
+ * @param {Record<string, unknown>} data - Data to insert
220
+ * @param {unknown[]} params - Parameter array
221
+ * @returns {string} SQL INSERT statement
222
+ */
223
+ function compileInsert(tableName, data, params) {
224
+ const keys = Object.keys(data);
225
+ const cols = keys.map((k) => `\`${k}\``).join(", ");
226
+ const placeholders = keys.map(() => "?").join(", ");
227
+ params.push(...keys.map((k) => data[k]));
228
+ return `INSERT INTO \`${tableName}\` (${cols}) VALUES (${placeholders})`;
229
+ }
230
+ /**
231
+ * Compile a bulk INSERT statement for multiple rows
232
+ * @param {string} tableName - Table name
233
+ * @param {Record<string, unknown>[]} data - Array of data to insert
234
+ * @param {unknown[]} params - Parameter array
235
+ * @returns {string} SQL bulk INSERT statement
236
+ */
237
+ function compileBulkInsert(tableName, data, params) {
238
+ if (data.length === 0) return "";
239
+ const keys = Object.keys(data[0]);
240
+ const cols = keys.map((k) => `\`${k}\``).join(", ");
241
+ const valuePlaceholders = data.map(() => `(${keys.map(() => "?").join(", ")})`).join(", ");
242
+ for (const row of data) for (const key of keys) params.push(row[key]);
243
+ return `INSERT INTO \`${tableName}\` (${cols}) VALUES ${valuePlaceholders}`;
244
+ }
245
+ /**
246
+ * Compile an UPDATE statement
247
+ * @param {string} tableName - Table name
248
+ * @param {Record<string, unknown>} data - Data to update
249
+ * @param {WhereClause} where - Where clause
250
+ * @param {unknown[]} params - Parameter array
251
+ * @returns {string} SQL UPDATE statement
252
+ */
253
+ function compileUpdate(tableName, data, where, params) {
254
+ let sql = `UPDATE \`${tableName}\` SET ${Object.keys(data).map((k) => {
255
+ params.push(data[k]);
256
+ return `\`${k}\` = ?`;
257
+ }).join(", ")}`;
258
+ if (Object.keys(where).length > 0) sql += ` WHERE ${compileWhere(where, params)}`;
259
+ return sql;
260
+ }
261
+ /**
262
+ * Compile a DELETE statement
263
+ * @param {string} tableName - Table name
264
+ * @param {WhereClause} where - Where clause
265
+ * @param {unknown[]} params - Parameter array
266
+ * @returns {string} SQL DELETE statement
267
+ */
268
+ function compileDelete(tableName, where, params) {
269
+ let sql = `DELETE FROM \`${tableName}\``;
270
+ if (Object.keys(where).length > 0) sql += ` WHERE ${compileWhere(where, params)}`;
271
+ return sql;
272
+ }
273
+ //#endregion
274
+ export { compileBulkInsert, compileColumnDef, compileColumnType, compileCreateTable, compileDelete, compileInsert, compileSelect, compileUpdate, compileWhere };
275
+
276
+ //# sourceMappingURL=sql-compiler.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-compiler.mjs","names":[],"sources":["../../src/drivers/sql-compiler.ts"],"sourcesContent":["import type {\n ColumnDataType,\n ColumnMetadata,\n DatabaseType,\n TableMetadata,\n WhereClause,\n WhereCondition,\n} from \"../types\";\n\n/**\n * Compile column type to SQL string for a specific database dialect\n * @param {ColumnMetadata} col - Column metadata\n * @param {DatabaseType} dialect - Database dialect\n * @returns {string} SQL column type string\n */\nexport function compileColumnType(col: ColumnMetadata, dialect: DatabaseType): string {\n const name = typeof dialect === \"string\" ? dialect : dialect.name;\n\n const typeMap: Record<ColumnDataType, Record<string, string>> = {\n integer: { mysql: \"INT\", mariadb: \"INT\", sqlite: \"INTEGER\", file: \"INTEGER\" },\n bigint: { mysql: \"BIGINT\", mariadb: \"BIGINT\", sqlite: \"INTEGER\", file: \"BIGINT\" },\n varchar: {\n mysql: `VARCHAR(${col.length ?? 255})`,\n mariadb: `VARCHAR(${col.length ?? 255})`,\n sqlite: \"TEXT\",\n file: \"VARCHAR\",\n },\n char: {\n mysql: `CHAR(${col.length ?? 1})`,\n mariadb: `CHAR(${col.length ?? 1})`,\n sqlite: \"TEXT\",\n file: \"CHAR\",\n },\n text: { mysql: \"TEXT\", mariadb: \"TEXT\", sqlite: \"TEXT\", file: \"TEXT\" },\n boolean: { mysql: \"TINYINT(1)\", mariadb: \"TINYINT(1)\", sqlite: \"INTEGER\", file: \"BOOLEAN\" },\n json: { mysql: \"JSON\", mariadb: \"JSON\", sqlite: \"TEXT\", file: \"JSON\" },\n datetime: { mysql: \"DATETIME\", mariadb: \"DATETIME\", sqlite: \"TEXT\", file: \"DATETIME\" },\n timestamp: { mysql: \"TIMESTAMP\", mariadb: \"TIMESTAMP\", sqlite: \"TEXT\", file: \"TIMESTAMP\" },\n decimal: {\n mysql: `DECIMAL(${col.precision ?? 10},${col.scale ?? 2})`,\n mariadb: `DECIMAL(${col.precision ?? 10},${col.scale ?? 2})`,\n sqlite: \"REAL\",\n file: \"DECIMAL\",\n },\n float: { mysql: \"FLOAT\", mariadb: \"FLOAT\", sqlite: \"REAL\", file: \"FLOAT\" },\n blob: { mysql: \"BLOB\", mariadb: \"BLOB\", sqlite: \"BLOB\", file: \"BLOB\" },\n };\n\n return typeMap[col.type]?.[name] ?? \"TEXT\";\n}\n\n/**\n * Compile a column definition to a SQL fragment\n * @param {ColumnMetadata} col - Column metadata\n * @param {DatabaseType} dialect - Database dialect\n * @returns {string} SQL column definition\n */\nexport function compileColumnDef(col: ColumnMetadata, dialect: DatabaseType): string {\n const parts: string[] = [`\\`${col.name}\\``, compileColumnType(col, dialect)];\n\n if (col.primaryKey) {\n parts.push(\"PRIMARY KEY\");\n }\n if (col.autoIncrement) {\n parts.push(dialect === \"mysql\" ? \"AUTO_INCREMENT\" : \"AUTOINCREMENT\");\n }\n if (col.notNull && !col.primaryKey) {\n parts.push(\"NOT NULL\");\n }\n if (col.unique && !col.primaryKey) {\n parts.push(\"UNIQUE\");\n }\n if (col.defaultValue !== undefined) {\n if (typeof col.defaultValue === \"string\") {\n parts.push(`DEFAULT '${col.defaultValue}'`);\n } else if (col.defaultValue === null) {\n parts.push(\"DEFAULT NULL\");\n } else {\n parts.push(`DEFAULT ${col.defaultValue}`);\n }\n }\n\n return parts.join(\" \");\n}\n\n/**\n * Compile a CREATE TABLE statement from table metadata\n * @param {TableMetadata} table - Table metadata\n * @param {DatabaseType} dialect - Database dialect\n * @returns {string} CREATE TABLE SQL statement\n */\nexport function compileCreateTable(table: TableMetadata, dialect: DatabaseType): string {\n const columnDefs: string[] = [];\n const constraints: string[] = [];\n\n for (const col of table.columns) {\n columnDefs.push(compileColumnDef(col, dialect));\n\n if (col.references) {\n const onDelete = col.references.onDelete ? ` ON DELETE ${col.references.onDelete}` : \"\";\n const onUpdate = col.references.onUpdate ? ` ON UPDATE ${col.references.onUpdate}` : \"\";\n constraints.push(\n `FOREIGN KEY (\\`${col.name}\\`) REFERENCES \\`${col.references.table}\\`(\\`${col.references.column}\\`)${onDelete}${onUpdate}`,\n );\n }\n }\n\n const allDefs = [...columnDefs, ...constraints].join(\", \");\n return `CREATE TABLE IF NOT EXISTS \\`${table.name}\\` (${allDefs})`;\n}\n\n/**\n * Compile a WHERE clause from a condition object\n * @param {WhereClause} where - Where clause object\n * @param {unknown[]} params - Parameter array to push values into\n * @returns {string} SQL WHERE fragment\n */\nexport function compileWhere(where: WhereClause, params: unknown[]): string {\n const conditions: string[] = [];\n\n for (const [key, value] of Object.entries(where)) {\n if (key === \"OR\" && Array.isArray(value)) {\n const orParts = (value as WhereClause[]).map((sub) => compileWhere(sub, params));\n if (orParts.length > 0) {\n conditions.push(`(${orParts.join(\" OR \")})`);\n }\n continue;\n }\n if (key === \"AND\" && Array.isArray(value)) {\n const andParts = (value as WhereClause[]).map((sub) => compileWhere(sub, params));\n if (andParts.length > 0) {\n conditions.push(`(${andParts.join(\" AND \")})`);\n }\n continue;\n }\n\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const cond = value as WhereCondition;\n if (cond.eq !== undefined) {\n params.push(cond.eq);\n conditions.push(`\\`${key}\\` = ?`);\n }\n if (cond.neq !== undefined) {\n params.push(cond.neq);\n conditions.push(`\\`${key}\\` != ?`);\n }\n if (cond.gt !== undefined) {\n params.push(cond.gt);\n conditions.push(`\\`${key}\\` > ?`);\n }\n if (cond.gte !== undefined) {\n params.push(cond.gte);\n conditions.push(`\\`${key}\\` >= ?`);\n }\n if (cond.lt !== undefined) {\n params.push(cond.lt);\n conditions.push(`\\`${key}\\` < ?`);\n }\n if (cond.lte !== undefined) {\n params.push(cond.lte);\n conditions.push(`\\`${key}\\` <= ?`);\n }\n if (cond.like !== undefined) {\n params.push(cond.like);\n conditions.push(`\\`${key}\\` LIKE ?`);\n }\n if (cond.notLike !== undefined) {\n params.push(cond.notLike);\n conditions.push(`\\`${key}\\` NOT LIKE ?`);\n }\n if (cond.in !== undefined && Array.isArray(cond.in)) {\n const placeholders = cond.in.map(() => \"?\").join(\", \");\n params.push(...cond.in);\n conditions.push(`\\`${key}\\` IN (${placeholders})`);\n }\n if (cond.notIn !== undefined && Array.isArray(cond.notIn)) {\n const placeholders = cond.notIn.map(() => \"?\").join(\", \");\n params.push(...cond.notIn);\n conditions.push(`\\`${key}\\` NOT IN (${placeholders})`);\n }\n if (cond.isNull === true) {\n conditions.push(`\\`${key}\\` IS NULL`);\n }\n if (cond.isNull === false) {\n conditions.push(`\\`${key}\\` IS NOT NULL`);\n }\n if (cond.between !== undefined && Array.isArray(cond.between)) {\n params.push(cond.between[0], cond.between[1]);\n conditions.push(`\\`${key}\\` BETWEEN ? AND ?`);\n }\n } else {\n params.push(value);\n conditions.push(`\\`${key}\\` = ?`);\n }\n }\n\n return conditions.length > 0 ? conditions.join(\" AND \") : \"1=1\";\n}\n\n/**\n * Compile a SELECT query from options\n * @param {string} tableName - Table name\n * @param {object} options - Query options\n * @param {unknown[]} params - Parameter array\n * @returns {string} SQL SELECT statement\n */\nexport function compileSelect(\n tableName: string,\n options: {\n select?: string[];\n where?: WhereClause;\n orderBy?: Record<string, \"asc\" | \"desc\">;\n take?: number;\n skip?: number;\n },\n params: unknown[],\n): string {\n const cols = options.select?.map((c) => `\\`${String(c)}\\``).join(\", \") ?? \"*\";\n let sql = `SELECT ${cols} FROM \\`${tableName}\\``;\n\n if (options.where && Object.keys(options.where).length > 0) {\n sql += ` WHERE ${compileWhere(options.where, params)}`;\n }\n if (options.orderBy) {\n const orderParts = Object.entries(options.orderBy).map(\n ([col, dir]) => `\\`${col}\\` ${dir.toUpperCase()}`,\n );\n if (orderParts.length > 0) {\n sql += ` ORDER BY ${orderParts.join(\", \")}`;\n }\n }\n if (options.take !== undefined) {\n sql += ` LIMIT ${options.take}`;\n }\n if (options.skip !== undefined) {\n sql += ` OFFSET ${options.skip}`;\n }\n\n return sql;\n}\n\n/**\n * Compile an INSERT statement\n * @param {string} tableName - Table name\n * @param {Record<string, unknown>} data - Data to insert\n * @param {unknown[]} params - Parameter array\n * @returns {string} SQL INSERT statement\n */\nexport function compileInsert(\n tableName: string,\n data: Record<string, unknown>,\n params: unknown[],\n): string {\n const keys = Object.keys(data);\n const cols = keys.map((k) => `\\`${k}\\``).join(\", \");\n const placeholders = keys.map(() => \"?\").join(\", \");\n params.push(...keys.map((k) => data[k]));\n return `INSERT INTO \\`${tableName}\\` (${cols}) VALUES (${placeholders})`;\n}\n\n/**\n * Compile a bulk INSERT statement for multiple rows\n * @param {string} tableName - Table name\n * @param {Record<string, unknown>[]} data - Array of data to insert\n * @param {unknown[]} params - Parameter array\n * @returns {string} SQL bulk INSERT statement\n */\nexport function compileBulkInsert(\n tableName: string,\n data: Record<string, unknown>[],\n params: unknown[],\n): string {\n if (data.length === 0) {\n return \"\";\n }\n const keys = Object.keys(data[0]!);\n const cols = keys.map((k) => `\\`${k}\\``).join(\", \");\n const valuePlaceholders = data.map(() => `(${keys.map(() => \"?\").join(\", \")})`).join(\", \");\n\n for (const row of data) {\n for (const key of keys) {\n params.push(row[key]);\n }\n }\n\n return `INSERT INTO \\`${tableName}\\` (${cols}) VALUES ${valuePlaceholders}`;\n}\n\n/**\n * Compile an UPDATE statement\n * @param {string} tableName - Table name\n * @param {Record<string, unknown>} data - Data to update\n * @param {WhereClause} where - Where clause\n * @param {unknown[]} params - Parameter array\n * @returns {string} SQL UPDATE statement\n */\nexport function compileUpdate(\n tableName: string,\n data: Record<string, unknown>,\n where: WhereClause,\n params: unknown[],\n): string {\n const setParts = Object.keys(data).map((k) => {\n params.push(data[k]);\n return `\\`${k}\\` = ?`;\n });\n let sql = `UPDATE \\`${tableName}\\` SET ${setParts.join(\", \")}`;\n if (Object.keys(where).length > 0) {\n sql += ` WHERE ${compileWhere(where, params)}`;\n }\n return sql;\n}\n\n/**\n * Compile a DELETE statement\n * @param {string} tableName - Table name\n * @param {WhereClause} where - Where clause\n * @param {unknown[]} params - Parameter array\n * @returns {string} SQL DELETE statement\n */\nexport function compileDelete(tableName: string, where: WhereClause, params: unknown[]): string {\n let sql = `DELETE FROM \\`${tableName}\\``;\n if (Object.keys(where).length > 0) {\n sql += ` WHERE ${compileWhere(where, params)}`;\n }\n return sql;\n}\n"],"mappings":"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"}
@@ -0,0 +1,262 @@
1
+ const require_errors = require("../errors.cjs");
2
+ const require_driver = require("./driver.cjs");
3
+ const require_sql_compiler = require("./sql-compiler.cjs");
4
+ //#region src/drivers/sqlite.ts
5
+ /**
6
+ * SQLite database driver supporting multiple libraries (better-sqlite3, sqlite3, sql.js, bun:sqlite)
7
+ */
8
+ var SQLiteDriver = class extends require_driver.BaseDriver {
9
+ db = null;
10
+ config;
11
+ provider;
12
+ constructor(config, provider) {
13
+ super();
14
+ this.config = config;
15
+ this.provider = provider;
16
+ }
17
+ /**
18
+ * Connect to the SQLite database
19
+ */
20
+ async connect() {
21
+ if (this.connected) return;
22
+ try {
23
+ this.db = await this.getAdapter();
24
+ await this.db.exec("PRAGMA journal_mode=WAL");
25
+ await this.db.exec("PRAGMA foreign_keys=ON");
26
+ this.connected = true;
27
+ } catch (err) {
28
+ throw new require_errors.DriverError(`Failed to connect to SQLite database: ${err.message}`);
29
+ }
30
+ }
31
+ async getAdapter() {
32
+ const provider = this.provider;
33
+ if (!provider || provider === "better-sqlite3") try {
34
+ const BetterSqlite3 = await import("better-sqlite3");
35
+ return new (BetterSqlite3.default || BetterSqlite3)(this.config.filename);
36
+ } catch (err) {
37
+ if (provider === "better-sqlite3") throw err;
38
+ }
39
+ if (!provider || provider === "sqlite3") try {
40
+ const db = new (await (import("sqlite3"))).Database(this.config.filename);
41
+ return {
42
+ close: () => new Promise((res, rej) => db.close((err) => err ? rej(err) : res())),
43
+ exec: (sql) => new Promise((res, rej) => db.exec(sql, (err) => err ? rej(err) : res())),
44
+ prepare: (sql) => ({
45
+ run: (...params) => new Promise((res, rej) => {
46
+ db.run(sql, params, function(err) {
47
+ if (err) return rej(err);
48
+ res({
49
+ lastInsertRowid: this.lastID,
50
+ changes: this.changes
51
+ });
52
+ });
53
+ }),
54
+ all: (...params) => new Promise((res, rej) => {
55
+ db.all(sql, params, (err, rows) => err ? rej(err) : res(rows));
56
+ })
57
+ })
58
+ };
59
+ } catch (err) {
60
+ if (provider === "sqlite3") throw err;
61
+ }
62
+ if (!provider || provider === "sql.js") try {
63
+ const SQL = await (await import("sql.js")).default();
64
+ const fs = await import("fs");
65
+ let data;
66
+ if (fs.existsSync(this.config.filename)) data = fs.readFileSync(this.config.filename);
67
+ const db = new SQL.Database(data);
68
+ return {
69
+ close: () => {
70
+ const binaryArray = db.export();
71
+ fs.writeFileSync(this.config.filename, Buffer.from(binaryArray));
72
+ db.close();
73
+ },
74
+ exec: (sql) => db.run(sql),
75
+ prepare: (sql) => {
76
+ const stmt = db.prepare(sql);
77
+ return {
78
+ run: (...params) => {
79
+ stmt.run(params);
80
+ const result = db.exec("SELECT last_insert_rowid()");
81
+ return {
82
+ lastInsertRowid: result[0]?.values[0] ? result[0].values[0][0] : 0,
83
+ changes: db.getRowsModified()
84
+ };
85
+ },
86
+ all: (...params) => {
87
+ const rows = [];
88
+ stmt.bind(params);
89
+ while (stmt.step()) rows.push(stmt.getAsObject());
90
+ return rows;
91
+ }
92
+ };
93
+ }
94
+ };
95
+ } catch (err) {
96
+ if (provider === "sql.js") throw err;
97
+ }
98
+ if (!provider || provider === "bun:sqlite") try {
99
+ const { Database } = await import("bun:sqlite");
100
+ return new Database(this.config.filename);
101
+ } catch (err) {
102
+ if (provider === "bun:sqlite") throw err;
103
+ }
104
+ throw new Error(provider ? `SQLite provider "${provider}" not found.` : "No SQLite driver found. Please install better-sqlite3, sqlite3, sql.js or run with Bun.");
105
+ }
106
+ /**
107
+ * Disconnect from the SQLite database
108
+ */
109
+ async disconnect() {
110
+ if (this.db) {
111
+ await this.db.close();
112
+ this.db = null;
113
+ this.connected = false;
114
+ }
115
+ }
116
+ /**
117
+ * Execute a SQL statement
118
+ * @param {string} sql - SQL statement
119
+ * @param {unknown[]} [params] - Query parameters
120
+ * @returns {Promise<any>} Execution result with lastInsertRowid and changes
121
+ */
122
+ async execute(sql, params = []) {
123
+ try {
124
+ const result = await this.db.prepare(sql).run(...this.formatParams(params));
125
+ return {
126
+ insertId: Number(result.lastInsertRowid),
127
+ affectedRows: result.changes
128
+ };
129
+ } catch (err) {
130
+ throw new require_errors.DriverError(`SQLite execute error: ${err.message}`);
131
+ }
132
+ }
133
+ /**
134
+ * Execute a SQL query
135
+ * @param {string} sql - SQL query
136
+ * @param {unknown[]} [params] - Query parameters
137
+ * @returns {Promise<any[]>} Query results
138
+ */
139
+ async query(sql, params = []) {
140
+ try {
141
+ return await this.db.prepare(sql).all(...this.formatParams(params));
142
+ } catch (err) {
143
+ throw new require_errors.DriverError(`SQLite query error: ${err.message}`);
144
+ }
145
+ }
146
+ formatParams(params) {
147
+ return params.map((p) => {
148
+ if (p instanceof Date) return p.toISOString();
149
+ return p;
150
+ });
151
+ }
152
+ /**
153
+ * Check if a table exists
154
+ * @param {string} name - Table name
155
+ * @returns {Promise<boolean>} Whether the table exists
156
+ */
157
+ async tableExists(name) {
158
+ return (await this.query("SELECT name FROM sqlite_master WHERE type='table' AND name=?", [name])).length > 0;
159
+ }
160
+ /**
161
+ * Get column metadata for a table
162
+ * @param {string} name - Table name
163
+ * @returns {Promise<ColumnMetadata[]>} Column metadata
164
+ */
165
+ async getTableColumns(name) {
166
+ return (await this.query(`PRAGMA table_info(\`${name}\`)`)).map((row) => ({
167
+ name: row.name,
168
+ type: this.mapSQLiteType(row.type),
169
+ primaryKey: row.pk === 1,
170
+ autoIncrement: row.pk === 1 && row.type.toUpperCase() === "INTEGER",
171
+ notNull: row.notnull === 1,
172
+ unique: false,
173
+ defaultValue: row.dflt_value
174
+ }));
175
+ }
176
+ /**
177
+ * Create a table from metadata
178
+ * @param {TableMetadata} meta - Table metadata
179
+ */
180
+ async createTable(meta) {
181
+ const sql = require_sql_compiler.compileCreateTable(meta, "sqlite");
182
+ await this.execute(sql);
183
+ }
184
+ /**
185
+ * Drop a table
186
+ * @param {string} name - Table name
187
+ */
188
+ async dropTable(name) {
189
+ await this.execute(`DROP TABLE IF EXISTS \`${name}\``);
190
+ }
191
+ /**
192
+ * Add a column to a table
193
+ * @param {string} table - Table name
194
+ * @param {ColumnMetadata} column - Column metadata
195
+ */
196
+ async addColumn(table, column) {
197
+ const colDef = require_sql_compiler.compileColumnDef(column, "sqlite");
198
+ await this.execute(`ALTER TABLE \`${table}\` ADD COLUMN ${colDef}`);
199
+ }
200
+ /**
201
+ * Drop a column from a table
202
+ * @param {string} table - Table name
203
+ * @param {string} name - Column name
204
+ */
205
+ async dropColumn(table, name) {
206
+ await this.execute(`ALTER TABLE \`${table}\` DROP COLUMN \`${name}\``);
207
+ }
208
+ /**
209
+ * Rename a column
210
+ * @param {string} table - Table name
211
+ * @param {string} oldName - Current name
212
+ * @param {string} newName - New name
213
+ */
214
+ async renameColumn(table, oldName, newName) {
215
+ await this.execute(`ALTER TABLE \`${table}\` RENAME COLUMN \`${oldName}\` TO \`${newName}\``);
216
+ }
217
+ /**
218
+ * Execute within a transaction
219
+ * @param {() => Promise<T>} fn - Function to execute
220
+ * @returns {Promise<T>} Result
221
+ */
222
+ async transaction(fn) {
223
+ await this.execute("BEGIN TRANSACTION");
224
+ try {
225
+ const result = await fn();
226
+ await this.execute("COMMIT");
227
+ return result;
228
+ } catch (err) {
229
+ await this.execute("ROLLBACK");
230
+ throw err;
231
+ }
232
+ }
233
+ /**
234
+ * Fetch all column metadata for all tables in the database
235
+ * @returns {Promise<Record<string, ColumnMetadata[]>>} Columns grouped by table name
236
+ */
237
+ async getAllTableColumns() {
238
+ try {
239
+ const tables = await this.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");
240
+ const result = {};
241
+ for (const table of tables) {
242
+ const tableName = table.name;
243
+ result[tableName] = await this.getTableColumns(tableName);
244
+ }
245
+ return result;
246
+ } catch (err) {
247
+ throw new require_errors.DriverError(`Failed to fetch all table columns: ${err.message}`);
248
+ }
249
+ }
250
+ mapSQLiteType(type) {
251
+ const upper = type.toUpperCase();
252
+ if (upper.includes("INT")) return "integer";
253
+ if (upper.includes("CHAR") || upper.includes("TEXT") || upper.includes("CLOB")) return "text";
254
+ if (upper.includes("REAL") || upper.includes("FLOAT") || upper.includes("DOUBLE")) return "float";
255
+ if (upper.includes("BLOB")) return "blob";
256
+ return "text";
257
+ }
258
+ };
259
+ //#endregion
260
+ exports.SQLiteDriver = SQLiteDriver;
261
+
262
+ //# sourceMappingURL=sqlite.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.cjs","names":["BaseDriver","DriverError","compileCreateTable","compileColumnDef"],"sources":["../../src/drivers/sqlite.ts"],"sourcesContent":["import { DriverError } from \"../errors\";\nimport type { ColumnMetadata, SQLiteConnectionConfig, TableMetadata } from \"../types\";\nimport { BaseDriver } from \"./driver\";\nimport { compileColumnDef, compileCreateTable } from \"./sql-compiler\";\n\n/**\n * Interface for SQLite database adapters\n */\ninterface SQLiteAdapter {\n close(): void | Promise<void>;\n prepare(sql: string): SQLiteStatement;\n exec(sql: string): void | Promise<void>;\n}\n\ninterface SQLiteStatement {\n run(...params: any[]): any | Promise<any>;\n all(...params: any[]): any[] | Promise<any[]>;\n}\n\n/**\n * SQLite database driver supporting multiple libraries (better-sqlite3, sqlite3, sql.js, bun:sqlite)\n */\nexport class SQLiteDriver extends BaseDriver {\n private db: SQLiteAdapter | null = null;\n private config: SQLiteConnectionConfig;\n private provider?: \"better-sqlite3\" | \"sqlite3\" | \"sql.js\" | \"bun:sqlite\";\n\n constructor(\n config: SQLiteConnectionConfig,\n provider?: \"better-sqlite3\" | \"sqlite3\" | \"sql.js\" | \"bun:sqlite\",\n ) {\n super();\n this.config = config;\n this.provider = provider;\n }\n\n /**\n * Connect to the SQLite database\n */\n async connect(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n try {\n const adapter = await this.getAdapter();\n this.db = adapter;\n await this.db.exec(\"PRAGMA journal_mode=WAL\");\n await this.db.exec(\"PRAGMA foreign_keys=ON\");\n this.connected = true;\n } catch (err: any) {\n throw new DriverError(`Failed to connect to SQLite database: ${err.message}`);\n }\n }\n\n private async getAdapter(): Promise<SQLiteAdapter> {\n const provider = this.provider;\n\n if (!provider || provider === \"better-sqlite3\") {\n try {\n const BetterSqlite3 = await import(\"better-sqlite3\");\n const Database = BetterSqlite3.default || BetterSqlite3;\n return new Database(this.config.filename) as any;\n } catch (err) {\n if (provider === \"better-sqlite3\") {\n throw err;\n }\n }\n }\n\n if (!provider || provider === \"sqlite3\") {\n try {\n const sqlite3 = await import(\"sqlite3\");\n const db = new sqlite3.Database(this.config.filename);\n\n return {\n close: () => new Promise<void>((res, rej) => db.close((err) => (err ? rej(err) : res()))),\n exec: (sql: string) =>\n new Promise<void>((res, rej) => db.exec(sql, (err) => (err ? rej(err) : res()))),\n prepare: (sql: string) => ({\n run: (...params: any[]) =>\n new Promise<{ lastInsertRowid: number; changes: number }>((res, rej) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) {\n return rej(err);\n }\n res({ lastInsertRowid: this.lastID, changes: this.changes });\n });\n }),\n all: (...params: any[]) =>\n new Promise<any[]>((res, rej) => {\n db.all(sql, params, (err, rows) => (err ? rej(err) : res(rows)));\n }),\n }),\n } as any;\n } catch (err) {\n if (provider === \"sqlite3\") {\n throw err;\n }\n }\n }\n\n if (!provider || provider === \"sql.js\") {\n try {\n const initSqlJs = await import(\"sql.js\");\n const SQL = await initSqlJs.default();\n const fs = await import(\"fs\");\n let data: Buffer | undefined;\n if (fs.existsSync(this.config.filename)) {\n data = fs.readFileSync(this.config.filename);\n }\n const db = new SQL.Database(data);\n return {\n close: () => {\n const binaryArray = db.export();\n fs.writeFileSync(this.config.filename, Buffer.from(binaryArray));\n db.close();\n },\n exec: (sql: string) => db.run(sql),\n prepare: (sql: string) => {\n const stmt = db.prepare(sql);\n return {\n run: (...params: any[]) => {\n stmt.run(params);\n const result = db.exec(\"SELECT last_insert_rowid()\");\n const lastInsertRowid = result[0]?.values[0]\n ? (result[0].values[0][0] as number)\n : 0;\n return { lastInsertRowid, changes: db.getRowsModified() };\n },\n all: (...params: any[]) => {\n const rows: any[] = [];\n stmt.bind(params);\n while (stmt.step()) {\n rows.push(stmt.getAsObject());\n }\n return rows;\n },\n };\n },\n } as any;\n } catch (err) {\n if (provider === \"sql.js\") {\n throw err;\n }\n }\n }\n\n if (!provider || provider === \"bun:sqlite\") {\n try {\n const { Database } = await import(\"bun:sqlite\");\n return new Database(this.config.filename) as any;\n } catch (err) {\n if (provider === \"bun:sqlite\") {\n throw err;\n }\n }\n }\n\n throw new Error(\n provider\n ? `SQLite provider \"${provider}\" not found.`\n : \"No SQLite driver found. Please install better-sqlite3, sqlite3, sql.js or run with Bun.\",\n );\n }\n\n /**\n * Disconnect from the SQLite database\n */\n async disconnect(): Promise<void> {\n if (this.db) {\n await this.db.close();\n this.db = null;\n this.connected = false;\n }\n }\n\n /**\n * Execute a SQL statement\n * @param {string} sql - SQL statement\n * @param {unknown[]} [params] - Query parameters\n * @returns {Promise<any>} Execution result with lastInsertRowid and changes\n */\n async execute(sql: string, params: unknown[] = []): Promise<any> {\n try {\n const stmt = this.db!.prepare(sql);\n const result = await stmt.run(...this.formatParams(params));\n return {\n insertId: Number(result.lastInsertRowid),\n affectedRows: result.changes,\n };\n } catch (err: any) {\n throw new DriverError(`SQLite execute error: ${err.message}`);\n }\n }\n\n /**\n * Execute a SQL query\n * @param {string} sql - SQL query\n * @param {unknown[]} [params] - Query parameters\n * @returns {Promise<any[]>} Query results\n */\n async query(sql: string, params: unknown[] = []): Promise<any[]> {\n try {\n const stmt = this.db!.prepare(sql);\n return await stmt.all(...this.formatParams(params));\n } catch (err: any) {\n throw new DriverError(`SQLite query error: ${err.message}`);\n }\n }\n\n private formatParams(params: unknown[]): any[] {\n return params.map((p) => {\n if (p instanceof Date) {\n return p.toISOString();\n }\n return p;\n });\n }\n\n /**\n * Check if a table exists\n * @param {string} name - Table name\n * @returns {Promise<boolean>} Whether the table exists\n */\n async tableExists(name: string): Promise<boolean> {\n const rows = await this.query(\"SELECT name FROM sqlite_master WHERE type='table' AND name=?\", [\n name,\n ]);\n return rows.length > 0;\n }\n\n /**\n * Get column metadata for a table\n * @param {string} name - Table name\n * @returns {Promise<ColumnMetadata[]>} Column metadata\n */\n async getTableColumns(name: string): Promise<ColumnMetadata[]> {\n const rows = (await this.query(`PRAGMA table_info(\\`${name}\\`)`)) as any[];\n return rows.map((row: any) => ({\n name: row.name,\n type: this.mapSQLiteType(row.type),\n primaryKey: row.pk === 1,\n autoIncrement: row.pk === 1 && row.type.toUpperCase() === \"INTEGER\",\n notNull: row.notnull === 1,\n unique: false,\n defaultValue: row.dflt_value,\n }));\n }\n\n /**\n * Create a table from metadata\n * @param {TableMetadata} meta - Table metadata\n */\n async createTable(meta: TableMetadata): Promise<void> {\n const sql = compileCreateTable(meta, \"sqlite\");\n await this.execute(sql);\n }\n\n /**\n * Drop a table\n * @param {string} name - Table name\n */\n async dropTable(name: string): Promise<void> {\n await this.execute(`DROP TABLE IF EXISTS \\`${name}\\``);\n }\n\n /**\n * Add a column to a table\n * @param {string} table - Table name\n * @param {ColumnMetadata} column - Column metadata\n */\n async addColumn(table: string, column: ColumnMetadata): Promise<void> {\n const colDef = compileColumnDef(column, \"sqlite\");\n await this.execute(`ALTER TABLE \\`${table}\\` ADD COLUMN ${colDef}`);\n }\n\n /**\n * Drop a column from a table\n * @param {string} table - Table name\n * @param {string} name - Column name\n */\n async dropColumn(table: string, name: string): Promise<void> {\n await this.execute(`ALTER TABLE \\`${table}\\` DROP COLUMN \\`${name}\\``);\n }\n\n /**\n * Rename a column\n * @param {string} table - Table name\n * @param {string} oldName - Current name\n * @param {string} newName - New name\n */\n async renameColumn(table: string, oldName: string, newName: string): Promise<void> {\n await this.execute(`ALTER TABLE \\`${table}\\` RENAME COLUMN \\`${oldName}\\` TO \\`${newName}\\``);\n }\n\n /**\n * Execute within a transaction\n * @param {() => Promise<T>} fn - Function to execute\n * @returns {Promise<T>} Result\n */\n async transaction<T>(fn: () => Promise<T>): Promise<T> {\n await this.execute(\"BEGIN TRANSACTION\");\n try {\n const result = await fn();\n await this.execute(\"COMMIT\");\n return result;\n } catch (err) {\n await this.execute(\"ROLLBACK\");\n throw err;\n }\n }\n\n /**\n * Fetch all column metadata for all tables in the database\n * @returns {Promise<Record<string, ColumnMetadata[]>>} Columns grouped by table name\n */\n async getAllTableColumns(): Promise<Record<string, ColumnMetadata[]>> {\n try {\n const tables = await this.query(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\",\n );\n const result: Record<string, ColumnMetadata[]> = {};\n\n for (const table of tables) {\n const tableName = table.name;\n result[tableName] = await this.getTableColumns(tableName);\n }\n return result;\n } catch (err: any) {\n throw new DriverError(`Failed to fetch all table columns: ${err.message}`);\n }\n }\n\n private mapSQLiteType(type: string): ColumnMetadata[\"type\"] {\n const upper = type.toUpperCase();\n if (upper.includes(\"INT\")) {\n return \"integer\";\n }\n if (upper.includes(\"CHAR\") || upper.includes(\"TEXT\") || upper.includes(\"CLOB\")) {\n return \"text\";\n }\n if (upper.includes(\"REAL\") || upper.includes(\"FLOAT\") || upper.includes(\"DOUBLE\")) {\n return \"float\";\n }\n if (upper.includes(\"BLOB\")) {\n return \"blob\";\n }\n return \"text\";\n }\n}\n"],"mappings":"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"}