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

fix(entity-generator): fix generation of entities with identifiers that overlap with core #5273

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

boenrobot
Copy link
Collaborator

@boenrobot boenrobot commented Feb 23, 2024

Accomplished by adding ts-morph as a dependency, and using it to post process the generated sources. On a possible conflict, user identifiers now include a marker ("U$"), to disambiguate them in the input to ts-morph.

On conflict, the prefix "Mikro" is added to MikroORM's imports as an alias, and if even that is not enough, the same prefix will keep being added until the conflict is resolved. Previously, there was a special case for the BaseEntity class. This is now removed in favor of this more general purpose conflict resolution, allowing an entity being named like "Entity" or "Property".

Fixed erroneously included skipped tables.

Ensured that tables that start with a number can also be referenced properly, not merely defined, by moving the "E" prefix addition into the naming strategy.

Copy link

codecov bot commented Feb 23, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.77%. Comparing base (b0c0236) to head (b25d220).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #5273    +/-   ##
========================================
  Coverage   99.77%   99.77%            
========================================
  Files         260      260            
  Lines       17886    17965    +79     
  Branches     3793     4355   +562     
========================================
+ Hits        17845    17924    +79     
  Misses         41       41            

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@boenrobot boenrobot marked this pull request as ready for review February 23, 2024 22:28
@@ -59,7 +59,7 @@
},
"dependencies": {
"@mikro-orm/knex": "6.1.5",
"fs-extra": "11.2.0"
"ts-morph": "21.0.1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I like to introduce this dependency, ts-morph means dependency on the whole TS compiler. Not to mention this has a significant perf hit on its own.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was having some doubts myself due to the performance concerns, but the more I tried to avoid it, the more I realized I am effectively duplicating ts-morph, except in a more error prone and less flexible way.

I had an early version where I tried to have an array of string tokens and custom "import reference" tokens in SourceFile, instead of composing a single string... with the plan being to then deal with the conflicts, and turn the "import reference" token objects into the resolved identifiers, joining all the strings together.

The serializeObject() then proved to be a big obstacle to that plan. Trying to work it into the whole array of tokens idea while still keeping it generic enough would likely incur asimilar performance penalty of its own... Not to mention it would make the SourceFile code infinitely more complex to manage.

So after reading a bit about how to efficiently use ts-morph, I settled on this - doing analysis first (because reading after write causes reparsing...), do only renaming in ts-morph (minimal modifications in general...), and doing only one save in the end to flush all changes (batching IO ops...).

I am not sure how much "dependency on the TS compiler" is an issue, given that it is used during generation, not application runtime. Users should be advised to use the entity generator as a dev dependency anyway, where they likely depend on tsc anyway, for type checking, even if doing builds with babel or swc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except in a more error prone and less flexible way.

You forgot to mention much more faster way, that's why it's done this way. The tests now take +90s because of this change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I found a way to make the happy path (the one without any potential conflicts with core inside a file) to remain pretty much as fast as it is today.

And even when not on the happy path, I did some further optimizations, whereby the scan across all files is done first, rather than scan of one file, then write, then scan of second file, etc. and I minimized the number of modifications, which is where the biggest penalty of all is.

@boenrobot boenrobot force-pushed the mightyMorphinConflictResolvers branch from 316325f to f469d63 Compare February 29, 2024 09:45
@boenrobot boenrobot marked this pull request as draft February 29, 2024 11:57
@boenrobot boenrobot force-pushed the mightyMorphinConflictResolvers branch 6 times, most recently from d822501 to db69d14 Compare February 29, 2024 14:24
@boenrobot
Copy link
Collaborator Author

In trying to optimize this, I found several other issues that are also fixed in this, but do mean that there's a bigger change in the snapshots. Comment at the top updated to match the new commit message 😅

…at overlap with core

Accomplished by adding ts-morph as a dependency, and using it
to post process the generated sources. On a possible conflict,
user identifiers now include a marker ("U$"),
to disambiguate them in the input to ts-morph.

On conflict, the prefix "Mikro" is added to MikroORM's imports as an alias,
and if even that is not enough,
the same prefix will keep being added until the conflict is resolved.
Previously, there was a special case for the BaseEntity class.
This is now removed in favor of this more general purpose conflict resolution,
allowing an entity being named like "Entity" or "Property".

Fixed erroneously included skipped tables, and schemas.

Ensured that tables that start with a number can also be referenced properly, not merely defined,
by moving the "E" prefix addition into the naming strategy.
@boenrobot boenrobot force-pushed the mightyMorphinConflictResolvers branch from 086e98b to b25d220 Compare April 9, 2024 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants