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

Distinguish prepared statements by overload. #875

Merged
merged 10 commits into from
Aug 17, 2024
Merged

Distinguish prepared statements by overload. #875

merged 10 commits into from
Aug 17, 2024

Conversation

jtv
Copy link
Owner

@jtv jtv commented Aug 3, 2024

Simplify the plethora of "exec" function names by making prepared statement calls look just like regular or parameterised statement calls. You call exec() as with a regular SQL statement, but you wrap the statement name in a new type pqxx::prepped to indicate that it's a prepared statement name, not an SQL statement in itself.

At the same time, the functionality to check that a result contain a specific number of rows (usually either zero, or one) moves into result member functions. That means separate functions for e.g. "check that this result contains exactly 1 row." With that, we can start cutting down on all those versions that every exec function needs.

The bulk of the exec functions will be:

  • Just an SQL statement, like the current exec(), calling libpq's PQexec().
  • An SQL statement with parameters, like the new params overload to exec(), calling libpq's PQexecParams().
  • A pqxx::prepped with optional parameters, in a new overload of exec(), calling libpq's PQexecPrepared().

It will be similar for query(), query_value(), and hopefully stream() and stream_like(). From the caller's perspective, calling any of these functions pretty much does the same thing regardless of whether you pass parameters. And now it should also be the same when you pass a prepared statement instead of an SQL string — it's just that the query is of a different type.

Streamlining these function variants is really urgent. We were getting to a situation where we should logically support a Cartesian product of {plain SQL, parameterised, prepared} × {exec, exec0, exec1, exec_n, query, query_value, for_query, stream, for_stream, stream_like} × {with description, with source_location, without} (3×10×3 == 90 functions) — and it'd keep getting worse if we wanted more exotic row-count restrictions such as "at most 1 row" or "between a and b rows." That's just not sustainable.

I'm hoping to get to something like {plain SQL, parameterised, prepared} × {exec, query, query_value, for_query, stream, for_stream, stream_like} × {with source_location} (3×6×1 == 18 functions). And maybe with clever use of templates we can eventually get it down to {plain SQL, parameterised, prepared} + {exec, exec0, query, query_value, stream, for_stream, stream_like} (10 functions).

Of course this will take time to complete. The statement descriptions go away in 8.0. But all those newly deprecated functions will stick around for another whole major release. That's still much better than continuing along the old road.

This is a new way to call prepared statements.  Instead of encoding
the fact that it's a prepared statement in the function name, you'll
wrap the name in a lightweight object which marks it as a prepared
statement name.

I'm also hoping to extract the row count checks (`exec0()`, `exec1()`
etc.) into a separate helper, so that most of the calls to the various
"exec" calls will just be to functions called `exec()`.  Whether they're
calls to prepared statements, to parameterised statements, or plain SQL
will become more of an implementation detail that the library derives
from the arguments.
test/unit/test_prepared_statement.cxx Dismissed Show dismissed Hide dismissed
test/unit/test_prepared_statement.cxx Dismissed Show dismissed Hide dismissed
test/unit/test_prepared_statement.cxx Dismissed Show dismissed Hide dismissed
@jtv jtv changed the title WIP: Distinguish prepared statements by overload. Distinguish prepared statements by overload. Aug 17, 2024
@jtv jtv merged commit 8af0c46 into master Aug 17, 2024
7 checks passed
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.

1 participant