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

WIP: Pass source_location into libpqxx functions. #944

Closed
wants to merge 63 commits into from
Closed

Conversation

jtv
Copy link
Owner

@jtv jtv commented Jan 30, 2025

I'm trying to add std::source_location parameters to every libpqxx function that may throw, and pass the value on whenever those functions call other libpqxx functions that may throw. The ideal end state would be one where every exception coming out of libpqxx would convey the location of the original call into libpqxx that ultimately triggered the exception.

In practice this ideal does not look fully attainable, because as far as I can see...

  1. there's no way to add a parameter with a default value to the end of a template function with a variable number of parameters.
  2. we have no reasonable way of dealing with exceptions that the standard library may throw when we call it.

jtv added 30 commits January 19, 2025 15:11
This type has been deprecated since 7.2.0, more than 4 years ago.
This was a long-forgotten feature that somebody thought might be a
good idea, around 20 years ago.  It's only been deprecated for a
short time, but it's so obscure that I stronly doubt that anyone has
ever used it at all.

Meanwhile it was weighing down a pretty basic piece of code that
comes up in lots of loops, so... less is more.
jtv and others added 28 commits January 19, 2025 15:13
Use `pqxx::connection::encrypt_password()` instead.
Use `pqxx::params` instead.
Use the factory functions instead.
Use `unesc_bin()` and `quote(bytes_view)` instead.
These constructors have been documented as "do not use" in various ways
for a long time.

More generally, I'm settling on a deprecation horizon of 3 years.  It's
been so long since 7.0 came out that it's just not reasonable to keep
everything that was deprecated since then.  Instead, I'm now retiring
things that were deprecated in 7.6.
Not clear why those were there in the first place.
* Retire `binarystring`.

This type has been deprecated since 7.2.0, more than 4 years ago.

* String conversion to `string_view`.  More binary types.

Fixes: #694
Fixes: #827

Making much broader use of concepts.  String conversions now accept any
contiguous range of `std::byte` as binary data.  Traits specialisations
for integer and floating-point types are simpler now.  And you can now
just convert from string to `std::string_view` (or `char const *`), so
long as you don't access it after the original string's lifetime ends.

* Work around Visual Studio 2022 concepts problem.

This compiler was having trouble with the syntax I used to specialise
the generic `string_traits<T>` template to a _concept_ `T` (as opposed
to run-of-the-mill specialisation to a _type_ `T`).

So just for the floating-point string traits, I went back to the old
setup where I had a separate implementation type template
(`string_float_traits`) and derived the `string_traits` implementations
for those types from instantiations of that template.

* Forbid string conversion from `char const *`.

It was stupid of me to allow this.  I hope nobody ever used it.
Not sure how useful this is, but it's definitely more intuitive.

Theoretically we might be able to leave `nullness::is_null()` on such
types unimplemented altogether, though that might make things a little
too irregular.
Fixes: #925

Extends a bunch more functions that accept `pqxx::bytes_view` with
variants which accept any type that satisfies the `pqxx::binary`
concept.

Also, change the `pqxx::bytes_view` type alias from being a
`std::basic_string_view<std::byte>` (which doesn't actually have to work
according to the standard!) to being a `std::span<std::byte>`.  This
seems to be broadly compatible with existing code.  For completeness I'm
adding a `pqxx::writable_bytes_view` as well.
There really wasn't much point to having "unit" tests and story tests
("legacy" tests, really) in separate directories.  Sweep them all
together into a single directory — it's simpler, and possibly faster
on some build systems.
* Assume support for `std::source_location`.

This is a C++20 feature, and it seems to be widely implemented.

Next step of course is to pass the source location in more places, so
that exceptions will be properly helpful in pinpointing where their
errors happened.  Ideally an error will tell you the location of the
original call into libpqxx that led to the problem.

* Use `std::map::contains()`.
* Assume support for `std::source_location`.

This is a C++20 feature, and it seems to be widely implemented.

Next step of course is to pass the source location in more places, so
that exceptions will be properly helpful in pinpointing where their
errors happened.  Ideally an error will tell you the location of the
original call into libpqxx that led to the problem.

* Use `std::map::contains()`.
This is just one small portion of the work needed.  I'm trying to ensure
that every libpqxx function that may throw an exception has a
`source_location` parameter, and that it passes this to any functions
it calls that may throw.

The end result would ideally be that any exception thrown by libpqxx
would include the location of the original call into libpqxx.

In practice unfortunately I'm not so sure that I can attain this
ideal.  Type parameter packs make it difficult.
@@ -416,6 +439,22 @@
}


void test_blob_generic_append_from_buf_appends()

Check notice

Code scanning / CodeQL

Unused static function Note test

Static function test_blob_generic_append_from_buf_appends is unreachable (
tst_test_blob_generic_append_from_buf_appends
must be removed at the same time)
@@ -306,7 +306,7 @@
tx.commit();
}

void test_variant_fold(pqxx::connection_base &connection)
void test_variant_fold(pqxx::connection &connection)

Check notice

Code scanning / CodeQL

Unused static function Note test

Static function test_variant_fold is unreachable (
test_stream_to
must be removed at the same time)
Static function test_variant_fold is unreachable (
tst_test_stream_to
must be removed at the same time)
@@ -206,9 +206,27 @@
}


void test_binary_converts_to_string()

Check notice

Code scanning / CodeQL

Unused static function Note test

Static function test_binary_converts_to_string is unreachable (
tst_test_binary_converts_to_string
must be removed at the same time)

namespace
{
template<typename T> void test_for(T const &val)

Check notice

Code scanning / CodeQL

Unused static function Note test

Static function test_for is unreachable (
test_binary_cast
must be removed at the same time)
Static function test_for is unreachable (
tst_test_binary_cast
must be removed at the same time)
}


void test_binary_cast()

Check notice

Code scanning / CodeQL

Unused static function Note test

Static function test_binary_cast is unreachable (
tst_test_binary_cast
must be removed at the same time)


namespace
{
void test_zview_is_a_range()

Check notice

Code scanning / CodeQL

Unused static function Note test

Static function test_zview_is_a_range is unreachable (
tst_test_zview_is_a_range
must be removed at the same time)
@jtv jtv closed this Jan 30, 2025
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

1 participant