-
-
Notifications
You must be signed in to change notification settings - Fork 18
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
Document pattern of checking for zero rows #85
Comments
Went ahead and tossed a couple PRs your way, if they suit you. I could go either way between I think they could both be useful, but I can also continue to work around the issue, so please feel free to close if they don't fit the project goals. 🫡 |
Thanks for the PR. I agree this is a common pattern, but having this in the library seems like it would make application control flow less clear. I'm going to close #87 and retitle this issue to match new scope, but I'd like to have an example of this pattern in the documentation. Would you want to send a PR over for that? |
sqlitex.Execute
- provide option to return an error if 0 rows are returned.
I'd like to push back a little on this being just a doc change before I give up the ghost. I see your point wrt control flow; however, I also think that forcing two statements in different scopes to address such a common use case creates friction. In my case, it was exacerbated by the presence of other conveniences that seemed to do what I wanted, but didn't. To elaborate: I didn't discover that this might bite me until I was writing tests, only to find my zero values untouched, and I ended up beating my head against the wall for a couple hours trying to find a way to do something declarative in So, essentially, the gap I was left with was how to use the otherwise elegant pattern of embedding my I considered a PR for something like Another option might be to use a little closure magic to automate the process with a // SingleRow is [Exec], but it returns an error if there is not exactly one result returned.
func SingleRow(conn *sqlite.Conn, query string, opts *ExecOptions) error {
oOpts, gotResult := oneResult(opts)
err := Execute(conn, query, oOpts)
if err != nil {
return err
}
if !gotResult() {
return errNoResults
}
return nil
}
// SingleRowFS is [ExecuteFS], but but it returns an error if there is not exactly one result returned.
func SingleRowFS(conn *sqlite.Conn, fsys fs.FS, filename string, opts *ExecOptions) error {
oOpts, gotResult := oneResult(opts)
err := ExecuteFS(conn, fsys, filename, oOpts)
if err != nil {
return err
}
if !gotResult() {
return errNoResults
}
return nil
}
func oneResult(opts *ExecOptions) (*ExecOptions, func() bool) {
if opts == nil {
opts = &ExecOptions{}
}
if opts.ResultFunc== nil {
opts.ResultFunc=func(*sqlite.Stmt) error { return nil }
}
called := false
opts.ResultFunc=func(stmt *sqlite.Stmt) error {
if called {
return errMultipleResults
}
called = true
return opts.ResultFunc(stmt)
}
return opts, func()bool{return called}
} |
In light of the contribution guide rework, now I'm worried I'm being too presumptuous 😔. If you'd prefer, I can close the PR and move the above to a discussion. If so, I'll be happy to proceed with the doc PR in the meantime. |
Thanks for the detailed experience report, and I'm sorry to hear that the library's behavior led to a frustrating debugging experience. I'm in agreement that this is an area that can be improved, and I'm genuinely appreciative for the conversation and code contribution. Just to set expectations, I'm currently travelling, so I won't be able to review this for a week or so.
I reworked the contribution guide mostly to remove the line "this is a project that fills my own needs" because it's definitely grown beyond that. I hope the new guide is not off-putting. I would appreciate any feedback you have on it (feel free to email privately if that's more comfortable to you). As stated above, I appreciate you reaching out on this issue. I'm in agreement with you that this experience can be improved, but I'm trying to start with the smallest maintenance cost change to address, then working up.
Yeah, let's start with a discussion. 👍 There's some interesting options here and I don't want you to churn on code until we have more alignment. |
As requested! #90 |
I am using
sqlitex.Execute
for both queries and updates, and I can't seem to figure out if there is a package-supported way to instruct these methods to return an error if zero rows are returned. Currently, I am doing something like the following:But this is annoying to keep writing. Have I missed something? I know we have
sqlitex.Result*
methods, but there isn't one forBytes
, which I'm using, and they don't really fit the workflow ofExecute
and friends.Provided there is no other way, I propose an additional field in
sqlitex.ExecOptions
calledExpectRows bool
orExpectResults bool
that, when true, returns either a sentinel error from sqlitex (likesqlitex.ErrNoRows
) or asqlite
error whose code resolves tosqlite.ResultNotFound
if no rows exist.The text was updated successfully, but these errors were encountered: