elersong / fireorm24

ORM for Firebase Firestore 🔥 updated for 2024
MIT License
1 stars 0 forks source link

Support Custom Repositories in Transactions #30

Open elersong opened 3 months ago

elersong commented 3 months ago

Description

Currently, the transaction object in Fireorm only exposes a getRepository method, which returns a TransactionRepository. This limits the ability to use custom repositories within transactions, as there is no getCustomRepository method available.

Steps to Reproduce

  1. Attempt to use a custom repository within a transaction in Fireorm.
  2. Notice that the transaction object does not provide a getCustomRepository method.

Expected Behavior

Ability to use custom repositories within transactions by providing a getCustomRepository method on the transaction object.

Actual Behavior

The transaction object only exposes a getRepository method, which returns a TransactionRepository.

Acceptance Criteria

Additional Context

Proposed API Changes

  1. Implement getCustomRepository Method:

    • Add a getCustomRepository method to the transaction object to support custom repositories in transactions.
    class Transaction {
     // Existing methods...
    
     getCustomRepository<T>(entity: EntityConstructor<T>): CustomRepository<T> {
       const repository = getCustomRepository(entity);
       // Apply necessary special treatment for transaction
       return new CustomTransactionRepository(repository, this);
     }
    }
  2. Special Treatment for Transaction Repositories:

    • Ensure that custom repositories within transactions receive the necessary special treatment.
    class CustomTransactionRepository<T> extends CustomRepository<T> {
     constructor(repository: CustomRepository<T>, private transaction: Transaction) {
       super(repository);
       // Apply transaction-specific logic
     }
    
     // Override necessary methods to handle transactions
    }
  3. Unit Tests:

    • Create unit tests to validate the functionality of custom repositories within transactions.
    test('should support custom repositories within transactions', async () => {
     const customRepo = transaction.getCustomRepository(CustomEntity);
     const customEntity = new CustomEntity();
     customEntity.name = 'Test Entity';
    
     await transaction.run(async () => {
       await customRepo.create(customEntity);
     });
    
     const fetchedEntity = await customRepo.findById(customEntity.id);
     expect(fetchedEntity.name).toBe('Test Entity');
    });

Example Implementation

@Collection()
class CustomEntity {
  id: string;
  name: string;
}

// Custom repository
class CustomRepository extends BaseRepository<CustomEntity> {
  // Custom methods...
}

// Transaction using custom repository
const customRepo = getCustomRepository(CustomEntity);

await transaction.run(async () => {
  const customRepoInTx = transaction.getCustomRepository(CustomEntity);
  const customEntity = new CustomEntity();
  customEntity.name = 'Test Entity';

  await customRepoInTx.create(customEntity);
});

// Verify the entity was created
const fetchedEntity = await customRepo.findById(customEntity.id);
console.log(fetchedEntity.name); // Output: 'Test Entity'

Original Issue