@dockstat/sqlite-wrapper 1.3.0 → 1.3.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.
- package/index.ts +46 -38
- package/package.json +2 -2
- package/query-builder/base.ts +9 -5
- package/query-builder/delete.ts +9 -3
- package/query-builder/index.ts +6 -5
- package/query-builder/insert.ts +9 -3
- package/query-builder/select.ts +8 -6
- package/query-builder/update.ts +9 -3
- package/utils/index.ts +2 -0
- package/utils/logger.ts +36 -4
- package/utils/transformer.ts +5 -2
package/index.ts
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { Database, type SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
2
3
|
import { QueryBuilder } from "./query-builder/index"
|
|
3
4
|
import type { ColumnDefinition, Parser, TableConstraints, TableOptions, TableSchema } from "./types"
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
// Re-export logger utilities for external use
|
|
7
|
-
export const logger = sqliteLogger
|
|
8
|
-
export const addLoggerParents = addParents
|
|
9
|
-
|
|
10
|
-
// Internal loggers for different components
|
|
11
|
-
const dbLog = createLogger("db")
|
|
12
|
-
const backupLog = createLogger("backup")
|
|
13
|
-
const tableLog = createLogger("table")
|
|
5
|
+
import { createLogger, type SqliteLogger } from "./utils"
|
|
14
6
|
|
|
15
7
|
/**
|
|
16
8
|
* Re-export all types and utilities
|
|
@@ -92,6 +84,10 @@ class DB {
|
|
|
92
84
|
protected dbPath: string
|
|
93
85
|
private autoBackupTimer: ReturnType<typeof setInterval> | null = null
|
|
94
86
|
private autoBackupOptions: AutoBackupOptions | null = null
|
|
87
|
+
private baseLogger: Logger
|
|
88
|
+
private dbLog: SqliteLogger
|
|
89
|
+
private backupLog: SqliteLogger
|
|
90
|
+
private tableLog: SqliteLogger
|
|
95
91
|
|
|
96
92
|
/**
|
|
97
93
|
* Open or create a SQLite database at `path`.
|
|
@@ -99,8 +95,16 @@ class DB {
|
|
|
99
95
|
* @param path - Path to the SQLite file (e.g. "app.db"). Use ":memory:" for in-memory DB.
|
|
100
96
|
* @param options - Optional database configuration
|
|
101
97
|
*/
|
|
102
|
-
constructor(path: string, options?: DBOptions) {
|
|
103
|
-
|
|
98
|
+
constructor(path: string, baseLogger: Logger, options?: DBOptions) {
|
|
99
|
+
this.baseLogger = baseLogger
|
|
100
|
+
|
|
101
|
+
// Wire base logger so sqlite-wrapper logs inherit the same LogHook/parents as the consumer.
|
|
102
|
+
this.dbLog = createLogger("DB", this.baseLogger)
|
|
103
|
+
this.backupLog = createLogger("Backup", this.baseLogger)
|
|
104
|
+
this.tableLog = createLogger("Table", this.baseLogger)
|
|
105
|
+
|
|
106
|
+
this.dbLog.connection(path, "open")
|
|
107
|
+
|
|
104
108
|
this.dbPath = path
|
|
105
109
|
this.db = new Database(path)
|
|
106
110
|
|
|
@@ -129,8 +133,7 @@ class DB {
|
|
|
129
133
|
*/
|
|
130
134
|
private setupAutoBackup(options: AutoBackupOptions): void {
|
|
131
135
|
if (this.dbPath === ":memory:") {
|
|
132
|
-
backupLog.warn("Auto-backup is not available for in-memory databases")
|
|
133
|
-
return
|
|
136
|
+
this.backupLog.warn("Auto-backup is not available for in-memory databases")
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
this.autoBackupOptions = {
|
|
@@ -146,7 +149,7 @@ class DB {
|
|
|
146
149
|
const fs = require("node:fs")
|
|
147
150
|
if (!fs.existsSync(this.autoBackupOptions.directory)) {
|
|
148
151
|
fs.mkdirSync(this.autoBackupOptions.directory, { recursive: true })
|
|
149
|
-
backupLog.info(`Created backup directory: ${this.autoBackupOptions.directory}`)
|
|
152
|
+
this.backupLog.info(`Created backup directory: ${this.autoBackupOptions.directory}`)
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
// Create initial backup
|
|
@@ -157,7 +160,7 @@ class DB {
|
|
|
157
160
|
this.backup()
|
|
158
161
|
}, this.autoBackupOptions.intervalMs)
|
|
159
162
|
|
|
160
|
-
backupLog.info(
|
|
163
|
+
this.backupLog.info(
|
|
161
164
|
`Auto-backup enabled: interval=${this.autoBackupOptions.intervalMs}ms, maxBackups=${this.autoBackupOptions.maxBackups}`
|
|
162
165
|
)
|
|
163
166
|
}
|
|
@@ -194,7 +197,7 @@ class DB {
|
|
|
194
197
|
// Use SQLite's backup API via VACUUM INTO for a consistent backup
|
|
195
198
|
try {
|
|
196
199
|
this.db.run(`VACUUM INTO '${backupPath.replace(/'/g, "''")}'`)
|
|
197
|
-
backupLog.backup("create", backupPath)
|
|
200
|
+
this.backupLog.backup("create", backupPath)
|
|
198
201
|
|
|
199
202
|
// Apply retention policy if auto-backup is enabled
|
|
200
203
|
if (this.autoBackupOptions) {
|
|
@@ -203,7 +206,7 @@ class DB {
|
|
|
203
206
|
|
|
204
207
|
return backupPath
|
|
205
208
|
} catch (error) {
|
|
206
|
-
backupLog.error(`Failed to create backup: ${error}`)
|
|
209
|
+
this.backupLog.error(`Failed to create backup: ${error}`)
|
|
207
210
|
throw error
|
|
208
211
|
}
|
|
209
212
|
}
|
|
@@ -238,12 +241,12 @@ class DB {
|
|
|
238
241
|
const toDelete = files.slice(maxBackups)
|
|
239
242
|
for (const file of toDelete) {
|
|
240
243
|
fs.unlinkSync(file.path)
|
|
241
|
-
backupLog.debug(`Removed old backup: ${file.name}`)
|
|
244
|
+
this.backupLog.debug(`Removed old backup: ${file.name}`)
|
|
242
245
|
}
|
|
243
|
-
backupLog.info(`Retention policy applied: removed ${toDelete.length} old backup(s)`)
|
|
246
|
+
this.backupLog.info(`Retention policy applied: removed ${toDelete.length} old backup(s)`)
|
|
244
247
|
}
|
|
245
248
|
} catch (error) {
|
|
246
|
-
backupLog.error(`Failed to apply retention policy: ${error}`)
|
|
249
|
+
this.backupLog.error(`Failed to apply retention policy: ${error}`)
|
|
247
250
|
}
|
|
248
251
|
}
|
|
249
252
|
|
|
@@ -254,7 +257,8 @@ class DB {
|
|
|
254
257
|
*/
|
|
255
258
|
listBackups(): Array<{ filename: string; path: string; size: number; created: Date }> {
|
|
256
259
|
if (!this.autoBackupOptions) {
|
|
257
|
-
backupLog.warn("Auto-backup is not configured. Use backup() with a custom path instead.")
|
|
260
|
+
this.backupLog.warn("Auto-backup is not configured. Use backup() with a custom path instead.")
|
|
261
|
+
|
|
258
262
|
return []
|
|
259
263
|
}
|
|
260
264
|
|
|
@@ -282,7 +286,7 @@ class DB {
|
|
|
282
286
|
(a: { created: Date }, b: { created: Date }) => b.created.getTime() - a.created.getTime()
|
|
283
287
|
)
|
|
284
288
|
} catch (error) {
|
|
285
|
-
backupLog.error(`Failed to list backups: ${error}`)
|
|
289
|
+
this.backupLog.error(`Failed to list backups: ${error}`)
|
|
286
290
|
return []
|
|
287
291
|
}
|
|
288
292
|
}
|
|
@@ -313,15 +317,15 @@ class DB {
|
|
|
313
317
|
|
|
314
318
|
try {
|
|
315
319
|
fs.copyFileSync(backupPath, restorePath)
|
|
316
|
-
backupLog.backup("restore", backupPath)
|
|
320
|
+
this.backupLog.backup("restore", backupPath)
|
|
317
321
|
|
|
318
322
|
// Reopen database if we closed it
|
|
319
323
|
if (restorePath === this.dbPath) {
|
|
320
324
|
this.db = new Database(this.dbPath)
|
|
321
|
-
dbLog.info("Database connection reopened after restore")
|
|
325
|
+
this.dbLog.info("Database connection reopened after restore")
|
|
322
326
|
}
|
|
323
327
|
} catch (error) {
|
|
324
|
-
backupLog.error(`Failed to restore backup: ${error}`)
|
|
328
|
+
this.backupLog.error(`Failed to restore backup: ${error}`)
|
|
325
329
|
throw error
|
|
326
330
|
}
|
|
327
331
|
}
|
|
@@ -333,7 +337,7 @@ class DB {
|
|
|
333
337
|
if (this.autoBackupTimer) {
|
|
334
338
|
clearInterval(this.autoBackupTimer)
|
|
335
339
|
this.autoBackupTimer = null
|
|
336
|
-
backupLog.info("Auto-backup stopped")
|
|
340
|
+
this.backupLog.info("Auto-backup stopped")
|
|
337
341
|
}
|
|
338
342
|
}
|
|
339
343
|
|
|
@@ -350,7 +354,7 @@ class DB {
|
|
|
350
354
|
*/
|
|
351
355
|
table<T extends Record<string, unknown>>(
|
|
352
356
|
tableName: string,
|
|
353
|
-
parser: Partial<Parser<T>>
|
|
357
|
+
parser: Partial<Parser<T>> = {}
|
|
354
358
|
): QueryBuilder<T> {
|
|
355
359
|
const pObj: Parser<T> = {
|
|
356
360
|
JSON: parser.JSON || [],
|
|
@@ -358,8 +362,8 @@ class DB {
|
|
|
358
362
|
BOOLEAN: parser.BOOLEAN || [],
|
|
359
363
|
}
|
|
360
364
|
|
|
361
|
-
tableLog.debug(`Creating QueryBuilder for: ${tableName}`)
|
|
362
|
-
return new QueryBuilder<T>(this.db, tableName, pObj)
|
|
365
|
+
this.tableLog.debug(`Creating QueryBuilder for: ${tableName}`)
|
|
366
|
+
return new QueryBuilder<T>(this.db, tableName, pObj, this.baseLogger)
|
|
363
367
|
}
|
|
364
368
|
|
|
365
369
|
/**
|
|
@@ -367,7 +371,7 @@ class DB {
|
|
|
367
371
|
* Also stops auto-backup if it's running.
|
|
368
372
|
*/
|
|
369
373
|
close(): void {
|
|
370
|
-
dbLog.connection(this.dbPath, "close")
|
|
374
|
+
this.dbLog.connection(this.dbPath, "close")
|
|
371
375
|
this.stopAutoBackup()
|
|
372
376
|
this.db.close()
|
|
373
377
|
}
|
|
@@ -521,7 +525,7 @@ class DB {
|
|
|
521
525
|
const allDefinitions = [columnDefs, ...tableConstraints].join(", ")
|
|
522
526
|
|
|
523
527
|
const columnNames = Object.keys(columns)
|
|
524
|
-
tableLog.tableCreate(tableName, columnNames)
|
|
528
|
+
this.tableLog.tableCreate(tableName, columnNames)
|
|
525
529
|
|
|
526
530
|
const sql = `CREATE ${temp}TABLE ${ifNot}${quoteIdent(
|
|
527
531
|
tableName
|
|
@@ -564,7 +568,11 @@ class DB {
|
|
|
564
568
|
BOOLEAN: mergedBoolean,
|
|
565
569
|
}
|
|
566
570
|
|
|
567
|
-
tableLog.parserConfig(
|
|
571
|
+
this.tableLog.parserConfig(
|
|
572
|
+
pObj.JSON.map(String),
|
|
573
|
+
pObj.BOOLEAN.map(String),
|
|
574
|
+
Object.keys(pObj.MODULE)
|
|
575
|
+
)
|
|
568
576
|
|
|
569
577
|
return this.table<_T>(tableName, pObj)
|
|
570
578
|
}
|
|
@@ -883,7 +891,7 @@ class DB {
|
|
|
883
891
|
stmt.run(tableName, comment)
|
|
884
892
|
} catch (error) {
|
|
885
893
|
// Silently ignore if we can't create metadata table
|
|
886
|
-
|
|
894
|
+
this.tableLog.warn(`Could not store table comment for ${tableName}: ${error}`)
|
|
887
895
|
}
|
|
888
896
|
}
|
|
889
897
|
|
|
@@ -906,7 +914,7 @@ class DB {
|
|
|
906
914
|
* runute a raw SQL statement
|
|
907
915
|
*/
|
|
908
916
|
run(sql: string): void {
|
|
909
|
-
|
|
917
|
+
this.tableLog.debug(`Running SQL: ${sql}`)
|
|
910
918
|
this.db.run(sql)
|
|
911
919
|
}
|
|
912
920
|
|
|
@@ -936,7 +944,7 @@ class DB {
|
|
|
936
944
|
* Commit a transaction
|
|
937
945
|
*/
|
|
938
946
|
commit(): void {
|
|
939
|
-
dbLog.transaction("commit")
|
|
947
|
+
this.dbLog.transaction("commit")
|
|
940
948
|
this.run("COMMIT")
|
|
941
949
|
}
|
|
942
950
|
|
|
@@ -944,7 +952,7 @@ class DB {
|
|
|
944
952
|
* Rollback a transaction
|
|
945
953
|
*/
|
|
946
954
|
rollback(): void {
|
|
947
|
-
dbLog.transaction("rollback")
|
|
955
|
+
this.dbLog.transaction("rollback")
|
|
948
956
|
this.run("ROLLBACK")
|
|
949
957
|
}
|
|
950
958
|
|
|
@@ -977,7 +985,7 @@ class DB {
|
|
|
977
985
|
*/
|
|
978
986
|
vacuum() {
|
|
979
987
|
const result = this.db.run("VACUUM")
|
|
980
|
-
dbLog.debug("Vacuum completed")
|
|
988
|
+
this.dbLog.debug("Vacuum completed")
|
|
981
989
|
return result
|
|
982
990
|
}
|
|
983
991
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dockstat/sqlite-wrapper",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "A TypeScript wrapper around bun:sqlite with type-safe query building",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"bun": ">=1.0.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@dockstat/logger": "
|
|
51
|
+
"@dockstat/logger": "workspace:*"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"typescript": "^5.9.3"
|
package/query-builder/base.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Database, SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
2
3
|
import type { Parser, QueryBuilderState } from "../types"
|
|
3
4
|
import {
|
|
4
5
|
createLogger,
|
|
@@ -20,9 +21,9 @@ import {
|
|
|
20
21
|
*/
|
|
21
22
|
export abstract class BaseQueryBuilder<T extends Record<string, unknown>> {
|
|
22
23
|
protected state: QueryBuilderState<T>
|
|
23
|
-
protected log
|
|
24
|
+
protected log: ReturnType<typeof createLogger>
|
|
24
25
|
|
|
25
|
-
constructor(db: Database, tableName: string, parser?: Parser<T
|
|
26
|
+
constructor(db: Database, tableName: string, parser?: Parser<T>, baseLogger?: Logger) {
|
|
26
27
|
this.state = {
|
|
27
28
|
db,
|
|
28
29
|
tableName,
|
|
@@ -32,6 +33,9 @@ export abstract class BaseQueryBuilder<T extends Record<string, unknown>> {
|
|
|
32
33
|
parser,
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
// If a base logger is provided, this will inherit the consumer's LogHook/parents.
|
|
37
|
+
this.log = createLogger("Query", baseLogger)
|
|
38
|
+
|
|
35
39
|
this.log.debug(`QueryBuilder initialized for table: ${tableName}`)
|
|
36
40
|
}
|
|
37
41
|
|
|
@@ -163,14 +167,14 @@ export abstract class BaseQueryBuilder<T extends Record<string, unknown>> {
|
|
|
163
167
|
* (deserialize JSON, convert booleans, etc.)
|
|
164
168
|
*/
|
|
165
169
|
protected transformRowFromDb(row: unknown): T {
|
|
166
|
-
return transformFromDb<T>(row, { parser: this.state.parser })
|
|
170
|
+
return transformFromDb<T>(row, { parser: this.state.parser, logger: this.log })
|
|
167
171
|
}
|
|
168
172
|
|
|
169
173
|
/**
|
|
170
174
|
* Transform multiple rows FROM the database
|
|
171
175
|
*/
|
|
172
176
|
protected transformRowsFromDb(rows: unknown[]): T[] {
|
|
173
|
-
return transformRowsFromDb<T>(rows, { parser: this.state.parser })
|
|
177
|
+
return transformRowsFromDb<T>(rows, { parser: this.state.parser, logger: this.log })
|
|
174
178
|
}
|
|
175
179
|
|
|
176
180
|
/**
|
|
@@ -178,6 +182,6 @@ export abstract class BaseQueryBuilder<T extends Record<string, unknown>> {
|
|
|
178
182
|
* (serialize JSON, stringify functions, etc.)
|
|
179
183
|
*/
|
|
180
184
|
protected transformRowToDb(row: Partial<T>): RowData {
|
|
181
|
-
return transformToDb<T>(row, { parser: this.state.parser })
|
|
185
|
+
return transformToDb<T>(row, { parser: this.state.parser, logger: this.log })
|
|
182
186
|
}
|
|
183
187
|
}
|
package/query-builder/delete.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { SQLQueryBindings } from "bun:sqlite"
|
|
2
|
-
import type {
|
|
1
|
+
import type { Database, SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
3
|
+
import type { DeleteResult, Parser } from "../types"
|
|
3
4
|
import { createLogger, quoteIdentifier } from "../utils"
|
|
4
5
|
import { SelectQueryBuilder } from "./select"
|
|
5
6
|
|
|
@@ -17,7 +18,12 @@ import { SelectQueryBuilder } from "./select"
|
|
|
17
18
|
* - Truncate (explicit full-table delete)
|
|
18
19
|
*/
|
|
19
20
|
export class DeleteQueryBuilder<T extends Record<string, unknown>> extends SelectQueryBuilder<T> {
|
|
20
|
-
private deleteLog
|
|
21
|
+
private deleteLog: ReturnType<typeof createLogger>
|
|
22
|
+
|
|
23
|
+
constructor(db: Database, tableName: string, parser: Parser<T>, baseLogger?: Logger) {
|
|
24
|
+
super(db, tableName, parser, baseLogger)
|
|
25
|
+
this.deleteLog = createLogger("Delete", baseLogger)
|
|
26
|
+
}
|
|
21
27
|
|
|
22
28
|
// ===== Public Delete Methods =====
|
|
23
29
|
|
package/query-builder/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Database, SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
2
3
|
import type {
|
|
3
4
|
ColumnNames,
|
|
4
5
|
DeleteResult,
|
|
@@ -32,12 +33,12 @@ export class QueryBuilder<T extends Record<string, unknown> = Record<string, unk
|
|
|
32
33
|
private updateBuilder: UpdateQueryBuilder<T>
|
|
33
34
|
private deleteBuilder: DeleteQueryBuilder<T>
|
|
34
35
|
|
|
35
|
-
constructor(db: Database, tableName: string, parser: Parser<T
|
|
36
|
+
constructor(db: Database, tableName: string, parser: Parser<T>, baseLogger?: Logger) {
|
|
36
37
|
// Create instances of each specialized builder
|
|
37
|
-
this.selectBuilder = new SelectQueryBuilder<T>(db, tableName, parser)
|
|
38
|
-
this.insertBuilder = new InsertQueryBuilder<T>(db, tableName, parser)
|
|
39
|
-
this.updateBuilder = new UpdateQueryBuilder<T>(db, tableName, parser)
|
|
40
|
-
this.deleteBuilder = new DeleteQueryBuilder<T>(db, tableName, parser)
|
|
38
|
+
this.selectBuilder = new SelectQueryBuilder<T>(db, tableName, parser, baseLogger)
|
|
39
|
+
this.insertBuilder = new InsertQueryBuilder<T>(db, tableName, parser, baseLogger)
|
|
40
|
+
this.updateBuilder = new UpdateQueryBuilder<T>(db, tableName, parser, baseLogger)
|
|
41
|
+
this.deleteBuilder = new DeleteQueryBuilder<T>(db, tableName, parser, baseLogger)
|
|
41
42
|
|
|
42
43
|
// Ensure all builders share the same state for WHERE conditions
|
|
43
44
|
this.syncBuilderStates()
|
package/query-builder/insert.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { SQLQueryBindings } from "bun:sqlite"
|
|
2
|
-
import type {
|
|
1
|
+
import type { Database, SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
3
|
+
import type { InsertOptions, InsertResult, Parser } from "../types"
|
|
3
4
|
import {
|
|
4
5
|
buildPlaceholders,
|
|
5
6
|
createLogger,
|
|
@@ -20,7 +21,12 @@ import { WhereQueryBuilder } from "./where"
|
|
|
20
21
|
* - Automatic JSON/Boolean serialization
|
|
21
22
|
*/
|
|
22
23
|
export class InsertQueryBuilder<T extends Record<string, unknown>> extends WhereQueryBuilder<T> {
|
|
23
|
-
private insertLog
|
|
24
|
+
private insertLog: ReturnType<typeof createLogger>
|
|
25
|
+
|
|
26
|
+
constructor(db: Database, tableName: string, parser: Parser<T>, baseLogger?: Logger) {
|
|
27
|
+
super(db, tableName, parser, baseLogger)
|
|
28
|
+
this.insertLog = createLogger("Insert", baseLogger)
|
|
29
|
+
}
|
|
24
30
|
|
|
25
31
|
// ===== Private Helpers =====
|
|
26
32
|
|
package/query-builder/select.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { SQLQueryBindings } from "bun:sqlite"
|
|
2
|
-
import type {
|
|
1
|
+
import type { Database, SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
3
|
+
import type { ColumnNames, OrderDirection, Parser } from "../types"
|
|
3
4
|
import { createLogger, quoteIdentifier } from "../utils"
|
|
4
5
|
import { WhereQueryBuilder } from "./where"
|
|
5
6
|
|
|
@@ -20,11 +21,12 @@ export class SelectQueryBuilder<T extends Record<string, unknown>> extends Where
|
|
|
20
21
|
private limitValue?: number
|
|
21
22
|
private offsetValue?: number
|
|
22
23
|
|
|
23
|
-
private selectLog
|
|
24
|
+
private selectLog: ReturnType<typeof createLogger>
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
super(db, tableName, parser)
|
|
27
|
-
|
|
26
|
+
constructor(db: Database, tableName: string, parser: Parser<T>, baseLogger?: Logger) {
|
|
27
|
+
super(db, tableName, parser, baseLogger)
|
|
28
|
+
this.selectLog = createLogger("Select", baseLogger)
|
|
29
|
+
}
|
|
28
30
|
|
|
29
31
|
// ===== Query Building Methods =====
|
|
30
32
|
|
package/query-builder/update.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { SQLQueryBindings } from "bun:sqlite"
|
|
2
|
-
import type {
|
|
1
|
+
import type { Database, SQLQueryBindings } from "bun:sqlite"
|
|
2
|
+
import type { Logger } from "@dockstat/logger"
|
|
3
|
+
import type { Parser, UpdateResult } from "../types"
|
|
3
4
|
import { buildSetClause, createLogger, quoteIdentifier, type RowData } from "../utils"
|
|
4
5
|
import { SelectQueryBuilder } from "./select"
|
|
5
6
|
|
|
@@ -15,7 +16,12 @@ import { SelectQueryBuilder } from "./select"
|
|
|
15
16
|
* - Automatic JSON serialization
|
|
16
17
|
*/
|
|
17
18
|
export class UpdateQueryBuilder<T extends Record<string, unknown>> extends SelectQueryBuilder<T> {
|
|
18
|
-
private updateLog
|
|
19
|
+
private updateLog: ReturnType<typeof createLogger>
|
|
20
|
+
|
|
21
|
+
constructor(db: Database, tableName: string, parser: Parser<T>, baseLogger?: Logger) {
|
|
22
|
+
super(db, tableName, parser, baseLogger)
|
|
23
|
+
this.updateLog = createLogger("Update", baseLogger)
|
|
24
|
+
}
|
|
19
25
|
|
|
20
26
|
// ===== Public Update Methods =====
|
|
21
27
|
|
package/utils/index.ts
CHANGED
package/utils/logger.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Logger from "@dockstat/logger"
|
|
1
|
+
import { Logger, type LogHook } from "@dockstat/logger"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Centralized logging for sqlite-wrapper
|
|
@@ -31,8 +31,15 @@ export class SqliteLogger {
|
|
|
31
31
|
private logger: Logger
|
|
32
32
|
private tableName?: string
|
|
33
33
|
|
|
34
|
-
constructor(name: string, parent?: Logger, tableName?: string) {
|
|
35
|
-
|
|
34
|
+
constructor(name: string, parent?: Logger, tableName?: string, logHook?: LogHook) {
|
|
35
|
+
try {
|
|
36
|
+
this.logger =
|
|
37
|
+
typeof parent?.spawn === "function" ? parent.spawn(name) : new Logger(name, [], logHook)
|
|
38
|
+
} catch (error) {
|
|
39
|
+
this.logger = new Logger(name, [], logHook)
|
|
40
|
+
console.error(error)
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
this.tableName = tableName
|
|
37
44
|
}
|
|
38
45
|
|
|
@@ -173,7 +180,12 @@ export const logger = new SqliteLogger("Sqlite")
|
|
|
173
180
|
/**
|
|
174
181
|
* Create a new logger for a specific module
|
|
175
182
|
*/
|
|
176
|
-
export function createLogger(name: string): SqliteLogger {
|
|
183
|
+
export function createLogger(name: string, baseLogger?: Logger): SqliteLogger {
|
|
184
|
+
// If a base logger is provided (recommended for apps/packages that want shared LogHook/parents),
|
|
185
|
+
// derive a sqlite-scoped child logger from it.
|
|
186
|
+
if (baseLogger) return new SqliteLogger(name, baseLogger)
|
|
187
|
+
|
|
188
|
+
// Fallback to the package-level logger (works, but won't automatically inherit app hooks)
|
|
177
189
|
return logger.child(name)
|
|
178
190
|
}
|
|
179
191
|
|
|
@@ -181,4 +193,24 @@ export function addLoggerParents(parents: string[]): void {
|
|
|
181
193
|
logger.addParents(parents)
|
|
182
194
|
}
|
|
183
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Configure a shared LogHook for sqlite-wrapper's root logger.
|
|
198
|
+
*
|
|
199
|
+
* Useful when consumers (e.g. `apps/api`, `packages/db`) want sqlite-wrapper logs
|
|
200
|
+
* to be routed through the same sink/formatter as the rest of the app.
|
|
201
|
+
*/
|
|
202
|
+
export function setSqliteLogHook(logHook: LogHook): void {
|
|
203
|
+
logger.getBaseLogger().setLogHook(logHook)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Optional convenience for consumers: create a sqlite-scoped base Logger that shares a LogHook.
|
|
208
|
+
*
|
|
209
|
+
* This is handy if you want to pass a base logger into `createLogger()` / `DB` and have
|
|
210
|
+
* everything inherit the same hook.
|
|
211
|
+
*/
|
|
212
|
+
export function createSqliteBaseLogger(logHook?: LogHook): Logger {
|
|
213
|
+
return new Logger("Sqlite", [], logHook)
|
|
214
|
+
}
|
|
215
|
+
|
|
184
216
|
export default logger
|
package/utils/transformer.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SQLQueryBindings } from "bun:sqlite"
|
|
2
2
|
import type { Parser } from "../types"
|
|
3
|
-
import { createLogger } from "./logger"
|
|
3
|
+
import { createLogger, type SqliteLogger } from "./logger"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Row Transformer for sqlite-wrapper
|
|
@@ -9,7 +9,7 @@ import { createLogger } from "./logger"
|
|
|
9
9
|
* including JSON columns, Boolean columns, and Module columns.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const defaultLogger = createLogger("Transformer")
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Generic row data type
|
|
@@ -21,6 +21,7 @@ export type RowData = Record<string, SQLQueryBindings>
|
|
|
21
21
|
*/
|
|
22
22
|
export interface TransformOptions<T> {
|
|
23
23
|
parser?: Parser<T>
|
|
24
|
+
logger?: SqliteLogger
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
@@ -43,6 +44,7 @@ export function transformFromDb<T extends Record<string, unknown>>(
|
|
|
43
44
|
return row as T
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
const logger = options?.logger || defaultLogger
|
|
46
48
|
const transformed = { ...row } as RowData
|
|
47
49
|
const transformedColumns: string[] = []
|
|
48
50
|
|
|
@@ -166,6 +168,7 @@ export function transformToDb<T extends Record<string, unknown>>(
|
|
|
166
168
|
return row as RowData
|
|
167
169
|
}
|
|
168
170
|
|
|
171
|
+
const logger = options?.logger || defaultLogger
|
|
169
172
|
const transformed = { ...row } as RowData
|
|
170
173
|
const transformedColumns: string[] = []
|
|
171
174
|
|