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

feat(core): add support for alternative loading strategies #556

Merged
merged 14 commits into from
May 18, 2020
Merged

feat(core): add support for alternative loading strategies #556

merged 14 commits into from
May 18, 2020

Conversation

willsoto
Copy link
Contributor

@willsoto willsoto commented May 8, 2020

This adds support for alternate load strategies. As of now, only one additional strategy is supported: joined. Currently, the only way to specify the strategy is on on the decorator for the relationship:

@Entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}

  • Tests
  • Docs
  • Cleanup

Closes #440 (reopen of #517)

@lgtm-com
Copy link

lgtm-com bot commented May 8, 2020

This pull request introduces 2 alerts when merging 9b09658 into 677c9e3 - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

@B4nan
Copy link
Member

B4nan commented May 9, 2020

Can't push to your fork, not sure why. Here is what I did to fix those 2 tests. But for me on local host few more tests are failing, not sure why (namely should load entities in all SQL EM tests).

Index: packages/core/src/EntityManager.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- packages/core/src/EntityManager.ts	(revision c134f3e9b1f086570d40944f9d610c7d078c8512)
+++ packages/core/src/EntityManager.ts	(date 1589031966559)
@@ -586,13 +586,16 @@
     }
 
     const preparedPopulate = this.preparePopulate(entityName, options.populate);
