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 bind params #42

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

Add support for bind params #42

wants to merge 1 commit into from

Conversation

blakeembrey
Copy link
Owner

Follow up from #41 (comment), prototyping a backward compatible way to add bind parameters.

TL;DR adds BIND_PARAM symbol, when seen it increments a counter, counter is used in a new .bind method to output a values list.

@blakeembrey
Copy link
Owner Author

@PhilippSalvisberg here's a simple prototype that's backward compatible.

@@ -12,6 +17,7 @@ export type RawValue = Value | Sql;
* A SQL instance can be nested within each other to build SQL strings.
*/
export class Sql {
readonly bindParams = 0;
Copy link
Owner Author

Choose a reason for hiding this comment

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

The only question to myself is whether values should now become a getter that throws when bindParams > 0? That would ensure the instance isn't incorrectly used without binding params.

@@ -90,6 +101,23 @@ export class Sql {
return value;
}

bind(...params: Value[]) {
Copy link
Owner Author

Choose a reason for hiding this comment

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

Doesn't technically need this method if you know what you're doing, but the array length safety and merging with any non-params seems like a good pattern to enforce.

/**
* A param that's expected to be bound later of included in `values`.
*/
export const BIND_PARAM = Symbol("BIND_PARAM");
Copy link
Owner Author

Choose a reason for hiding this comment

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

Name options:

  • BIND_PARAMETER
  • BIND_VALUE
  • BIND
  • BIND_KEY
  • PARAM

@PhilippSalvisberg
Copy link
Contributor

Thanks for the follow-up.

AFAIU the cases I mentioned in #41 (comment) (bind definitions e.g. for output parameters and executeMany) are not simplified by this change.

I can see that this change simplifies some code for a series of similar SQL statements (bind/execute in a loop). However, using executeMany in OracleDB or a single SQL statement would probably be more efficient.

Maybe I didn't understand the intention and the use case.

@blakeembrey
Copy link
Owner Author

However, using executeMany in OracleDB or a single SQL statement would probably be more efficient.

Good question. I was trying to make it easier to use executeMany. You'd be able to do something like:

const query = sql`UPDATE x SET y = ${BIND_PARAM} WHERE z = ${BIND_PARAM}`;
const result = db.executeMany(query.statement, [[1, 1], [2, 2], [3, 4]]);

However, if you wanted better safety for the params:

const result = db.executeMany(query.statement, [query.bind(1, 1), query.bind(2, 2), query.bind(3, 3)]);

@blakeembrey
Copy link
Owner Author

blakeembrey commented Apr 22, 2024

You are right that it's a very marginal improvement, and you could just use 1 or something and ignore values anyway and it'd work the same as the first example. The only difference would be if you happened to have something like this mixing positions you want to bind later and bind now:

const query = sql`UPDATE x SET y = ${true} WHERE z = ${BIND_PARAM}`;
const result = db.executeMany(query.statement, [query.bind(1), query.bind(2), query.bind(3)]); 
// Would be `[[true, 1], [true, 2], [true, 3]]`.

@PhilippSalvisberg
Copy link
Contributor

(...)

const query = sql`UPDATE x SET y = ${true} WHERE z = ${BIND_PARAM}`;
const result = db.executeMany(query.statement, [query.bind(1), query.bind(2), query.bind(3)]); 
// Would be `[[true, 1], [true, 2], [true, 3]]`.

Excellent example. Thanks for the explanation. I agree. This new feature can simplify the code, especially with many "fixed" bind values and a few delayed bindings.

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