Created
April 17, 2024 15:04
-
-
Save fl0wo/ddd552ea319c78b29ded6b940e7584c6 to your computer and use it in GitHub Desktop.
UpdateRowBeforeAndAfterPlugin using LibSQLPlugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TableNamesTurso = is just a type containing all the "names of the tables" | |
If you have drizzle: export type TableNamesTurso = keyof NonNullable<typeof schema>; // use ur db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {LibSQLPlugin} from "libsql-client-hooks"; | |
import { InStatement, Client, ResultSet } from '@libsql/core/api'; | |
import {isUpdateForTable, removeSpaces} from "./utils"; | |
import {TableNamesTurso} from "../index"; | |
export class UpdateRowBeforeAndAfterPlugin<T> implements LibSQLPlugin { | |
private rowBefore: T | undefined; | |
constructor( | |
private readonly tableName: TableNamesTurso, | |
private readonly queryGetRowBeforeById: (id: any) => Promise<T>, | |
private readonly execWithBeforeAndAfter: (rowBefore: T, rowAfter: T) => Promise<void> | |
) { | |
} | |
async beforeExecute(query: InStatement, __: Client){ | |
if(!isUpdateForTable(query, this.tableName)) { | |
return query; | |
} | |
//{ | |
// sql: 'update "trades" set "amount" = ?, "id" = ?, "id_bot" = ?, "placed_by" = ?, "price" = ?, "side" = ?, "symbol" = ?, "timestamp" = ? where "trades"."id" = ? returning "id", "id_bot", "symbol", "side", "amount", "price", "placed_by", "fee_rate", "fee_coin", "fee_type", "fee_cost", "profit", "profit_percentage", "timestamp", "order", "type", "taker_or_maker", "cost", "created_at", "updated_at"', | |
// args: [ | |
// 0, | |
// 'fake-trade-test', | |
// 'test_bot_id', | |
// 'bot', | |
// 0, | |
// 'sell', | |
// '', | |
// 1713352086126, | |
// 'fake-trade-test' | |
// ] | |
// } | |
// 1. Find the index of the ? for the "id" field | |
const txtQuery = removeSpaces((query as any)?.sql); | |
const idIndex = txtQuery.indexOf('"id"=?'); | |
const txtQueryBefore = txtQuery.substring(0,idIndex); | |
const nQMarksBefore = txtQueryBefore.split('?').length - 1; | |
// 2. Get the value of the ? for the "id" field | |
const args = (query as any)?.args; | |
const rowId = args?.[nQMarksBefore]; | |
// 3. Get the row before the update | |
this.rowBefore = await this.queryGetRowBeforeById(rowId); | |
return query; | |
} | |
async afterExecute(result: ResultSet, query: InStatement, ___: Client){ | |
if(!isUpdateForTable(query)) { | |
return result; | |
} | |
if(!this.rowBefore) { | |
throw new Error('Row before is not set'); | |
} | |
if(result.rows.length !== 1) { | |
throw new Error('Expected one row to be returned'); | |
} | |
await this.execWithBeforeAndAfter(this.rowBefore, result.rows[0] as T); | |
return result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function isUpdateForTable(query: any, tableName?: string): boolean { | |
if(!tableName) { | |
// only check that is an update query | |
return /update/i.test(typeof query === "string" ? query : query.sql); | |
} | |
const escapedTableName = tableName.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
const regexp = new RegExp(`update "?${escapedTableName}"? set`, 'i'); | |
return regexp.test(typeof query === "string" ? query : query.sql); | |
} | |
export function removeSpaces(txt: string) { | |
if(!txt) return txt; | |
return txt.replace(/\s/g, ''); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Before: {
id: 'fake-trade-test',
idBot: 'test_bot_id',
symbol: '',
side: 'sell',
amount: 0,
price: 0,
placedBy: 'bot',
feeRate: null,
feeCoin: null,
feeType: null,
feeCost: null,
profit: null,
profitPercentage: null,
timestamp: 2024-04-17T14:56:42.609Z,
order: null,
type: null,
takerOrMaker: null,
cost: null,
createdAt: 1970-01-20T19:55:51.741Z,
updatedAt: 1970-01-20T19:55:51.741Z
}
After: {
id: 'fake-trade-test',
id_bot: 'test_bot_id',
symbol: '',
side: 'sell',
amount: 0,
price: 0,
placed_by: 'bot',
fee_rate: null,
fee_coin: null,
fee_type: null,
fee_cost: null,
profit: null,
profit_percentage: null,
timestamp: 1713365992938,
order: null,
type: null,
taker_or_maker: null,
cost: null,
created_at: 1713351741,
updated_at: 1713351741
}