-
Notifications
You must be signed in to change notification settings - Fork 30
feat: add named params support #92
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Bilux <i.bilux@gmail.com>
Signed-off-by: Bilux <i.bilux@gmail.com>
Signed-off-by: Bilux <i.bilux@gmail.com>
DallasHoff
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good so far.
What do you think about using export type Statement = {
sql: string;
params: unknown[] | Record<string, unknown>;
};The sqlocal/src/drivers/sqlite-memory-driver.ts Line 213 in c105867
Referenced from SQLite wasm: |
Signed-off-by: Bilux <i.bilux@gmail.com>
fc772d2 to
17c2228
Compare
Signed-off-by: Bilux <i.bilux@gmail.com>
wip: testing the sqlite/wasm Bindable typing
|
We can also export the // Use the `normalizeNamedParams` helper function
await sql('INSERT INTO groceries (name) VALUES (:name)', normalizeNamedParams({ name: 'bread' }));
// Or provide a valid binding object instead
await sql('INSERT INTO groceries (name) VALUES (:name)', { ':name': 'bread' });This provide more flexibility, but may introduce some confusion. |
|
Let's not use BindingSpec or BindableValue. Simpler types will suffice. |
|
If you finish making changes, please feel free to request re-review or remove the draft status from the PR. |
I reverted that commit.
Yes, it should be ready for review. |
|
I also left this comment last night. Did you see it and does it make sense? |
Signed-off-by: Bilux <i.bilux@gmail.com>
I didn't notice it. I think that would be better.
The last commit merges |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is all of this new logic that parses the SQL necessary? Ideally, any SQL parsing should be SQLite's job. SQLocal should just be taking the user's SQL and parameters, passing them to SQLite, and returning the results. We shouldn't be duplicating work that SQLite was going to do anyway. Is there a reason it won't work without this preprocessing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is all of this new logic that parses the SQL necessary? Ideally, any SQL parsing should be SQLite's job. SQLocal should just be taking the user's SQL and parameters, passing them to SQLite, and returning the results. We shouldn't be duplicating work that SQLite was going to do anyway. Is there a reason it won't work without this preprocessing?
The SQLite wasm uses BindingSpec which is defined as:
/** Specifies parameter bindings. */
declare type BindingSpec =
| readonly BindableValue[]
| { [paramName: string]: BindableValue }
/** Assumed to have binding index `1` */
| (SqlValue | boolean);we can use it or adapt it somehow to make things cleaner.
Referenced from SQLite wasm:
https://github.com/sqlite/sqlite-wasm/blob/31e4b6e478a3f10a11b477feb08f1e54b53c791a/index.d.ts#L27C1-L32C26
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not about the types. The types are fine. Record<string, any> is compatible with BindingSpec. I'm saying that all the extraction and normalization logic that the last commit added is not necessary. SQLite does that itself already, so you can just pass the parameter object to the driver directly without modifying it, and SQLite will handle validating it.
| it('should allow regular ? placeholders in template literals', async () => { | ||
| // This should work - regular ? placeholders are fine | ||
| const item = 'bread'; | ||
| const insert1 = | ||
| await sql`INSERT INTO groceries (name) VALUES (${item}) RETURNING name`; | ||
| expect(insert1).toEqual([{ name: 'bread' }]); | ||
|
|
||
| // Multiple regular ? placeholders | ||
| const item2 = 'milk'; | ||
| const quantity = 2; | ||
| await sql`CREATE TABLE IF NOT EXISTS items (name TEXT, qty INTEGER)`; | ||
| const insert2 = | ||
| await sql`INSERT INTO items (name, qty) VALUES (${item2}, ${quantity}) RETURNING *`; | ||
| expect(insert2).toEqual([{ name: 'milk', qty: 2 }]); | ||
| await sql`DROP TABLE items`; | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this block. It's just retesting logic that already has tests.
Hello,
This is a work-in-progress for #91 aiming to add support for named parameters.
I’ve added tests, and they’re all passing so far. However, the current implementation is not perfect (far from it, actually), there’s definitely room for improvement.
Any feedback or suggestions for a cleaner or more efficient approach would be very welcome.
Thank you.