Skip to content

Commit

Permalink
feat: add typeorm car rental write repo, add typeorm transaction mngr
Browse files Browse the repository at this point in the history
  • Loading branch information
haroldcohen committed Nov 16, 2023
1 parent 0523650 commit 8c81b28
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {container} from 'tsyringe';
import TypeORMCarRentalReadRepository from 'src/driven/repositories/typeorm/carRental/read';
import TypeORMCarRentalWriteRepository from "src/driven/repositories/typeorm/carRental/write";
import TypeORMTransactionManager from "src/driven/repositories/typeorm/common/transactionManager";

/**
* Configures tsyringe to use typeORM repositories.
*/
const useTypeORMRepositories = (): void => {
container.register("TransactionManagerInterface", {useClass: TypeORMTransactionManager});
container.register("CarRentalReadRepositoryInterface", {useClass: TypeORMCarRentalReadRepository});
const carRentalReadRepository = container.resolve("CarRentalReadRepositoryInterface");
container.registerInstance("CarRentalReadRepositoryInterface", carRentalReadRepository);
Expand Down
2 changes: 1 addition & 1 deletion src/core/domain/common/interfaces/transactionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default interface TransactionManagerInterface {
/**
* Starts a transaction block, within which change of states will be atomic.
*/
startTransaction(): void;
startTransaction(): Promise<void>;

/**
* Creates and returns a new transaction
Expand Down
2 changes: 1 addition & 1 deletion src/core/useCases/carRental/command/rentACar/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class RentACar {
}

async execute(command: RentACarCommand): Promise<CarRentalDTO> {
this.transactionManager.startTransaction();
await this.transactionManager.startTransaction();
const availableCar = await this.carReadRepository.getOneAvailableCar({
modelId: command.carModelId,
pickupDateTime: command.pickupDateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class InMemoryTransactionManagerProxy implements TransactionManag
this.transaction = null;
}

startTransaction(): void {
async startTransaction(): Promise<void> {
this.transaction = this.transactionManager.newTransaction();
}

Expand Down
8 changes: 4 additions & 4 deletions src/driven/repositories/typeorm/carRental/write.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import CarRentalWriteRepositoryInterface from "src/core/domain/carRental/interfaces/repositories/write";
import CarRentalDTO from "src/core/domain/carRental/dto";
import {TypeORMCarRental} from "src/driven/repositories/typeorm/entities";
import {DataSource, Repository} from "typeorm";
import {inject, singleton} from "tsyringe";
import {DataSource, QueryRunner} from "typeorm";
import {container, inject, singleton} from "tsyringe";

@singleton()
export default class TypeORMCarRentalWriteRepository implements CarRentalWriteRepositoryInterface {
Expand All @@ -14,7 +14,7 @@ export default class TypeORMCarRentalWriteRepository implements CarRentalWriteRe
}

async create(carRentalDTO: CarRentalDTO): Promise<void> {
const repository = this.dataSource.getRepository(TypeORMCarRental);
const queryRunner: QueryRunner = container.resolve("CurrentQueryRunner");
const typeORMCarRental = new TypeORMCarRental();
typeORMCarRental.id = carRentalDTO.id;
typeORMCarRental.totalPrice = carRentalDTO.totalPrice;
Expand All @@ -23,7 +23,7 @@ export default class TypeORMCarRentalWriteRepository implements CarRentalWriteRe
typeORMCarRental.customer = {id: carRentalDTO.customerId};
typeORMCarRental.car = <any>{id: carRentalDTO.car.id};

await repository.save(typeORMCarRental);
await queryRunner.manager.save(typeORMCarRental);
}

}
32 changes: 32 additions & 0 deletions src/driven/repositories/typeorm/common/transactionManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import TransactionManagerInterface from "src/core/domain/common/interfaces/transactionManager";
import TransactionInterface from "src/core/domain/common/interfaces/transaction";
import {DataSource, QueryRunner} from "typeorm";
import {container, inject, singleton} from "tsyringe";

@singleton()
export default class TypeORMTransactionManager implements TransactionManagerInterface {

private readonly dataSource: DataSource;

constructor(@inject("DataSource") dataSource: DataSource) {
this.dataSource = dataSource;
}

async commit(): Promise<void> {
const queryRunner: QueryRunner = container.resolve("CurrentQueryRunner");
await queryRunner.commitTransaction();
await queryRunner.release();
}

// @ts-ignore
newTransaction(): TransactionInterface {
}

async startTransaction(): Promise<void> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
container.register("CurrentQueryRunner", {useValue: queryRunner});
}

}
12 changes: 5 additions & 7 deletions tests/integration/typeorm/carRental/command/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import {runDataSourceBeforeEachOps} from "tests/integration/typeorm/utils/setup"
import DateParser from "tests/utils/dateParser";
import {advanceTo} from "jest-date-mock";
import useTestingUtilities from "tests/configuration/containers/utils";
import {DataSource} from "typeorm";
import {v4} from "uuid";
import {runDataSourceAfterEachOps} from "tests/integration/typeorm/utils/tearDown";
import {
populateCarAndCarModelFromCarRentalTestCase,
populateCustomerFromCarRentalTestCase
} from "tests/integration/typeorm/carRental/utils/populateFromTestCase";
import {expectedCarRentalFromTestCase} from "tests/integration/typeorm/utils/misc";
import TypeORMTransactionManager from "src/driven/repositories/typeorm/common/transactionManager";

describe.each([
{
Expand Down Expand Up @@ -57,6 +57,7 @@ describe.each([
let carRentalToCreate: CarRentalDTO;
let expectedCarRental: CarRentalDTO;
let dateParser: DateParser;
let transactionManager: TypeORMTransactionManager;

beforeAll(() => {
advanceTo(Date.now());
Expand All @@ -70,6 +71,7 @@ describe.each([
repository = container.resolve("CarRentalWriteRepositoryInterface");
readRepository = container.resolve("CarRentalReadRepositoryInterface");
await runDataSourceBeforeEachOps();
transactionManager = container.resolve("TransactionManagerInterface");
await populateCustomerFromCarRentalTestCase(testCase.rental);
await populateCarAndCarModelFromCarRentalTestCase(testCase.rental);
expectedCarRental = expectedCarRentalFromTestCase(
Expand All @@ -84,13 +86,9 @@ describe.each([
})

test(`Create a car rental ${testCase.rental.id} should create one car rental in the database`, async () => {
const dataSource: DataSource = container.resolve("DataSource");
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
await transactionManager.startTransaction();
await repository.create(carRentalToCreate);
await queryRunner.commitTransaction();
await queryRunner.release();
await transactionManager.commit();
const retrievedCarRental = await readRepository.read(testCase.rental.id);
expect(retrievedCarRental.toDTO()).toEqual(expectedCarRental);
})
Expand Down
3 changes: 0 additions & 3 deletions tests/integration/typeorm/carRental/query/read.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import useTestingUtilities from 'tests/configuration/containers/utils';
import TypeORMCarRentalReadRepository from 'src/driven/repositories/typeorm/carRental/read';
import CarRentalDTO from 'src/core/domain/carRental/dto';
import TypeORMCarRentalFactory from 'tests/integration/typeorm/seeding/factories/carRental';
import TypeORMCustomerFactory from 'tests/integration/typeorm/seeding/factories/customer';
import TypeORMCarFactory from 'tests/integration/typeorm/seeding/factories/car';
import TypeORMCarModelFactory from 'tests/integration/typeorm/seeding/factories/carModel';
import {runDataSourceBeforeEachOps} from 'tests/integration/typeorm/utils/setup';
import {runDataSourceAfterEachOps} from 'tests/integration/typeorm/utils/tearDown';
import {
Expand Down

0 comments on commit 8c81b28

Please sign in to comment.