@hedystia/db 2.0.6 → 2.0.8

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 (67) hide show
  1. package/dist/cache/index.mjs +12 -0
  2. package/dist/cache/index.mjs.map +1 -0
  3. package/dist/cache/manager.mjs +156 -153
  4. package/dist/cache/manager.mjs.map +1 -1
  5. package/dist/cache/memory-store.mjs +113 -111
  6. package/dist/cache/memory-store.mjs.map +1 -1
  7. package/dist/cli/commands/migrate.cjs +78 -0
  8. package/dist/cli/commands/migrate.cjs.map +1 -0
  9. package/dist/cli/commands/migrate.mjs +83 -0
  10. package/dist/cli/commands/migrate.mjs.map +1 -0
  11. package/dist/cli/commands/migration.cjs +3 -2
  12. package/dist/cli/commands/migration.cjs.map +1 -1
  13. package/dist/cli/commands/migration.mjs +4 -3
  14. package/dist/cli/commands/migration.mjs.map +1 -1
  15. package/dist/cli.cjs +44 -5
  16. package/dist/cli.cjs.map +1 -1
  17. package/dist/cli.mjs +45 -5
  18. package/dist/cli.mjs.map +1 -1
  19. package/dist/core/database.cjs +75 -29
  20. package/dist/core/database.cjs.map +1 -1
  21. package/dist/core/database.d.cts +11 -0
  22. package/dist/core/database.d.mts +11 -0
  23. package/dist/core/database.mjs +91 -34
  24. package/dist/core/database.mjs.map +1 -1
  25. package/dist/core/repository.mjs +414 -410
  26. package/dist/core/repository.mjs.map +1 -1
  27. package/dist/drivers/driver.mjs +9 -7
  28. package/dist/drivers/driver.mjs.map +1 -1
  29. package/dist/drivers/file.mjs +315 -312
  30. package/dist/drivers/file.mjs.map +1 -1
  31. package/dist/drivers/index.mjs +15 -6
  32. package/dist/drivers/index.mjs.map +1 -1
  33. package/dist/drivers/mysql.mjs +261 -256
  34. package/dist/drivers/mysql.mjs.map +1 -1
  35. package/dist/drivers/sql-compiler.mjs +4 -1
  36. package/dist/drivers/sql-compiler.mjs.map +1 -1
  37. package/dist/drivers/sqlite.cjs +12 -1
  38. package/dist/drivers/sqlite.cjs.map +1 -1
  39. package/dist/drivers/sqlite.mjs +258 -242
  40. package/dist/drivers/sqlite.mjs.map +1 -1
  41. package/dist/errors.mjs +48 -64
  42. package/dist/errors.mjs.map +1 -1
  43. package/dist/index.mjs +21 -9
  44. package/dist/index.mjs.map +1 -1
  45. package/dist/migrations/templates.cjs +4 -3
  46. package/dist/migrations/templates.cjs.map +1 -1
  47. package/dist/migrations/templates.d.cts +3 -2
  48. package/dist/migrations/templates.d.mts +3 -2
  49. package/dist/migrations/templates.mjs +4 -3
  50. package/dist/migrations/templates.mjs.map +1 -1
  51. package/dist/schema/column.mjs +155 -157
  52. package/dist/schema/column.mjs.map +1 -1
  53. package/dist/schema/columns/index.mjs +103 -171
  54. package/dist/schema/columns/index.mjs.map +1 -1
  55. package/dist/schema/index.mjs +15 -0
  56. package/dist/schema/index.mjs.map +1 -0
  57. package/dist/schema/registry.mjs +122 -119
  58. package/dist/schema/registry.mjs.map +1 -1
  59. package/dist/schema/table.mjs +4 -1
  60. package/dist/schema/table.mjs.map +1 -1
  61. package/dist/sync/synchronizer.mjs +2 -1
  62. package/dist/sync/synchronizer.mjs.map +1 -1
  63. package/dist/utils/naming.cjs +9 -0
  64. package/dist/utils/naming.cjs.map +1 -1
  65. package/dist/utils/naming.mjs +9 -1
  66. package/dist/utils/naming.mjs.map +1 -1
  67. package/package.json +1 -1
