reshuffle
Version:
Reshuffle is a fast, unopinionated, minimalist integration framework
98 lines (85 loc) • 3 kB
text/typescript
import { PersistentStoreAdapter, Updater } from './types'
import mssql from 'mssql'
export default class MSSQLStoreAdapter implements PersistentStoreAdapter {
private dbValidated = false
constructor(private pool: any, private table: string) {}
private async validateDB(): Promise<void> {
if (!this.dbValidated) {
await this.pool
.request()
.query(
`IF OBJECT_ID('${this.table}', 'U') IS NULL CREATE TABLE ${this.table} (id varchar(250) primary key, value varchar(500))`,
)
this.dbValidated = true
}
}
public async del(key: string): Promise<void> {
await this.validateDB()
await this.pool.request().input('id', key).query(`DELETE FROM ${this.table} WHERE id = @id`)
}
public async get(key: string): Promise<any> {
await this.validateDB()
return await this.getValueForKey(key)
}
private async getValueForKey(key: string): Promise<any> {
const res = await this.pool
.request()
.input('id', key)
.query(`SELECT value FROM ${this.table} WHERE id = @id`)
const rows = res.recordset
return rows?.length ? JSON.parse(rows[0].value) : undefined
}
private async insertUpdate(isInsert: boolean, key: string, value: string) {
if (isInsert) {
await this.pool
.request()
.input('id', key)
.input('value', value)
.query(`INSERT INTO ${this.table} (id, value) VALUES(@id, @value)`)
} else {
await this.pool
.request()
.input('id', key)
.input('value', value)
.query(`UPDATE ${this.table} SET value = @value WHERE id = @id`)
}
}
public async list(): Promise<string[]> {
await this.validateDB()
const res = await this.pool.request().query(`SELECT id FROM ${this.table}`)
const rows = res.recordset
return rows?.length ? rows.map((row: any) => row.id) : undefined
}
public async set(key: string, value: any): Promise<any> {
await this.validateDB()
const transaction = new mssql.Transaction(this.pool)
try {
await transaction.begin()
const valueForKey = await this.getValueForKey(key)
await this.insertUpdate(valueForKey === undefined, key, JSON.stringify(value))
await transaction.commit()
} catch (error) {
await transaction.rollback()
throw error
}
return value
}
public async update(key: string, updater: Updater): Promise<any[]> {
await this.validateDB()
const transaction = new mssql.Transaction(this.pool)
try {
await transaction.begin()
const val = await this.getValueForKey(key)
const oldValue = typeof val === 'object' ? { ...val } : val
const newValue = await updater(oldValue)
if (newValue !== undefined) {
await this.insertUpdate(oldValue === undefined, key, JSON.stringify(newValue))
}
await transaction.commit()
return [oldValue, newValue]
} catch (error) {
await transaction.rollback()
throw error
}
}
}