mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-31 00:16:47 +01:00
0da48cc0d1
## About the changes This transactional implementation decorates a service with a transactional method that removes the need to start transactions in the method using the service. This is a gradual rollout with a feature toggle, just because transactions are not easy.
54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
import { Knex } from 'knex';
|
|
|
|
export type KnexTransaction = Knex.Transaction;
|
|
|
|
export type MockTransaction = null;
|
|
|
|
export type UnleashTransaction = KnexTransaction | MockTransaction;
|
|
|
|
export type TransactionCreator<S> = <T>(
|
|
scope: (trx: S) => void | Promise<T>,
|
|
) => Promise<T>;
|
|
|
|
export const createKnexTransactionStarter = (
|
|
knex: Knex,
|
|
): TransactionCreator<UnleashTransaction> => {
|
|
function transaction<T>(
|
|
scope: (trx: KnexTransaction) => void | Promise<T>,
|
|
) {
|
|
return knex.transaction(scope);
|
|
}
|
|
return transaction;
|
|
};
|
|
|
|
export type DbServiceFactory<S> = (db: Knex) => S;
|
|
export type WithTransactional<S> = S & {
|
|
transactional: <R>(fn: (service: S) => R) => Promise<R>;
|
|
};
|
|
|
|
export function withTransactional<S>(
|
|
serviceFactory: (db: Knex) => S,
|
|
db: Knex,
|
|
): WithTransactional<S> {
|
|
const service = serviceFactory(db) as WithTransactional<S>;
|
|
|
|
service.transactional = async <R>(fn: (service: S) => R) =>
|
|
db.transaction(async (trx: Knex.Transaction) => {
|
|
const transactionalService = serviceFactory(trx);
|
|
return fn(transactionalService);
|
|
});
|
|
|
|
return service;
|
|
}
|
|
|
|
/** Just for testing purposes */
|
|
export function withFakeTransactional<S>(service: S): WithTransactional<S> {
|
|
const serviceWithFakeTransactional = service as WithTransactional<S>;
|
|
|
|
serviceWithFakeTransactional.transactional = async <R>(
|
|
fn: (service: S) => R,
|
|
) => fn(serviceWithFakeTransactional);
|
|
|
|
return serviceWithFakeTransactional;
|
|
}
|