@@ -1,337 +1,340 @@
1
- import { __require } from "../_virtual/_rolldown/runtime.mjs";
2
- import { DriverError } from "../errors.mjs";
3
- import { BaseDriver } from "./driver.mjs";
1
+ import { __esmMin, __require } from "../_virtual/_rolldown/runtime.mjs";
2
+ import { DriverError, init_errors } from "../errors.mjs";
3
+ import { BaseDriver, init_driver } from "./driver.mjs";
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
5
5
  import { join } from "path";
6
6
  //#region src/drivers/file.ts
7
- /**
8
- * File-based database driver using JSON files for storage
9
- */
10
- var FileDriver = class extends BaseDriver {
11
- config;
12
- data = /* @__PURE__ */ new Map();
13
- constructor(config) {
14
- super();
15
- this.config = config;
16
- }
17
- /**
18
- * Connect to the file database (ensures directory exists and loads data)
19
- */
20
- async connect() {
21
- if (this.connected) return;
22
- if (!existsSync(this.config.directory)) mkdirSync(this.config.directory, { recursive: true });
23
- this.loadAll();
24
- this.connected = true;
25
- }
26
- /**
27
- * Disconnect from the file database (flushes data to disk)
28
- */
29
- async disconnect() {
30
- this.flushAll();
31
- this.data.clear();
32
- this.connected = false;
33
- }
34
- /**
35
- * Execute a SQL-like statement (parsed internally for file driver)
36
- * @param {string} sql - SQL statement
37
- * @param {unknown[]} [params] - Query parameters
38
- * @returns {Promise<any>} Execution result
39
- */
40
- async execute(sql, params = []) {
41
- return this.executeParsed(sql, params);
42
- }
43
- /**
44
- * Execute a SQL-like query
45
- * @param {string} sql - SQL query
46
- * @param {unknown[]} [params] - Query parameters
47
- * @returns {Promise<any[]>} Query results
48
- */
49
- async query(sql, params = []) {
50
- const result = this.executeParsed(sql, params);
51
- return Array.isArray(result) ? result : [];
52
- }
53
- /**
54
- * Check if a table exists
55
- * @param {string} name - Table name
56
- * @returns {Promise<boolean>} Whether the table exists
57
- */
58
- async tableExists(name) {
59
- return this.data.has(name);
60
- }
61
- /**
62
- * Get column metadata for a table
63
- * @param {string} name - Table name
64
- * @returns {Promise<ColumnMetadata[]>} Column metadata
65
- */
66
- async getTableColumns(name) {
67
- const table = this.data.get(name);
68
- if (!table) return [];
69
- return Object.values(table.meta.columns);
70
- }
71
- /**
72
- * Create a table from metadata
73
- * @param {TableMetadata} meta - Table metadata
74
- */
75
- async createTable(meta) {
76
- if (this.data.has(meta.name)) return;
77
- this.data.set(meta.name, {
78
- rows: [],
79
- autoIncrementId: 0,
80
- meta: { columns: [...meta.columns] }
81
- });
82
- this.flush(meta.name);
83
- }
84
- /**
85
- * Drop a table
86
- * @param {string} name - Table name
87
- */
88
- async dropTable(name) {
89
- this.data.delete(name);
90
- const filePath = join(this.config.directory, `${name}.json`);
91
- try {
92
- const { unlinkSync } = await import("fs");
93
- if (existsSync(filePath)) unlinkSync(filePath);
94
- } catch {}
95
- }
96
- /**
97
- * Add a column to a table
98
- * @param {string} table - Table name
99
- * @param {ColumnMetadata} column - Column metadata
100
- */
101
- async addColumn(table, column) {
102
- const tableData = this.data.get(table);
103
- if (!tableData) throw new DriverError(`Table "${table}" does not exist`);
104
- tableData.meta.columns.push(column);
105
- for (const row of tableData.rows) row[column.name] = column.defaultValue ?? null;
106
- this.flush(table);
107
- }
108
- /**
109
- * Drop a column from a table
110
- * @param {string} table - Table name
111
- * @param {string} name - Column name
112
- */
113
- async dropColumn(table, name) {
114
- const tableData = this.data.get(table);
115
- if (!tableData) throw new DriverError(`Table "${table}" does not exist`);
116
- tableData.meta.columns = tableData.meta.columns.filter((c) => c.name !== name);
117
- for (const row of tableData.rows) delete row[name];
118
- this.flush(table);
119
- }
120
- /**
121
- * Rename a column
122
- * @param {string} table - Table name
123
- * @param {string} oldName - Current name
124
- * @param {string} newName - New name
125
- */
126
- async renameColumn(table, oldName, newName) {
127
- const tableData = this.data.get(table);
128
- if (!tableData) throw new DriverError(`Table "${table}" does not exist`);
129
- const col = tableData.meta.columns.find((c) => c.name === oldName);
130
- if (col) col.name = newName;
131
- for (const row of tableData.rows) {
132
- row[newName] = row[oldName];
133
- delete row[oldName];
7
+ var FileDriver;
8
+ var init_file = __esmMin((() => {
9
+ init_errors();
10
+ init_driver();
11
+ FileDriver = class extends BaseDriver {
12
+ config;
13
+ data = /* @__PURE__ */ new Map();
14
+ constructor(config) {
15
+ super();
16
+ this.config = config;
134
17
  }
135
- this.flush(table);
136
- }
137
- /**
138
- * Execute within a transaction (pseudo-transaction for file driver)
139
- * @param {() => Promise<T>} fn - Function to execute
140
- * @returns {Promise<T>} Result
141
- */
142
- async transaction(fn) {
143
- const snapshot = /* @__PURE__ */ new Map();
144
- for (const [name, tableData] of this.data) snapshot.set(name, JSON.stringify(tableData));
145
- try {
146
- const result = await fn();
18
+ /**
19
+ * Connect to the file database (ensures directory exists and loads data)
20
+ */
21
+ async connect() {
22
+ if (this.connected) return;
23
+ if (!existsSync(this.config.directory)) mkdirSync(this.config.directory, { recursive: true });
24
+ this.loadAll();
25
+ this.connected = true;
26
+ }
27
+ /**
28
+ * Disconnect from the file database (flushes data to disk)
29
+ */
30
+ async disconnect() {
147
31
  this.flushAll();
148
- return result;
149
- } catch (err) {
150
- for (const [name, json] of snapshot) this.data.set(name, JSON.parse(json));
151
- throw err;
32
+ this.data.clear();
33
+ this.connected = false;
152
34
  }
153
- }
154
- /**
155
- * Batch fetch all table columns (already in memory for file driver)
156
- */
157
- async getAllTableColumns() {
158
- const result = {};
159
- for (const [name, tableData] of this.data) result[name] = [...tableData.meta.columns];
160
- return result;
161
- }
162
- /**
163
- * Direct access for the repository to perform typed operations
164
- * @param {string} tableName - Table name
165
- * @returns {FileTableData | undefined} Table data
166
- */
167
- getTableData(tableName) {
168
- return this.data.get(tableName);
169
- }
170
- /**
171
- * Insert a row directly into the file store
172
- * @param {string} tableName - Table name
173
- * @param {Record<string, unknown>} row - Row data
174
- * @returns {number} The insert ID
175
- */
176
- insertRow(tableName, row) {
177
- const tableData = this.data.get(tableName);
178
- if (!tableData) throw new DriverError(`Table "${tableName}" does not exist`);
179
- let pkCol = null;
180
- for (const col of tableData.meta.columns) if (col.autoIncrement) {
181
- pkCol = col.name;
182
- break;
35
+ /**
36
+ * Execute a SQL-like statement (parsed internally for file driver)
37
+ * @param {string} sql - SQL statement
38
+ * @param {unknown[]} [params] - Query parameters
39
+ * @returns {Promise<any>} Execution result
40
+ */
41
+ async execute(sql, params = []) {
42
+ return this.executeParsed(sql, params);
183
43
  }
184
- if (pkCol && row[pkCol] === void 0) {
185
- tableData.autoIncrementId++;
186
- row[pkCol] = tableData.autoIncrementId;
44
+ /**
45
+ * Execute a SQL-like query
46
+ * @param {string} sql - SQL query
47
+ * @param {unknown[]} [params] - Query parameters
48
+ * @returns {Promise<any[]>} Query results
49
+ */
50
+ async query(sql, params = []) {
51
+ const result = this.executeParsed(sql, params);
52
+ return Array.isArray(result) ? result : [];
187
53
  }
188
- tableData.rows.push({ ...row });
189
- this.flush(tableName);
190
- return pkCol ? row[pkCol] : 0;
191
- }
192
- /**
193
- * Find rows matching a filter function
194
- * @param {string} tableName - Table name
195
- * @param {(row: Record<string, unknown>) => boolean} filter - Filter function
196
- * @returns {Record<string, unknown>[]} Matching rows
197
- */
198
- findRows(tableName, filter) {
199
- const tableData = this.data.get(tableName);
200
- if (!tableData) return [];
201
- if (!filter) return tableData.rows.map((r) => ({ ...r }));
202
- return tableData.rows.filter(filter).map((r) => ({ ...r }));
203
- }
204
- /**
205
- * Update rows matching a filter
206
- * @param {string} tableName - Table name
207
- * @param {(row: Record<string, unknown>) => boolean} filter - Filter function
208
- * @param {Record<string, unknown>} data - Update data
209
- * @returns {number} Number of affected rows
210
- */
211
- updateRows(tableName, filter, data) {
212
- const tableData = this.data.get(tableName);
213
- if (!tableData) return 0;
214
- let count = 0;
215
- for (const row of tableData.rows) if (filter(row)) {
216
- Object.assign(row, data);
217
- count++;
54
+ /**
55
+ * Check if a table exists
56
+ * @param {string} name - Table name
57
+ * @returns {Promise<boolean>} Whether the table exists
58
+ */
59
+ async tableExists(name) {
60
+ return this.data.has(name);
218
61
  }
219
- if (count > 0) this.flush(tableName);
220
- return count;
221
- }
222
- /**
223
- * Delete rows matching a filter
224
- * @param {string} tableName - Table name
225
- * @param {(row: Record<string, unknown>) => boolean} filter - Filter function
226
- * @returns {number} Number of deleted rows
227
- */
228
- deleteRows(tableName, filter) {
229
- const tableData = this.data.get(tableName);
230
- if (!tableData) return 0;
231
- const before = tableData.rows.length;
232
- tableData.rows = tableData.rows.filter((r) => !filter(r));
233
- const deleted = before - tableData.rows.length;
234
- if (deleted > 0) this.flush(tableName);
235
- return deleted;
236
- }
237
- /**
238
- * Truncate a table
239
- * @param {string} tableName - Table name
240
- */
241
- truncateTable(tableName) {
242
- const tableData = this.data.get(tableName);
243
- if (tableData) {
244
- tableData.rows = [];
245
- tableData.autoIncrementId = 0;
246
- this.flush(tableName);
62
+ /**
63
+ * Get column metadata for a table
64
+ * @param {string} name - Table name
65
+ * @returns {Promise<ColumnMetadata[]>} Column metadata
66
+ */
67
+ async getTableColumns(name) {
68
+ const table = this.data.get(name);
69
+ if (!table) return [];
70
+ return Object.values(table.meta.columns);
247
71
  }
248
- }
249
- /**
250
- * Count rows matching a filter
251
- * @param {string} tableName - Table name
252
- * @param {(row: Record<string, unknown>) => boolean} [filter] - Filter function
253
- * @returns {number} Row count
254
- */
255
- countRows(tableName, filter) {
256
- const tableData = this.data.get(tableName);
257
- if (!tableData) return 0;
258
- if (!filter) return tableData.rows.length;
259
- return tableData.rows.filter(filter).length;
260
- }
261
- loadAll() {
262
- if (!existsSync(this.config.directory)) return;
263
- const { readdirSync } = __require("fs");
264
- const files = readdirSync(this.config.directory);
265
- for (const file of files) if (file.endsWith(".json")) {
266
- const name = file.replace(".json", "");
72
+ /**
73
+ * Create a table from metadata
74
+ * @param {TableMetadata} meta - Table metadata
75
+ */
76
+ async createTable(meta) {
77
+ if (this.data.has(meta.name)) return;
78
+ this.data.set(meta.name, {
79
+ rows: [],
80
+ autoIncrementId: 0,
81
+ meta: { columns: [...meta.columns] }
82
+ });
83
+ this.flush(meta.name);
84
+ }
85
+ /**
86
+ * Drop a table
87
+ * @param {string} name - Table name
88
+ */
89
+ async dropTable(name) {
90
+ this.data.delete(name);
91
+ const filePath = join(this.config.directory, `${name}.json`);
267
92
  try {
268
- const content = readFileSync(join(this.config.directory, file), "utf-8");
269
- this.data.set(name, JSON.parse(content));
93
+ const { unlinkSync } = await import("fs");
94
+ if (existsSync(filePath)) unlinkSync(filePath);
270
95
  } catch {}
271
96
  }
272
- }
273
- flush(tableName) {
274
- const tableData = this.data.get(tableName);
275
- if (!tableData) return;
276
- writeFileSync(join(this.config.directory, `${tableName}.json`), JSON.stringify(tableData, null, 2), "utf-8");
277
- }
278
- flushAll() {
279
- for (const [name] of this.data) this.flush(name);
280
- }
281
- executeParsed(sql, params) {
282
- const trimmed = sql.trim().toUpperCase();
283
- if (trimmed.startsWith("CREATE TABLE")) return {
284
- insertId: 0,
285
- affectedRows: 0
286
- };
287
- if (trimmed.startsWith("DROP TABLE")) {
288
- const match = sql.match(/DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?`?(\w+)`?/i);
289
- if (match?.[1]) this.data.delete(match[1]);
290
- return {
291
- insertId: 0,
292
- affectedRows: 0
293
- };
97
+ /**
98
+ * Add a column to a table
99
+ * @param {string} table - Table name
100
+ * @param {ColumnMetadata} column - Column metadata
101
+ */
102
+ async addColumn(table, column) {
103
+ const tableData = this.data.get(table);
104
+ if (!tableData) throw new DriverError(`Table "${table}" does not exist`);
105
+ tableData.meta.columns.push(column);
106
+ for (const row of tableData.rows) row[column.name] = column.defaultValue ?? null;
107
+ this.flush(table);
294
108
  }
295
- if (trimmed.startsWith("SELECT")) {
296
- const tableMatch = sql.match(/FROM\s+`?(\w+)`?/i);
297
- if (!tableMatch) return [];
298
- const tableName = tableMatch[1];
299
- if (!tableName) return [];
300
- return this.findRows(tableName);
109
+ /**
110
+ * Drop a column from a table
111
+ * @param {string} table - Table name
112
+ * @param {string} name - Column name
113
+ */
114
+ async dropColumn(table, name) {
115
+ const tableData = this.data.get(table);
116
+ if (!tableData) throw new DriverError(`Table "${table}" does not exist`);
117
+ tableData.meta.columns = tableData.meta.columns.filter((c) => c.name !== name);
118
+ for (const row of tableData.rows) delete row[name];
119
+ this.flush(table);
301
120
  }
302
- if (trimmed.startsWith("INSERT")) {
303
- const tableMatch = sql.match(/INTO\s+`?(\w+)`?/i);
304
- if (!tableMatch) return {
305
- insertId: 0,
306
- affectedRows: 0
307
- };
308
- const colMatch = sql.match(/\(([^)]+)\)\s+VALUES/i);
309
- if (!colMatch) return {
310
- insertId: 0,
311
- affectedRows: 0
312
- };
313
- const cols = colMatch[1]?.split(",").map((c) => c.trim().replace(/`/g, ""));
314
- if (!cols) return {
121
+ /**
122
+ * Rename a column
123
+ * @param {string} table - Table name
124
+ * @param {string} oldName - Current name
125
+ * @param {string} newName - New name
126
+ */
127
+ async renameColumn(table, oldName, newName) {
128
+ const tableData = this.data.get(table);
129
+ if (!tableData) throw new DriverError(`Table "${table}" does not exist`);
130
+ const col = tableData.meta.columns.find((c) => c.name === oldName);
131
+ if (col) col.name = newName;
132
+ for (const row of tableData.rows) {
133
+ row[newName] = row[oldName];
134
+ delete row[oldName];
135
+ }
136
+ this.flush(table);
137
+ }
138
+ /**
139
+ * Execute within a transaction (pseudo-transaction for file driver)
140
+ * @param {() => Promise<T>} fn - Function to execute
141
+ * @returns {Promise<T>} Result
142
+ */
143
+ async transaction(fn) {
144
+ const snapshot = /* @__PURE__ */ new Map();
145
+ for (const [name, tableData] of this.data) snapshot.set(name, JSON.stringify(tableData));
146
+ try {
147
+ const result = await fn();
148
+ this.flushAll();
149
+ return result;
150
+ } catch (err) {
151
+ for (const [name, json] of snapshot) this.data.set(name, JSON.parse(json));
152
+ throw err;
153
+ }
154
+ }
155
+ /**
156
+ * Batch fetch all table columns (already in memory for file driver)
157
+ */
158
+ async getAllTableColumns() {
159
+ const result = {};
160
+ for (const [name, tableData] of this.data) result[name] = [...tableData.meta.columns];
161
+ return result;
162
+ }
163
+ /**
164
+ * Direct access for the repository to perform typed operations
165
+ * @param {string} tableName - Table name
166
+ * @returns {FileTableData | undefined} Table data
167
+ */
168
+ getTableData(tableName) {
169
+ return this.data.get(tableName);
170
+ }
171
+ /**
172
+ * Insert a row directly into the file store
173
+ * @param {string} tableName - Table name
174
+ * @param {Record<string, unknown>} row - Row data
175
+ * @returns {number} The insert ID
176
+ */
177
+ insertRow(tableName, row) {
178
+ const tableData = this.data.get(tableName);
179
+ if (!tableData) throw new DriverError(`Table "${tableName}" does not exist`);
180
+ let pkCol = null;
181
+ for (const col of tableData.meta.columns) if (col.autoIncrement) {
182
+ pkCol = col.name;
183
+ break;
184
+ }
185
+ if (pkCol && row[pkCol] === void 0) {
186
+ tableData.autoIncrementId++;
187
+ row[pkCol] = tableData.autoIncrementId;
188
+ }
189
+ tableData.rows.push({ ...row });
190
+ this.flush(tableName);
191
+ return pkCol ? row[pkCol] : 0;
192
+ }
193
+ /**
194
+ * Find rows matching a filter function
195
+ * @param {string} tableName - Table name
196
+ * @param {(row: Record<string, unknown>) => boolean} filter - Filter function
197
+ * @returns {Record<string, unknown>[]} Matching rows
198
+ */
199
+ findRows(tableName, filter) {
200
+ const tableData = this.data.get(tableName);
201
+ if (!tableData) return [];
202
+ if (!filter) return tableData.rows.map((r) => ({ ...r }));
203
+ return tableData.rows.filter(filter).map((r) => ({ ...r }));
204
+ }
205
+ /**
206
+ * Update rows matching a filter
207
+ * @param {string} tableName - Table name
208
+ * @param {(row: Record<string, unknown>) => boolean} filter - Filter function
209
+ * @param {Record<string, unknown>} data - Update data
210
+ * @returns {number} Number of affected rows
211
+ */
212
+ updateRows(tableName, filter, data) {
213
+ const tableData = this.data.get(tableName);
214
+ if (!tableData) return 0;
215
+ let count = 0;
216
+ for (const row of tableData.rows) if (filter(row)) {
217
+ Object.assign(row, data);
218
+ count++;
219
+ }
220
+ if (count > 0) this.flush(tableName);
221
+ return count;
222
+ }
223
+ /**
224
+ * Delete rows matching a filter
225
+ * @param {string} tableName - Table name
226
+ * @param {(row: Record<string, unknown>) => boolean} filter - Filter function
227
+ * @returns {number} Number of deleted rows
228
+ */
229
+ deleteRows(tableName, filter) {
230
+ const tableData = this.data.get(tableName);
231
+ if (!tableData) return 0;
232
+ const before = tableData.rows.length;
233
+ tableData.rows = tableData.rows.filter((r) => !filter(r));
234
+ const deleted = before - tableData.rows.length;
235
+ if (deleted > 0) this.flush(tableName);
236
+ return deleted;
237
+ }
238
+ /**
239
+ * Truncate a table
240
+ * @param {string} tableName - Table name
241
+ */
242
+ truncateTable(tableName) {
243
+ const tableData = this.data.get(tableName);
244
+ if (tableData) {
245
+ tableData.rows = [];
246
+ tableData.autoIncrementId = 0;
247
+ this.flush(tableName);
248
+ }
249
+ }
250
+ /**
251
+ * Count rows matching a filter
252
+ * @param {string} tableName - Table name
253
+ * @param {(row: Record<string, unknown>) => boolean} [filter] - Filter function
254
+ * @returns {number} Row count
255
+ */
256
+ countRows(tableName, filter) {
257
+ const tableData = this.data.get(tableName);
258
+ if (!tableData) return 0;
259
+ if (!filter) return tableData.rows.length;
260
+ return tableData.rows.filter(filter).length;
261
+ }
262
+ loadAll() {
263
+ if (!existsSync(this.config.directory)) return;
264
+ const { readdirSync } = __require("fs");
265
+ const files = readdirSync(this.config.directory);
266
+ for (const file of files) if (file.endsWith(".json")) {
267
+ const name = file.replace(".json", "");
268
+ try {
269
+ const content = readFileSync(join(this.config.directory, file), "utf-8");
270
+ this.data.set(name, JSON.parse(content));
271
+ } catch {}
272
+ }
273
+ }
274
+ flush(tableName) {
275
+ const tableData = this.data.get(tableName);
276
+ if (!tableData) return;
277
+ writeFileSync(join(this.config.directory, `${tableName}.json`), JSON.stringify(tableData, null, 2), "utf-8");
278
+ }
279
+ flushAll() {
280
+ for (const [name] of this.data) this.flush(name);
281
+ }
282
+ executeParsed(sql, params) {
283
+ const trimmed = sql.trim().toUpperCase();
284
+ if (trimmed.startsWith("CREATE TABLE")) return {
315
285
  insertId: 0,
316
286
  affectedRows: 0
317
287
  };
318
- const row = {};
319
- for (let i = 0; i < cols.length; i++) {
320
- const col = cols[i];
321
- if (col) row[col] = params[i];
288
+ if (trimmed.startsWith("DROP TABLE")) {
289
+ const match = sql.match(/DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?`?(\w+)`?/i);
290
+ if (match?.[1]) this.data.delete(match[1]);
291
+ return {
292
+ insertId: 0,
293
+ affectedRows: 0
294
+ };
295
+ }
296
+ if (trimmed.startsWith("SELECT")) {
297
+ const tableMatch = sql.match(/FROM\s+`?(\w+)`?/i);
298
+ if (!tableMatch) return [];
299
+ const tableName = tableMatch[1];
300
+ if (!tableName) return [];
301
+ return this.findRows(tableName);
302
+ }
303
+ if (trimmed.startsWith("INSERT")) {
304
+ const tableMatch = sql.match(/INTO\s+`?(\w+)`?/i);
305
+ if (!tableMatch) return {
306
+ insertId: 0,
307
+ affectedRows: 0
308
+ };
309
+ const colMatch = sql.match(/\(([^)]+)\)\s+VALUES/i);
310
+ if (!colMatch) return {
311
+ insertId: 0,
312
+ affectedRows: 0
313
+ };
314
+ const cols = colMatch[1]?.split(",").map((c) => c.trim().replace(/`/g, ""));
315
+ if (!cols) return {
316
+ insertId: 0,
317
+ affectedRows: 0
318
+ };
319
+ const row = {};
320
+ for (let i = 0; i < cols.length; i++) {
321
+ const col = cols[i];
322
+ if (col) row[col] = params[i];
323
+ }
324
+ return {
325
+ insertId: this.insertRow(tableMatch[1], row),
326
+ affectedRows: 1
327
+ };
322
328
  }
323
329
  return {
324
- insertId: this.insertRow(tableMatch[1], row),
325
- affectedRows: 1
330
+ insertId: 0,
331
+ affectedRows: 0
326
332
  };
327
333
  }
328
- return {
329
- insertId: 0,
330
- affectedRows: 0
331
- };
332
- }
333
- };
334
+ };
335
+ }));
334
336
  //#endregion
335
- export { FileDriver };
337
+ init_file();
338
+ export { FileDriver, init_file };
336
339
 
337
340
  //# sourceMappingURL=file.mjs.map