-
     await this.entityLoader.populate(entityName, [entity], preparedPopulate, where, options.orderBy || {}, options.refresh);
 
     return entity;
   }
 
   private preparePopulate(entityName: string, populate?: string | Populate): PopulateOptions[] {
+    if (populate === true) {
+      return [{ field: '*', all: true }];
+    }
+
     const meta = this.metadata.get(entityName);
 
     if (Array.isArray(populate)) {
Index: packages/core/src/drivers/IDatabaseDriver.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- packages/core/src/drivers/IDatabaseDriver.ts	(revision c134f3e9b1f086570d40944f9d610c7d078c8512)
+++ packages/core/src/drivers/IDatabaseDriver.ts	(date 1589031926857)
@@ -103,4 +103,5 @@
 export type PopulateOptions = {
   field: string;
   strategy?: LoadStrategy;
+  all?: boolean;
 };
Index: packages/core/src/entity/EntityLoader.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- packages/core/src/entity/EntityLoader.ts	(revision c134f3e9b1f086570d40944f9d610c7d078c8512)
+++ packages/core/src/entity/EntityLoader.ts	(date 1589031919483)
@@ -34,7 +34,7 @@
   }
 
   private normalizePopulate(entityName: string, populate: PopulateOptions[] | true, lookup: boolean): PopulateOptions[] {
-    if (populate === true) {
+    if (populate === true || populate.some(p => p.all)) {
       populate = this.lookupAllRelationships(entityName);
     } else {
       populate = Utils.asArray(populate);

@B4nan
Copy link
Member

B4nan commented May 9, 2020

Btw I believe there are some unresolved comments in the previous PR, right? Like the aliasing of joined tables (books => b1 in the table alias).

@willsoto
Copy link
Contributor Author

willsoto commented May 9, 2020

Thanks! I’ll integrate those changes into my fork...not sure why you can’t push since I’ve allowed edits from maintainers.

and yes, still pending items. I’ve been focused on getting all existing tests passing so I can write more joined load tests

@lgtm-com
Copy link

lgtm-com bot commented May 10, 2020

This pull request introduces 2 alerts when merging ef94fd7 into ff77f9d - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

@willsoto
Copy link
Contributor Author

Referencing #517 (comment), did you have any implementation suggestions? I assume you mean to use the existing aliasCounter on the query builder, maybe even using getNextAlias, but how do you actually use that number to map the results once you get them?

I am currently relying on the order of populate/joinedLoads to be able to match the index once I get results back (eg, if books2 is joined loaded and is index 3 in the populate array, I alias that as b4 and then when I map that result and iterate over the joined loads, I know that b4 maps to the correct entity)

It's less clear to me how I would use the aliasCounter when reading the results back, does it get reset at some point so I can just iterate again and have those numbers match up?

@B4nan
Copy link
Member

B4nan commented May 10, 2020

Maybe reuse qb.getNextAlias(), changing the logic so it uses the first letter of given entity. Depending on the order sounds a bit fragile, instead we should use qb._aliasMap or qb._joins (take a look at getAliasForEntity, could be also reused).

@B4nan B4nan mentioned this pull request May 11, 2020
46 tasks
@willsoto
Copy link
Contributor Author

willsoto commented May 12, 2020

So, I agree that relying on index is brittle and I have been familiarizing myself with the code you suggested. I do have a couple of questions though:

  • Based on our previous discussions, a lot of the logic for this ended up living inside the AbstractSqlDriver, do you expect that to change? _joins and _alias are private to the query builder and looking at their usage the methods in that class manipulate those objects directly.
  • getAliasForEntity expects a CriteriaNode but I'm not yet clear on how those actually come to be. So the question is how should I use that? 🙃

I definitely feel like the pieces are there but I'm not sure how much you expect to change (eg, should most of the logic move into the QueryBuilder now?

Also, thanks for your patience and help on this, I know you probably could have had this done already. It's been nice to learn a small piece of the codebase though.

@B4nan
Copy link
Member

B4nan commented May 12, 2020

Based on our previous discussions, a lot of the logic for this ended up living inside the AbstractSqlDriver, do you expect that to change? _joins and _alias are private to the query builder and looking at their usage the methods in that class manipulate those objects directly.

QB is using the driver to map queries, so its fine that the mapping part is in driver. But the ultimate goal is to have QB also usable "alone", it will still use driver for executing and mapping the results to entities, but we should be also able to use this new joined strategy with query builder, without using entity manager. That basically means that the internal qb.populate() method should no longer be internal. But when used directly (not from the EM/driver), it should always use the joined strategy (as QB always produces single query).

const authors = await qb.select().populate(['books']).getResult();
// authors[0].books[0] should be populated Book instance via joined strategy, regardless of the books property settings

But that could be delivered as part of another PR (not necessarily by you), as a follow up.

getAliasForEntity expects a CriteriaNode but I'm not yet clear on how those actually come to be. So the question is how should I use that? 🙃

I think I mentioned that it would need to be adjusted by making the node param optional. Or you can create new method that will do exactly what you need, it was just a suggestion (without much thinking/reviewing the current code).

That CriteriaNode thing is used in query conditions automatically, mainly for auto-joining purposes. Here you would need to also handle manual (explicit) joins. But it should work pretty much the same way as with CriteriaNode - you still need something like the path to be sure you are matching the right join (as joining book.author is not the same as book.author.favouriteAuthor - although its the same target entity).

I definitely feel like the pieces are there but I'm not sure how much you expect to change (eg, should most of the logic move into the QueryBuilder now?

I think this should be now answered already, if not, let's discuss concrete parts of the implementation. But the mapping to entities needs to stay in the driver.

Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
@B4nan
Copy link
Member

B4nan commented May 16, 2020

What's the status? I'd like to merge this soon, it does not have to be 100% completed just yet, as long as the tests are passing and we are back on 100% coverage I think we can merge (we are targeting dev branch so not a big deal if something is broken).

I can imagine the pain of rebasing this (and I am holding my horses not rebasing dev with latest changes from master, so trying to make it less painful 😄). It would be probably good for both of us to have this merged asap and define the list of missing things somewhere so we have a clear understanding of where we are, and do them as (maybe more than one) smaller PR(s) on top of this.

I'd like to work on lazy scalar properties next week and I can imagine a lot of merge conflicts If I do it before the core of this is merged. So would be great if we can get this to mergable state soon (but no rush, and thanks for all the work on this!)

@willsoto
Copy link
Contributor Author

Sorry! I was planning on working on the last item you commented on today. The week has been really busy so didn’t get around to it like I’d hoped.

So we can get it merged, I can work on getting test coverage back to 100% instead and then, like you said, have follow-up PRs with fixes and improvements. I know there is missing stuff but I’m starting to feel bad it’s been open for so long lol

Do you prefer I get that last comment addressed and get test coverage back to 100 or just get coverage back?

@B4nan
Copy link
Member

B4nan commented May 16, 2020

No need to be sorry :] I also had quite busy working week...

And no need to rush, I would aim to merge this early next week, but its up to you and your capacity. Would be good to address that aliases thing, if that is what you mean, then I would probably rather wait for that to be implemented.

Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
@lgtm-com
Copy link

lgtm-com bot commented May 16, 2020

This pull request introduces 1 alert when merging dc0dc79 into 3b3eec7 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
@lgtm-com
Copy link

lgtm-com bot commented May 16, 2020

This pull request introduces 1 alert when merging 9293cbe into 3b3eec7 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

This ensures that even if no related records are returned by the joined load,
we still end up with the root entity.

Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
@willsoto
Copy link
Contributor Author

willsoto commented May 17, 2020

@B4nan Okay, so here is where I am at:

  • I've stopped relying on index and instead am relying on the _aliasMap. I'll be honest, I am not sure if it is exactly what you were envisioning but I would be happy to iterate further in subsequent PRs in the interest of getting this merged.
  • I switched to using a left outer join since we still wanted the root entity returned even when there are no records to join. I use the presence of lack thereof of the primary key on the joined entity to determine whether or not I have a record. I hope this is a safe assumption.
  • I added some test.todos to capture some of the work to be done.
  • I still have not handled the case of book.author vs book.author.favouriteAuthor. I hope that is okay for now. I'd personally like to get this merged without that - if you feel it is acceptable - since I think that would be a pretty clean new PR.

WRT coverage, I am not sure what else I can do. Coveralls is not reporting any uncovered lines like it has been so I don't know what else to add 😬

@B4nan
Copy link
Member

B4nan commented May 17, 2020

WRT coverage, I am not sure what else I can do. Coveralls is not reporting any uncovered lines like it has been so I don't know what else to add 😭

It's about branches, not just lines. Also if you used optional chaining somewhere, we might need to ignore that in coverage report via /* istanbul ignore next */, as istanbul would require us to test all the possibilities which is not needed.

Run yarn coverage and check the generated report inside coverage/lcov-report/index.html.

File                              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------------------------|---------|----------|---------|---------|-------------------
All files                         |     100 |    99.91 |     100 |     100 |                   
 cli/src                          |     100 |      100 |     100 |     100 |                   
  CLIHelper.ts                    |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 cli/src/commands                 |     100 |      100 |     100 |     100 |                   
  ClearCacheCommand.ts            |     100 |      100 |     100 |     100 |                   
  DebugCommand.ts                 |     100 |      100 |     100 |     100 |                   
  GenerateCacheCommand.ts         |     100 |      100 |     100 |     100 |                   
  GenerateEntitiesCommand.ts      |     100 |      100 |     100 |     100 |                   
  ImportCommand.ts                |     100 |      100 |     100 |     100 |                   
  MigrationCommandFactory.ts      |     100 |      100 |     100 |     100 |                   
  SchemaCommandFactory.ts         |     100 |      100 |     100 |     100 |                   
 core/src                         |     100 |    99.24 |     100 |     100 |                   
  EntityManager.ts                |     100 |    99.06 |     100 |     100 | 508               
  MikroORM.ts                     |     100 |      100 |     100 |     100 |                   
  enums.ts                        |     100 |      100 |     100 |     100 |                   
  exceptions.ts                   |     100 |      100 |     100 |     100 |                   
  typings.ts                      |     100 |      100 |     100 |     100 |                   
 core/src/cache                   |     100 |      100 |     100 |     100 |                   
  FileCacheAdapter.ts             |     100 |      100 |     100 |     100 |                   
  NullCacheAdapter.ts             |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/connections             |     100 |      100 |     100 |     100 |                   
  Connection.ts                   |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/decorators              |     100 |      100 |     100 |     100 |                   
  Embeddable.ts                   |     100 |      100 |     100 |     100 |                   
  Embedded.ts                     |     100 |      100 |     100 |     100 |                   
  Entity.ts                       |     100 |      100 |     100 |     100 |                   
  Enum.ts                         |     100 |      100 |     100 |     100 |                   
  Formula.ts                      |     100 |      100 |     100 |     100 |                   
  Indexed.ts                      |     100 |      100 |     100 |     100 |                   
  ManyToMany.ts                   |     100 |      100 |     100 |     100 |                   
  ManyToOne.ts                    |     100 |      100 |     100 |     100 |                   
  OneToMany.ts                    |     100 |      100 |     100 |     100 |                   
  OneToOne.ts                     |     100 |      100 |     100 |     100 |                   
  PrimaryKey.ts                   |     100 |      100 |     100 |     100 |                   
  Property.ts                     |     100 |      100 |     100 |     100 |                   
  Repository.ts                   |     100 |      100 |     100 |     100 |                   
  hooks.ts                        |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/drivers                 |     100 |      100 |     100 |     100 |                   
  DatabaseDriver.ts               |     100 |      100 |     100 |     100 |                   
  IDatabaseDriver.ts              |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/entity                  |     100 |      100 |     100 |     100 |                   
  ArrayCollection.ts              |     100 |      100 |     100 |     100 |                   
  BaseEntity.ts                   |     100 |      100 |     100 |     100 |                   
  Collection.ts                   |     100 |      100 |     100 |     100 |                   
  EntityAssigner.ts               |     100 |      100 |     100 |     100 |                   
  EntityFactory.ts                |     100 |      100 |     100 |     100 |                   
  EntityHelper.ts                 |     100 |      100 |     100 |     100 |                   
  EntityIdentifier.ts             |     100 |      100 |     100 |     100 |                   
  EntityLoader.ts                 |     100 |      100 |     100 |     100 |                   
  EntityRepository.ts             |     100 |      100 |     100 |     100 |                   
  EntityTransformer.ts            |     100 |      100 |     100 |     100 |                   
  EntityValidator.ts              |     100 |      100 |     100 |     100 |                   
  Reference.ts                    |     100 |      100 |     100 |     100 |                   
  WrappedEntity.ts                |     100 |      100 |     100 |     100 |                   
  enums.ts                        |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
  wrap.ts                         |     100 |      100 |     100 |     100 |                   
 core/src/hydration               |     100 |      100 |     100 |     100 |                   
  Hydrator.ts                     |     100 |      100 |     100 |     100 |                   
  ObjectHydrator.ts               |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/metadata                |     100 |    99.78 |     100 |     100 |                   
  EntitySchema.ts                 |     100 |    98.92 |     100 |     100 | 291               
  JavaScriptMetadataProvider.ts   |     100 |      100 |     100 |     100 |                   
  MetadataDiscovery.ts            |     100 |      100 |     100 |     100 |                   
  MetadataProvider.ts             |     100 |      100 |     100 |     100 |                   
  MetadataStorage.ts              |     100 |      100 |     100 |     100 |                   
  MetadataValidator.ts            |     100 |      100 |     100 |     100 |                   
  ReflectMetadataProvider.ts      |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/naming-strategy         |     100 |      100 |     100 |     100 |                   
  AbstractNamingStrategy.ts       |     100 |      100 |     100 |     100 |                   
  EntityCaseNamingStrategy.ts     |     100 |      100 |     100 |     100 |                   
  MongoNamingStrategy.ts          |     100 |      100 |     100 |     100 |                   
  UnderscoreNamingStrategy.ts     |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/platforms               |     100 |      100 |     100 |     100 |                   
  ExceptionConverter.ts           |     100 |      100 |     100 |     100 |                   
  Platform.ts                     |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/types                   |     100 |      100 |     100 |     100 |                   
  ArrayType.ts                    |     100 |      100 |     100 |     100 |                   
  BigIntType.ts                   |     100 |      100 |     100 |     100 |                   
  BlobType.ts                     |     100 |      100 |     100 |     100 |                   
  DateType.ts                     |     100 |      100 |     100 |     100 |                   
  JsonType.ts                     |     100 |      100 |     100 |     100 |                   
  TimeType.ts                     |     100 |      100 |     100 |     100 |                   
  Type.ts                         |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/unit-of-work            |     100 |      100 |     100 |     100 |                   
  ChangeSet.ts                    |     100 |      100 |     100 |     100 |                   
  ChangeSetComputer.ts            |     100 |      100 |     100 |     100 |                   
  ChangeSetPersister.ts           |     100 |      100 |     100 |     100 |                   
  CommitOrderCalculator.ts        |     100 |      100 |     100 |     100 |                   
  UnitOfWork.ts                   |     100 |      100 |     100 |     100 |                   
  enums.ts                        |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 core/src/utils                   |     100 |      100 |     100 |     100 |                   
  Configuration.ts                |     100 |      100 |     100 |     100 |                   
  ConfigurationLoader.ts          |     100 |      100 |     100 |     100 |                   
  Logger.ts                       |     100 |      100 |     100 |     100 |                   
  RequestContext.ts               |     100 |      100 |     100 |     100 |                   
  SmartQueryHelper.ts             |     100 |      100 |     100 |     100 |                   
  Utils.ts                        |     100 |      100 |     100 |     100 |                   
  ValidationError.ts              |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 entity-generator/src             |     100 |      100 |     100 |     100 |                   
  EntityGenerator.ts              |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 knex/src                         |     100 |    99.28 |     100 |     100 |                   
  AbstractSqlConnection.ts        |     100 |      100 |     100 |     100 |                   
  AbstractSqlDriver.ts            |     100 |    99.09 |     100 |     100 | 312               
  AbstractSqlPlatform.ts          |     100 |      100 |     100 |     100 |                   
  SqlEntityManager.ts             |     100 |      100 |     100 |     100 |                   
  SqlEntityRepository.ts          |     100 |      100 |     100 |     100 |                   
 knex/src/query                   |     100 |      100 |     100 |     100 |                   
  ArrayCriteriaNode.ts            |     100 |      100 |     100 |     100 |                   
  CriteriaNode.ts                 |     100 |      100 |     100 |     100 |                   
  ObjectCriteriaNode.ts           |     100 |      100 |     100 |     100 |                   
  QueryBuilder.ts                 |     100 |      100 |     100 |     100 |                   
  QueryBuilderHelper.ts           |     100 |      100 |     100 |     100 |                   
  ScalarCriteriaNode.ts           |     100 |      100 |     100 |     100 |                   
  enums.ts                        |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
  internal.ts                     |     100 |      100 |     100 |     100 |                   
 knex/src/schema                  |     100 |      100 |     100 |     100 |                   
  DatabaseSchema.ts               |     100 |      100 |     100 |     100 |                   
  DatabaseTable.ts                |     100 |      100 |     100 |     100 |                   
  SchemaGenerator.ts              |     100 |      100 |     100 |     100 |                   
  SchemaHelper.ts                 |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 mariadb/src                      |     100 |      100 |     100 |     100 |                   
  MariaDbConnection.ts            |     100 |      100 |     100 |     100 |                   
  MariaDbDriver.ts                |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 migrations/src                   |     100 |      100 |     100 |     100 |                   
  Migration.ts                    |     100 |      100 |     100 |     100 |                   
  MigrationGenerator.ts           |     100 |      100 |     100 |     100 |                   
  MigrationRunner.ts              |     100 |      100 |     100 |     100 |                   
  MigrationStorage.ts             |     100 |      100 |     100 |     100 |                   
  Migrator.ts                     |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 mikro-orm/src                    |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 mongodb/src                      |     100 |      100 |     100 |     100 |                   
  MongoConnection.ts              |     100 |      100 |     100 |     100 |                   
  MongoDriver.ts                  |     100 |      100 |     100 |     100 |                   
  MongoEntityManager.ts           |     100 |      100 |     100 |     100 |                   
  MongoEntityRepository.ts        |     100 |      100 |     100 |     100 |                   
  MongoExceptionConverter.ts      |     100 |      100 |     100 |     100 |                   
  MongoPlatform.ts                |     100 |      100 |     100 |     100 |                   
 mysql-base/src                   |     100 |      100 |     100 |     100 |                   
  MySqlConnection.ts              |     100 |      100 |     100 |     100 |                   
  MySqlDriver.ts                  |     100 |      100 |     100 |     100 |                   
  MySqlExceptionConverter.ts      |     100 |      100 |     100 |     100 |                   
  MySqlPlatform.ts                |     100 |      100 |     100 |     100 |                   
  MySqlSchemaHelper.ts            |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 mysql/src                        |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 postgresql/src                   |     100 |      100 |     100 |     100 |                   
  PostgreSqlConnection.ts         |     100 |      100 |     100 |     100 |                   
  PostgreSqlDriver.ts             |     100 |      100 |     100 |     100 |                   
  PostgreSqlExceptionConverter.ts |     100 |      100 |     100 |     100 |                   
  PostgreSqlPlatform.ts           |     100 |      100 |     100 |     100 |                   
  PostgreSqlSchemaHelper.ts       |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 reflection/src                   |     100 |      100 |     100 |     100 |                   
  TsMorphMetadataProvider.ts      |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   
 sqlite/src                       |     100 |      100 |     100 |     100 |                   
  SqliteConnection.ts             |     100 |      100 |     100 |     100 |                   
  SqliteDriver.ts                 |     100 |      100 |     100 |     100 |                   
  SqliteExceptionConverter.ts     |     100 |      100 |     100 |     100 |                   
  SqlitePlatform.ts               |     100 |      100 |     100 |     100 |                   
  SqliteSchemaHelper.ts           |     100 |      100 |     100 |     100 |                   
  index.ts                        |     100 |      100 |     100 |     100 |                   

Signed-off-by: Will Soto <willsoto@users.noreply.github.com>
@willsoto
Copy link
Contributor Author

@B4nan not sure if you get notified on every push, but CI is now passing so you can take a look whenever you get a chance.

@B4nan
Copy link
Member

B4nan commented May 18, 2020

Ok let's merge this and improve via other PRs.

Sorry about the confusion with aliasMap, its not really the way to go, we need the path approach and lookup the alias in _joins map, that way we will be also safe in terms of the book.author vs book.author.favouriteAuthor. Also I don't really like that aliasMap parameter in mapResult, but I will need to think about it more and maybe play with the code myself to understand better all the constraints. Maybe if we put there instance of the QB, it would be more understandable API (as this method is part of the public API). I will be happy to take over that particular problem myself if you want to focus on other things.

Anyway, thanks again!

@B4nan B4nan changed the title Add support for alternative loading strategies feat(core): add support for alternative loading strategies May 18, 2020
@B4nan B4nan merged commit 6d5a5f7 into mikro-orm:dev May 18, 2020
@willsoto
Copy link
Contributor Author

@B4nan Agreed. I considered passing around the query builder at one point for exactly that reason but I also wondered if there was just a better api in general. In hindsight I probably should have made _joins work but was too unfamiliar with the API honestly.

Feel free to reach out once you are done with some of the other work you have in mind. I would love to continue working on this - albeit with smaller more manageable PRs 😆

Thanks again for all the feedback and patience

@willsoto willsoto deleted the feat/loading-strategy branch May 18, 2020 17:39
B4nan pushed a commit that referenced this pull request May 21, 2020
This adds support for alternate load strategies. As of now, only one additional strategy is supported: `joined`. Currently, the only way to specify the strategy is on on the decorator for the relationship:

```ts
@entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}
```

Related: #440
B4nan pushed a commit that referenced this pull request Jun 1, 2020
This adds support for alternate load strategies. As of now, only one additional strategy is supported: `joined`. Currently, the only way to specify the strategy is on on the decorator for the relationship:

```ts
@entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}
```

Related: #440
B4nan pushed a commit that referenced this pull request Jun 5, 2020
This adds support for alternate load strategies. As of now, only one additional strategy is supported: `joined`. Currently, the only way to specify the strategy is on on the decorator for the relationship:

```ts
@entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}
```

Related: #440
B4nan pushed a commit that referenced this pull request Jun 16, 2020
This adds support for alternate load strategies. As of now, only one additional strategy is supported: `joined`. Currently, the only way to specify the strategy is on on the decorator for the relationship:

```ts
@entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}
```

Related: #440
B4nan pushed a commit that referenced this pull request Aug 2, 2020
This adds support for alternate load strategies. As of now, only one additional strategy is supported: `joined`. Currently, the only way to specify the strategy is on on the decorator for the relationship:

```ts
@entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}
```

Related: #440
B4nan pushed a commit that referenced this pull request Aug 9, 2020
This adds support for alternate load strategies. As of now, only one additional strategy is supported: `joined`. Currently, the only way to specify the strategy is on on the decorator for the relationship:

```ts
@entity()
export class Author2 {
  @OneToMany({
    entity: () => Book2,
    mappedBy: 'author',
    orderBy: { title: QueryOrder.ASC },
    strategy: LoadStrategy.JOINED, // new property
  })
  books!: Collection<Book2>;
}
```

Related: #440
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