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 em.upsert() method #3525

Merged
merged 1 commit into from
Sep 21, 2022
Merged

feat(core): add em.upsert() method #3525

merged 1 commit into from
Sep 21, 2022

Conversation

B4nan
Copy link
Member

@B4nan B4nan commented Sep 21, 2022

We can use em.upsert() create or update the entity, based on whether it is already present in the database. This method performs an insert on conflict merge query ensuring the database is in sync, returning a managed entity instance. The method accepts either entityName together with the entity data, or just entity instance.

// insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41
const author = await em.upsert(Author, { email: 'foo@bar.com', age: 33 });

The entity data needs to contain either the primary key, or any other unique property. Let's consider the following example, where Author.email is a unique property:

// insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41
// select "id" from "author" where "email" = 'foo@bar.com'
const author = await em.upsert(Author, { email: 'foo@bar.com', age: 33 });

Depending on the driver support, this will either use a returning query, or a separate select query, to fetch the primary key if it's missing from the data.

If the entity is already present in current context, there won't be any queries - instead, the entity data will be assigned and an explicit flush will be required for those changes to be persisted.

Closes #3515

We can use `em.upsert()` create or update the entity, based on whether it is already present in the database.
This method performs an `insert on conflict merge` query ensuring the database is in sync, returning a managed
entity instance. The method accepts either `entityName` together with the entity `data`, or just entity instance.

```ts
// insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41
const author = await em.upsert(Author, { email: 'foo@bar.com', age: 33 });
```

The entity data needs to contain either the primary key, or any other unique property. Let's consider the following
example, where `Author.email` is a unique property:

```ts
// insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41
// select "id" from "author" where "email" = 'foo@bar.com'
const author = await em.upsert(Author, { email: 'foo@bar.com', age: 33 });
```

Depending on the driver support, this will either use a returning query, or a separate select query, to fetch the
primary key if it's missing from the `data`.

If the entity is already present in current context, there won't be any queries - instead, the entity data will be
assigned and an explicit `flush` will be required for those changes to be persisted.
@codecov-commenter
Copy link

codecov-commenter commented Sep 21, 2022

Codecov Report

Base: 99.85% // Head: 99.81% // Decreases project coverage by -0.03% ⚠️

Coverage data is based on head (f6ddc8b) compared to base (dbe8aa4).
Patch coverage: 94.38% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3525      +/-   ##
==========================================
- Coverage   99.85%   99.81%   -0.04%     
==========================================
  Files         210      211       +1     
  Lines       12938    13013      +75     
  Branches     2998     3022      +24     
==========================================
+ Hits        12919    12989      +70     
- Misses         19       24       +5     
Impacted Files Coverage Δ
packages/core/src/drivers/IDatabaseDriver.ts 100.00% <ø> (ø)
packages/core/src/logging/SimpleLogger.ts 89.47% <89.47%> (ø)
packages/core/src/EntityManager.ts 99.46% <92.68%> (-0.54%) ⬇️
packages/core/src/entity/EntityFactory.ts 100.00% <100.00%> (ø)
packages/core/src/entity/EntityHelper.ts 100.00% <100.00%> (ø)
packages/core/src/logging/DefaultLogger.ts 100.00% <100.00%> (ø)
packages/core/src/logging/index.ts 100.00% <100.00%> (ø)
packages/core/src/typings.ts 100.00% <100.00%> (ø)
packages/knex/src/AbstractSqlDriver.ts 99.60% <100.00%> (+<0.01%) ⬆️
packages/mongodb/src/MongoConnection.ts 100.00% <100.00%> (ø)
... and 1 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@B4nan B4nan merged commit 3285cdb into master Sep 21, 2022
@B4nan B4nan deleted the upsert branch September 21, 2022 23:09
@B4nan B4nan restored the upsert branch January 10, 2023 19:11
@B4nan B4nan deleted the upsert branch January 10, 2023 19:17
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.

Create entity if not found
2 participants