Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Subcollections Use TransactionRepositories Inside Transactions #37

Closed
elersong opened this issue Jul 13, 2024 · 1 comment · Fixed by #42
Closed

Ensure Subcollections Use TransactionRepositories Inside Transactions #37

elersong opened this issue Jul 13, 2024 · 1 comment · Fixed by #42
Labels
bug Something isn't working enhancement New feature or request from_willyovale An issue described in original project, but never implemented

Comments

@elersong
Copy link
Owner

elersong commented Jul 13, 2024

Description

When interacting with subcollections inside a transaction, the subcollections should also be TransactionRepositories to ensure consistency and proper transaction handling. Currently, subcollections do not automatically switch to TransactionRepositories within transactions.

Steps to Reproduce

  1. Start a transaction and interact with a subcollection.
  2. Observe that the subcollection is not treated as a TransactionRepository.

Expected Behavior

Subcollections should automatically switch to TransactionRepositories when inside a transaction.

Actual Behavior

Subcollections remain as regular repositories, not switching to TransactionRepositories within transactions.

Acceptance Criteria

  • Change the type of ISubCollection<Entity> to ITransactionRepository<Entity> when interacting with subcollections inside a transaction.
  • Ensure that all subcollection interactions within a transaction use the TransactionRepository.
  • Add unit tests to validate the behavior of subcollections within transactions.

Additional Context

  • June 10, 2022: Initial issue raised about the need for subcollections to use TransactionRepositories inside transactions.
  • June 17, 2022: Agreement on the need for the change and a request for a pull request.

Proposed API Changes

  1. Update ISubCollection Type:

    • Change the type of ISubCollection<Entity> to ITransactionRepository<Entity> when inside a transaction.
    interface ISubCollection<Entity> {
      // Existing methods...
    }
    
    interface ITransactionRepository<Entity> extends ISubCollection<Entity> {
      // Additional methods specific to transactions...
    }
  2. Modify Repository Initialization:

    • Ensure that subcollections are initialized as TransactionRepositories when inside a transaction.
    class BaseFirestoreRepository<T> {
      async runTransaction<R>(fn: (tran: Transaction) => Promise<R>): Promise<R> {
        return this.firestore.runTransaction(async tran => {
          const transactionRepository = new TransactionRepository(this.firestoreColRef, tran);
          return await fn(transactionRepository);
        });
      }
    
      private getSubCollectionRepository<U>(subCollection: ISubCollection<U>, tran?: Transaction): ITransactionRepository<U> {
        if (tran) {
          return new TransactionRepository(subCollection, tran);
        }
        return subCollection;
      }
    }
  3. Unit Tests:

    • Add unit tests to validate that subcollections use TransactionRepositories within transactions.
    test('should use TransactionRepository for subcollections inside transactions', async () => {
      const bandRepository = getRepository(Band);
    
      await bandRepository.runTransaction(async tran => {
        const band = await tran.findById('band1');
        const albumsRepo = band.albums;
        expect(albumsRepo).toBeInstanceOf(TransactionRepository);
    
        const album = new Album();
        album.id = 'album1';
        album.name = 'Test Album';
    
        await albumsRepo.create(album);
        const savedAlbum = await albumsRepo.findById('album1');
        expect(savedAlbum.name).toBe('Test Album');
      });
    });

Example Implementation

class Album {
  id: string;
  name: string;
}

@Collection()
class Band {
  id: string;
  name: string;
  formationYear: number;
  genres: Array<string>;

  @SubCollection(Album, 'albums')
  albums: ISubCollection<Album>;
}

const bandRepository = getRepository(Band);

await bandRepository.runTransaction(async tran => {
  const band = await tran.findById('band1');
  const albumsRepo = band.albums; // Should be a TransactionRepository

  const album = new Album();
  album.id = 'album1';
  album.name = 'Test Album';

  await albumsRepo.create(album);
  const savedAlbum = await albumsRepo.findById('album1');
  console.log(savedAlbum.name); // Output: 'Test Album'
});

Original Issue

@elersong elersong added bug Something isn't working enhancement New feature or request from_willyovale An issue described in original project, but never implemented labels Jul 13, 2024
@elersong
Copy link
Owner Author

elersong commented Jul 13, 2024

Potentially connected to #36

  • tomorroN's Issue (Jun 10, 2022): Discusses ensuring subcollections use TransactionRepositories inside transactions.
  • iamgbayer's Issue (Mar 16, 2022): Queries about automatically querying subcollections and could indirectly relate to handling subcollections in transactions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request from_willyovale An issue described in original project, but never implemented
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant