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

Add support for passing a unique column to queryBuilder for UPSERT st… #63

Closed
wants to merge 1 commit into from

Conversation

azeemhassni
Copy link

The default primary key does work but is not suitable for all situations, there are use cases that need an email or an api key to be used as the conflicting column.

…atements

The default primary key does work but is not suitable for all situations, there are use cases that need an email or an api key to be used as the conflicting column
@changeset-bot
Copy link

changeset-bot bot commented Dec 10, 2022

⚠️ No Changeset found

Latest commit: 7200fa5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@@ -32,6 +32,7 @@ export type GenerateQueryOptions<T extends object> = {
orderBy?: OrderBy<T> | OrderBy<T>[];
data?: Partial<T>;
upsertOnlyUpdateData?: Partial<T>;
uniqueColumn?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Have you run this code against D1 to confirm it works?

Copy link
Author

Choose a reason for hiding this comment

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

I think the type can be a little more strict but otherwise I have tested this on a D1 preview and it works fine.

Copy link
Contributor

@Skye-31 Skye-31 left a comment

Choose a reason for hiding this comment

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

I'm thinking it may be better to update the name of the primaryKeys option to better reflect it's purpose.

@@ -171,9 +172,10 @@ export function GenerateQuery<T extends object>(
.split("")
.join(", ")})`;

const primaryKeyStr = Array.isArray(primaryKeys)
const primaryKeyStr = options.uniqueColumn || (Array.isArray(primaryKeys)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason we can't just use the primary key value for this? It could use a rename - but functionally it appears to do exactly the same

Copy link
Author

Choose a reason for hiding this comment

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

I think this covers a completely different use case, for example I have a table where the primary key is id but when upserting I want to use a different unique column like email, api_key or something similar.

I probably would not want to update the primary key to be email or api_key instead of id. does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we instead renamed the variable to something like conflictConstraint, that would demonstrate it's purpose better, and still allow you to do this.

Copy link
Author

Choose a reason for hiding this comment

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

Are you suggesting to change options.uniqueColumn to options.conflictConstraint or you are thinking more like renaming the primaryKeys in the options passed to the model constructor?

Copy link
Author

Choose a reason for hiding this comment

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

If it's the later then do you not think that would cause issues with the migrations? I was under the impression that you can also create the table using the model configurations.

Copy link
Contributor

Choose a reason for hiding this comment

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

I do mean the latter. This would ideally:

  • Rename the variable in the Query builder
  • Edit the Model#Upsert method to have a new optional parameter for constraint columns, which will default to the primary key(s) if not already present

@@ -291,6 +291,15 @@ describe("Query Builder", () => {
upsertOnlyUpdateData: { id: 1 },
})
).to.not.throw();

expect(() =>
GenerateQuery(QueryType.UPSERT, "test", {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a fault of your test in particular, but we really should be testing the output of these queries too

@Skye-31 Skye-31 marked this pull request as draft February 12, 2023 19:32
@azeemhassni
Copy link
Author

Closing this PR as I don't have enough time to finish the work required here. 😞

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