fix(deno): return number
s from sqlite driver #62
2 changed files with 72 additions and 6 deletions
|
@ -55,7 +55,7 @@ export abstract class BaseStorageDriver implements IStorageDriver {
|
|||
protected _log!: Logger
|
||||
|
||||
setup(log: Logger): void {
|
||||
this._log = log
|
||||
this._log = log.create('sqlite')
|
||||
}
|
||||
|
||||
protected get loaded(): boolean {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { BaseSqliteStorageDriver, ISqliteDatabase } from '@mtcute/core'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { BaseSqliteStorageDriver, ISqliteDatabase, ISqliteStatement } from '@mtcute/core'
|
||||
|
||||
import { Logger } from '../utils.js'
|
||||
|
||||
import type { BindParameters, Database as TDatabase, Statement as TStatement } from '@db/sqlite'
|
||||
|
||||
let Database: typeof import('@db/sqlite').Database
|
||||
|
||||
|
@ -16,6 +21,66 @@ export interface SqliteStorageDriverOptions {
|
|||
disableWal?: boolean
|
||||
}
|
||||
|
||||
function replaceBigintsWithNumber(obj?: object): object | undefined {
|
||||
if (!obj) return obj
|
||||
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (typeof value === 'bigint') {
|
||||
(obj as any)[key] = Number(value)
|
||||
}
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
class WrappedStatement implements ISqliteStatement {
|
||||
constructor(
|
||||
private stmt: TStatement,
|
||||
private sql: string,
|
||||
private log: Logger,
|
||||
) {}
|
||||
|
||||
run(...params: unknown[]): void {
|
||||
this.log.verbose('RUN %s %o', this.sql, params)
|
||||
this.stmt.run(...(params as BindParameters[]))
|
||||
}
|
||||
|
||||
get(...params: unknown[]): unknown {
|
||||
this.log.verbose('GET %s %o', this.sql, params)
|
||||
|
||||
return replaceBigintsWithNumber(this.stmt.get(...(params as BindParameters[])))
|
||||
}
|
||||
|
||||
all(...params: unknown[]): unknown[] {
|
||||
this.log.verbose('ALL %s %o', this.sql, params)
|
||||
|
||||
return this.stmt.all(...(params as BindParameters[])).map(replaceBigintsWithNumber)
|
||||
}
|
||||
}
|
||||
|
||||
class WrappedDatabase implements ISqliteDatabase {
|
||||
constructor(
|
||||
private db: TDatabase,
|
||||
private log: Logger,
|
||||
) {}
|
||||
|
||||
transaction(fn: any): any {
|
||||
return this.db.transaction(fn)
|
||||
}
|
||||
|
||||
prepare<BindParameters extends unknown[]>(sql: string): ISqliteStatement<BindParameters> {
|
||||
return new WrappedStatement(this.db.prepare(sql), sql, this.log)
|
||||
}
|
||||
|
||||
exec(sql: string): void {
|
||||
this.db.exec(sql)
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.db.close()
|
||||
}
|
||||
}
|
||||
|
||||
export class SqliteStorageDriver extends BaseSqliteStorageDriver {
|
||||
constructor(
|
||||
readonly filename = ':memory:',
|
||||
|
@ -34,14 +99,15 @@ export class SqliteStorageDriver extends BaseSqliteStorageDriver {
|
|||
}
|
||||
|
||||
_createDatabase(): ISqliteDatabase {
|
||||
const db = new Database(this.filename, {
|
||||
int64: true,
|
||||
})
|
||||
// non-int64 mode trims numbers to 32 bits, and we don't want that
|
||||
// but int64 mode returns all numbers as bigints, but mtcute expects them
|
||||
// as numbers, so we need to convert them... thx deno
|
||||
const db = new Database(this.filename, { int64: true })
|
||||
|
||||
if (!this.params?.disableWal) {
|
||||
db.exec('PRAGMA journal_mode = WAL;')
|
||||
}
|
||||
|
||||
return db as ISqliteDatabase
|
||||
return new WrappedDatabase(db, this._log)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue