@lobomfz/db 0.3.1 → 0.3.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobomfz/db",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Bun SQLite database with Arktype schemas and typed Kysely client",
5
5
  "keywords": [
6
6
  "arktype",
package/src/database.ts CHANGED
@@ -63,6 +63,7 @@ export class Database<T extends SchemaRecord> {
63
63
  private sqlite: BunDatabase;
64
64
 
65
65
  private columns: ColumnsMap = new Map();
66
+ private tableColumns = new Map<string, Set<string>>();
66
67
 
67
68
  readonly infer: TablesFromSchemas<T> = undefined as any;
68
69
 
@@ -82,7 +83,7 @@ export class Database<T extends SchemaRecord> {
82
83
 
83
84
  this.kysely = new Kysely<TablesFromSchemas<T>>({
84
85
  dialect: new BunSqliteDialect({ database: this.sqlite }),
85
- plugins: [new DeserializePlugin(this.columns, validation), new ParseJSONResultsPlugin()],
86
+ plugins: [new DeserializePlugin(this.columns, this.tableColumns, validation), new ParseJSONResultsPlugin()],
86
87
  });
87
88
  }
88
89
 
@@ -264,6 +265,8 @@ export class Database<T extends SchemaRecord> {
264
265
  }
265
266
 
266
267
  private registerColumns(tableName: string, props: Prop[]) {
268
+ this.tableColumns.set(tableName, new Set(props.map((p) => p.key)));
269
+
267
270
  const colMap = new Map<string, ColumnCoercion>();
268
271
 
269
272
  for (const prop of props) {
@@ -365,8 +368,12 @@ export class Database<T extends SchemaRecord> {
365
368
  reset(table?: keyof T & string): void {
366
369
  const tables = table ? [table] : Object.keys(this.options.schema.tables);
367
370
 
371
+ this.sqlite.run("PRAGMA foreign_keys = OFF");
372
+
368
373
  for (const t of tables) {
369
374
  this.sqlite.run(`DELETE FROM "${t}"`);
370
375
  }
376
+
377
+ this.sqlite.run("PRAGMA foreign_keys = ON");
371
378
  }
372
379
  }
package/src/plugin.ts CHANGED
@@ -23,6 +23,7 @@ export class DeserializePlugin implements KyselyPlugin {
23
23
 
24
24
  constructor(
25
25
  private columns: ColumnsMap,
26
+ private tableColumns: Map<string, Set<string>>,
26
27
  private validation: Required<JsonValidation>,
27
28
  ) {}
28
29
 
@@ -149,47 +150,51 @@ export class DeserializePlugin implements KyselyPlugin {
149
150
  }
150
151
  }
151
152
 
152
- private coerceRow(table: string, row: UnknownRow, cols: Map<string, ColumnCoercion>) {
153
- for (const [col, coercion] of cols) {
154
- if (!(col in row)) {
155
- continue;
153
+ private coerceSingle(table: string, row: UnknownRow, col: string, coercion: ColumnCoercion) {
154
+ if (coercion === "boolean") {
155
+ if (typeof row[col] === "number") {
156
+ row[col] = row[col] === 1;
156
157
  }
157
158
 
158
- if (coercion === "boolean") {
159
- if (typeof row[col] === "number") {
160
- row[col] = row[col] === 1;
161
- }
159
+ return;
160
+ }
162
161
 
163
- continue;
162
+ if (coercion === "date") {
163
+ if (typeof row[col] === "number") {
164
+ row[col] = new Date(row[col] * 1000);
164
165
  }
165
166
 
166
- if (coercion === "date") {
167
- if (typeof row[col] === "number") {
168
- row[col] = new Date(row[col] * 1000);
169
- }
167
+ return;
168
+ }
170
169
 
171
- continue;
172
- }
170
+ if (typeof row[col] !== "string") {
171
+ return;
172
+ }
173
173
 
174
- if (typeof row[col] !== "string") {
175
- continue;
176
- }
174
+ const value = row[col];
177
175
 
178
- const value = row[col];
176
+ let parsed: unknown;
179
177
 
180
- let parsed: unknown;
178
+ try {
179
+ parsed = JSON.parse(value);
180
+ } catch (e) {
181
+ throw new JsonParseError(table, col, value, e);
182
+ }
181
183
 
182
- try {
183
- parsed = JSON.parse(value);
184
- } catch (e) {
185
- throw new JsonParseError(table, col, value, e);
186
- }
184
+ if (this.validation.onRead) {
185
+ this.validateJsonValue(table, col, parsed, coercion.schema);
186
+ }
187
+
188
+ row[col] = parsed;
189
+ }
187
190
 
188
- if (this.validation.onRead) {
189
- this.validateJsonValue(table, col, parsed, coercion.schema);
191
+ private coerceRow(table: string, row: UnknownRow, cols: Map<string, ColumnCoercion>) {
192
+ for (const [col, coercion] of cols) {
193
+ if (!(col in row)) {
194
+ continue;
190
195
  }
191
196
 
192
- row[col] = parsed;
197
+ this.coerceSingle(table, row, col, coercion);
193
198
  }
194
199
  }
195
200
 
@@ -206,14 +211,32 @@ export class DeserializePlugin implements KyselyPlugin {
206
211
  return args.result;
207
212
  }
208
213
 
209
- const cols = this.columns.get(table);
210
-
211
- if (!cols) {
212
- return args.result;
213
- }
214
+ const mainCols = this.columns.get(table);
215
+ const mainTableColumns = this.tableColumns.get(table);
214
216
 
215
217
  for (const row of args.result.rows) {
216
- this.coerceRow(table, row, cols);
218
+ if (mainCols) {
219
+ this.coerceRow(table, row, mainCols);
220
+ }
221
+
222
+ for (const col of Object.keys(row)) {
223
+ if (mainTableColumns?.has(col)) {
224
+ continue;
225
+ }
226
+
227
+ for (const [otherTable, otherCols] of this.columns) {
228
+ if (otherTable === table) {
229
+ continue;
230
+ }
231
+
232
+ const coercion = otherCols.get(col);
233
+
234
+ if (coercion) {
235
+ this.coerceSingle(otherTable, row, col, coercion);
236
+ break;
237
+ }
238
+ }
239
+ }
217
240
  }
218
241
 
219
242
  return { ...args.result };