feat(d1): add raw_with_column_names for raw({ columnNames: true }) - #1060
Open
mqmalagris wants to merge 1 commit into
Open
feat(d1): add raw_with_column_names for raw({ columnNames: true })#1060mqmalagris wants to merge 1 commit into
mqmalagris wants to merge 1 commit into
Conversation
worker-sys bound `raw()` with no arguments, so the `{ columnNames: true }`
form of the D1 API was unreachable. Callers that index rows positionally
had no way to learn which column each position refers to.
Bind `raw` a second time as `raw_with_options`, since wasm-bindgen cannot
overload on arity, and add `D1PreparedStatement::raw_with_column_names`,
which returns `(Vec<String>, Vec<Vec<T>>)`.
D1 returns the column names as the first array of the result, typed
upstream as `[string[], ...T[]]`. Splitting the header out keeps the rows
uniformly `T` instead of pushing that quirk onto the caller. Verified
against miniflare: a zero-row query still returns the header, so the
column names are reported with an empty row set rather than nothing.
Closes cloudflare#1052
Collaborator
|
Let's rather add the options object as typed, with getters/setters for props. See the patterns in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1052
Problem
worker-sysbindsD1PreparedStatement.raw()with no arguments, so theraw({ columnNames: true })form of the D1 API is unreachable from Rust.raw()gives back rows as positional arrays with no way to learn what those positions mean.That blocks the case in the issue: an ORM mapping layer (the reporter is working on a
diesel-d1fork) indexes a row byusize, so arrays-of-arrays are the right shape — but it still needs the column names to map them.Fix
Two layers, both mirroring what's already there.
worker-sys/src/types/d1.rs— bindrawa second time, asraw_with_options, taking ajs_sys::Object. A separate Rust name is required because wasm-bindgen can't overload on arity;js_name=rawkeeps it pointing at the same JS method. The existing zero-argrawbinding is untouched.worker/src/d1/mod.rs— addraw_with_column_names<T>() -> Result<(Vec<String>, Vec<Vec<T>>)>. It builds{ columnNames: true }, calls the new binding, then splits the header off the front.The split is the reason this is a separate method rather than an option on
raw(). D1 returns the column names as the first array of the result — typed upstream asPromise<[string[], ...T[]]>— so a single return value would be heterogeneous and force every caller to deal with a first row that isn't a row. Returning(names, rows)keeps rows uniformlyT.Also non-breaking:
raw()andraw_js_value()keep their exact signatures and behavior.Test
Extended the existing
prepared_statementintegration test intest/src/d1.rs, next to the currentraw()assertions:raw_with_column_namesyields["id", "name", "age"]plus one row whose positional values match whatraw()returns;That second case is the one I would have got wrong by reading the code alone, so I checked it against a real runtime rather than assuming. With miniflare:
So the header is always present when
columnNamesis set, which matches the upstream tuple type. The implementation still guards the empty-array case, but as a defensive branch rather than an expected one, and the doc comment says the names are reported even with no rows.Checks run:
cargo check -p worker -p worker-sandbox --target wasm32-unknown-unknown,cargo clippy -p worker -p worker-sys --target wasm32-unknown-unknown -- -D warnings(clean),cargo fmt --check(clean).I did not add a changeset — no
.changeset/*.mdhas been filed per-PR in this repo's history, only the README and config. Happy to add one if that's wrong.Out of scope
raw_js_value()has nocolumnNamescounterpart. It seemed better to add the one method the issue asks for than to speculatively double the surface; say the word if you'd likeraw_js_value_with_column_namesfor symmetry.