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

Make entity change set available to enable papertrail-like features #637

Closed
maphe opened this issue Jul 2, 2020 · 3 comments
Closed

Make entity change set available to enable papertrail-like features #637

maphe opened this issue Jul 2, 2020 · 3 comments
Labels
enhancement New feature or request

Comments

@maphe
Copy link

maphe commented Jul 2, 2020

Is your feature request related to a problem? Please describe.
I can't find a way to read the change set of an entity. Basically I'd like to implement some kind of papertrail feature where I could log, in a dedicated table (let's call it versions here), the changes that occur to specific entities. That would include the before and after save states of the entity.

Describe the solution you'd like
Ideally I'd like:

  1. a way to read the current change set of an entity: EntityManager.getChangeSet(entity)
  2. a way to write into the versions table upon events like create or update (as far as I understand current limitations on the lifecycle hooks, I can't do it from a @AfterUpdate as it is today). I imagine an event that I can listen to that carries the change set would work.

Describe alternatives you've considered
I've looked at the existing lifecycle hooks but limitations are pretty clear and well explained, seems to be a dead end.
I've dig into the UnitOfWork and ChangeSet code but couldn't find anything relevant.
I would like not to have to use/write a MySQL binlog parser.

Additional context
My end goal is to have something that looks like https://www.npmjs.com/package/sequelize-paper-trail adapted for mikro-orm, but I don't want to ask for the whole thing, I just need the means to do it so I can do it myself.
If you think I already have everything I need today and I just couldn't find it please point me to the relevant functions and classes.

@maphe maphe added the enhancement New feature or request label Jul 2, 2020
B4nan added a commit that referenced this issue Jul 6, 2020
There is a special kind of events executed during the commit phase (flush operation).
They are executed before, during and after the flush, and they are not bound to any
entity in particular.

- `beforeFlush` is executed before change sets are computed, this is the only
  event where it is safe to persist new entities.
- `onFlush` is executed after the change sets are computed.
- `afterFlush` is executed as the last step just before the `flush` call resolves.
  it will be executed even if there are no changes to be flushed.

Flush event args will not contain any entity instance, as they are entity agnostic.
They do contain additional reference to the `UnitOfWork` instance.

Closes #637
@B4nan
Copy link
Member

B4nan commented Jul 6, 2020

#642 will add support for flush events, that should allow you to do this:

class FlushSubscriber implements EventSubscriber {

  async onFlush(args: FlushEventArgs): Promise<void> {
    const changeSets = args.uow.getChangeSets();
    const cs = changeSets.find(cs => cs.type === ChangeSetType.CREATE && cs.name === 'FooBar');

    if (cs) {
      const baz = new FooBaz();
      baz.name = 'dynamic';
      cs.entity.baz = baz;
      args.uow.computeChangeSet(baz)!;
      args.uow.recomputeSingleChangeSet(cs.entity);
    }
  }

}

em.getEventManager().registerSubscriber(new Subscriber());
const bar = new FooBar();
bar.name = 'bar';
await em.persistAndFlush(bar);

It works quite similar to doctrine, you need to explicitly compute the changeset of new entity, as well as recompute changesets of existing entities that you want to change in the subscriber:

https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/events.html#onflush

B4nan added a commit that referenced this issue Jul 6, 2020
There is a special kind of events executed during the commit phase (flush operation).
They are executed before, during and after the flush, and they are not bound to any
entity in particular.

- `beforeFlush` is executed before change sets are computed, this is the only
  event where it is safe to persist new entities.
- `onFlush` is executed after the change sets are computed.
- `afterFlush` is executed as the last step just before the `flush` call resolves.
  it will be executed even if there are no changes to be flushed.

Flush event args will not contain any entity instance, as they are entity agnostic.
They do contain additional reference to the `UnitOfWork` instance.

Closes #637
@maphe
Copy link
Author

maphe commented Jul 6, 2020

Nice, thanks, I'll try it out when it's merged.

B4nan added a commit that referenced this issue Jul 6, 2020
There is a special kind of events executed during the commit phase (flush operation).
They are executed before, during and after the flush, and they are not bound to any
entity in particular.

- `beforeFlush` is executed before change sets are computed, this is the only
  event where it is safe to persist new entities.
- `onFlush` is executed after the change sets are computed.
- `afterFlush` is executed as the last step just before the `flush` call resolves.
  it will be executed even if there are no changes to be flushed.

Flush event args will not contain any entity instance, as they are entity agnostic.
They do contain additional reference to the `UnitOfWork` instance.

Closes #637
@B4nan B4nan mentioned this issue Jul 6, 2020
46 tasks
B4nan added a commit that referenced this issue Jul 6, 2020
There is a special kind of events executed during the commit phase (flush operation).
They are executed before, during and after the flush, and they are not bound to any
entity in particular.

- `beforeFlush` is executed before change sets are computed, this is the only
  event where it is safe to persist new entities.
- `onFlush` is executed after the change sets are computed.
- `afterFlush` is executed as the last step just before the `flush` call resolves.
  it will be executed even if there are no changes to be flushed.

Flush event args will not contain any entity instance, as they are entity agnostic.
They do contain additional reference to the `UnitOfWork` instance.

Closes #637
@B4nan
Copy link
Member

B4nan commented Jul 6, 2020

Closing as #642 is merged, will release new alpha later this week.

@B4nan B4nan closed this as completed Jul 6, 2020
B4nan added a commit that referenced this issue Aug 2, 2020
There is a special kind of events executed during the commit phase (flush operation).
They are executed before, during and after the flush, and they are not bound to any
entity in particular.

- `beforeFlush` is executed before change sets are computed, this is the only
  event where it is safe to persist new entities.
- `onFlush` is executed after the change sets are computed.
- `afterFlush` is executed as the last step just before the `flush` call resolves.
  it will be executed even if there are no changes to be flushed.

Flush event args will not contain any entity instance, as they are entity agnostic.
They do contain additional reference to the `UnitOfWork` instance.

Closes #637
B4nan added a commit that referenced this issue Aug 9, 2020
There is a special kind of events executed during the commit phase (flush operation).
They are executed before, during and after the flush, and they are not bound to any
entity in particular.

- `beforeFlush` is executed before change sets are computed, this is the only
  event where it is safe to persist new entities.
- `onFlush` is executed after the change sets are computed.
- `afterFlush` is executed as the last step just before the `flush` call resolves.
  it will be executed even if there are no changes to be flushed.

Flush event args will not contain any entity instance, as they are entity agnostic.
They do contain additional reference to the `UnitOfWork` instance.

Closes #637
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants