Skip to content

Commit

Permalink
chore: update typeorm adapter, add docs (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
Papooch authored Apr 22, 2024
1 parent a2a8e5a commit c019a2d
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# TypeOrm adapter
# TypeORM adapter

## Installation

Expand Down Expand Up @@ -29,6 +29,14 @@ pnpm add @nestjs-cls/transactional-adapter-typeorm
</TabItem>
</Tabs>

:::important

Please note that due to the deliberate choice to _not_ monkey-patch any underlying library, the only way to propagate the transaction using this adapter is by using the `EntityManager`. There is no transactional support for working directly with repositories without getting them through the (transactional) `EntityManager`

For a more fully-featured solution for TypeORM, see the [`typeorm-transactional`](https://github.com/Aliheym/typeorm-transactional) community package.

:::

## Registration

```ts
Expand All @@ -48,3 +56,61 @@ ClsModule.forRoot({
],
}),
```

:::note

When using with `@nestjs/typeorm`, the data source token needs to be retrieved with the `getDataSourceToken` function, that can be optionally provided with a custom connection name.

```ts
import { getDataSourceToken } from '@nestjs/typeorm';
// ...
dataSourceToken: getDataSourceToken(),
```

:::

## Typing & usage

The `tx` property on the `TransactionHost<TransactionalAdapterTypeOrm>` is typed as [`EntityManager`](https://typeorm.io/working-with-entity-manager).

## Example

```ts title="user.service.ts"
@Injectable()
class UserService {
constructor(private readonly userRepository: UserRepository) {}

@Transactional()
async runTransaction() {
// highlight-start
// both methods are executed in the same transaction
const user = await this.userRepository.createUser('John');
const foundUser = await this.userRepository.getUserById(r1.id);
// highlight-end
assert(foundUser.id === user.id);
}
}
```

```ts title="user.repository.ts"
@Injectable()
class UserRepository {
constructor(
private readonly txHost: TransactionHost<TransactionalAdapterTypeOrm>,
) {}

async getUserById(id: number) {
// highlight-start
// txHost.tx is typed as EntityManager
return await this.txHost.tx.getRepository(User).findOneBy({ id });
// highlight-end
}

async createUser(name: string, email: string) {
return await this.txHost.tx.getRepository(User).save({
name,
email: `${name}@email.com`,
});
}
}
```

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestjs-cls/transactional-adapter-typeorm",
"version": "1.2.0",
"version": "1.0.0",
"description": "A typeorm adapter for @nestjs-cls/transactional",
"author": "Giosuè Delgado S.Z. - Relybytes Srl <info@relybytes.com>",
"license": "MIT",
Expand Down Expand Up @@ -64,4 +64,4 @@
"typeorm": "0.3.20",
"typescript": "5.0"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { DataSource, EntityManager } from 'typeorm';
import {
TypeOrmTransactionOptions,
TypeOrmTransactionalAdapterOptions,
} from './transactional-options';
import { TransactionalAdapter } from '@nestjs-cls/transactional';
import { DataSource, EntityManager } from 'typeorm';
import type { IsolationLevel } from 'typeorm/driver/types/IsolationLevel';

export interface TypeOrmTransactionalAdapterOptions {
/**
* The injection token for the TypeORM DataSource instance.
*/
dataSourceToken: any;
}

export interface TypeOrmTransactionOptions {
isolationLevel: IsolationLevel;
}

export class TransactionalAdapterTypeOrm
implements
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ services:
db:
image: postgres:15
ports:
- 5444:5432
- 5446:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
ClsPluginTransactional,
InjectTransaction,
Transaction,
Transactional,
TransactionHost,
} from '@nestjs-cls/transactional';
Expand All @@ -25,7 +27,7 @@ class User {
const dataSource = new DataSource({
type: 'postgres',
host: 'localhost',
port: 5444,
port: 5446,
username: 'postgres',
password: 'postgres',
database: 'postgres',
Expand All @@ -36,17 +38,16 @@ const dataSource = new DataSource({
@Injectable()
class UserRepository {
constructor(
private readonly transactionHost: TransactionHost<TransactionalAdapterTypeOrm>,
@InjectTransaction()
private readonly tx: Transaction<TransactionalAdapterTypeOrm>,
) {}

async getUserById(id: number) {
return await this.transactionHost.tx
.getRepository(User)
.findOneBy({ id });
return await this.tx.getRepository(User).findOneBy({ id });
}

async createUser(name: string) {
return await this.transactionHost.tx.getRepository(User).save({
return await this.tx.getRepository(User).save({
name,
email: `${name}@email.com`,
});
Expand All @@ -58,8 +59,7 @@ class UserService {
constructor(
private readonly userRepository: UserRepository,
private readonly transactionHost: TransactionHost<TransactionalAdapterTypeOrm>,

private datasource: DataSource,
private readonly dataSource: DataSource,
) {}

@Transactional()
Expand All @@ -74,7 +74,7 @@ class UserService {
})
async transactionWithDecoratorWithOptions() {
const r1 = await this.userRepository.createUser('James');
const r2 = await this.datasource
const r2 = await this.dataSource
.getRepository(User)
.createQueryBuilder('user')
.where('user.id = :id', { id: r1.id })
Expand All @@ -88,7 +88,7 @@ class UserService {
{ isolationLevel: 'SERIALIZABLE' },
async () => {
const r1 = await this.userRepository.createUser('Joe');
const r2 = await this.datasource
const r2 = await this.dataSource
.getRepository(User)
.createQueryBuilder('user')
.where('user.id = :id', { id: r1.id })
Expand Down Expand Up @@ -129,6 +129,7 @@ class TypeOrmModule {}
adapter: new TransactionalAdapterTypeOrm({
dataSourceToken: DataSource,
}),
enableTransactionProxy: true,
}),
],
}),
Expand Down

0 comments on commit c019a2d

Please sign in to comment.