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: 8.0.0 development #914

Open
wants to merge 64 commits into
base: master
Choose a base branch
from
Open

WIP: 8.0.0 development #914

wants to merge 64 commits into from

Conversation

jtv
Copy link
Owner

@jtv jtv commented Dec 22, 2024

First, we raise the minimum language version from C++17 to C++20, and we simplify things by assuming that C++20 features are present.

Not necessarily all C++20 features, mind you; there are still compilers out there, probably widely used, that do not implement <charconv> for floating-point types for instance.

Then, we retire some deprecated features such as —

  • binarystring
  • row slicing
  • etc.

Next we start implementing pending design changes which require API changes, ABI changes, and/or C++20.

@jtv jtv changed the title Bump to 8.0.0 in preparation. 8.0.0 development Dec 23, 2024
@jtv jtv changed the title 8.0.0 development WIP: 8.0.0 development Dec 23, 2024
@jtv jtv force-pushed the start-8 branch 12 times, most recently from 72d1847 to 6335fbe Compare December 26, 2024 22:51
jtv and others added 16 commits January 19, 2025 15:13
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.
jtv and others added 3 commits January 19, 2025 15:33
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.
@@ -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 added 5 commits January 26, 2025 00:44
* 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()`.
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.  (Unless you pass your own choice of source location, of course).

In practice, this ideal is not quite attainable...
* Parameter packs make it hard — you can't just make a function accept any number of arguments of any type, and then add a `source_location` parameter _after_ that.
* With overloaded operators it's completely impossible — there's no way of adding parameters to a function with a fixed, language-dictated signature.
* Destructors take no arguments at all, so they're out as well.
* Callbacks and string conversions are a problem as well, because their existing definitions don't include `source_location`.

I do have a plan for that last item though.  I can probably update the signatures and use compile-time introspection (probably using function concepts) to detect whether the given user-defined function supports the old API or the new API.  That's a separate job though.

Oh, and because I don't want to grow all my function signatures with an additional tedious `std::source_location location = std::source_location::current()` etc, I created a type alias `sl`.  Hate how cryptic this makes the functions, but I really need these to be brief.

/// Connect to a database, using `options` string.
explicit connection(char const options[])
explicit connection(char const options[], sl loc = sl::current())

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
@@ -836,12 +839,12 @@
//@{

/// Escape string for use as SQL string literal on this connection.
[[nodiscard]] std::string esc(char const text[]) const
[[nodiscard]] std::string
esc(char const text[], sl loc = sl::current()) const

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
@@ -190,12 +190,19 @@
* functions on the connection object.
*/
//@{
[[nodiscard]] std::string esc(char const str[], sl loc = sl::current())

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
}

/// Unescape binary data, e.g. from a `bytea` field.
/** Takes a binary string as escaped by PostgreSQL, and returns a restored
* copy of the original binary data.
*/
[[nodiscard]] bytes unesc_bin(char const text[])
[[nodiscard]] bytes unesc_bin(char const text[], sl loc = sl::current())

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
@@ -745,7 +746,8 @@
}


void pqxx::connection::prepare(char const name[], char const definition[]) &
void pqxx::connection::prepare(

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
@@ -755,52 +757,51 @@
}


void pqxx::connection::prepare(char const definition[]) &
void pqxx::connection::prepare(char const definition[], sl loc) &

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
}


void PQXX_COLD pqxx::connection::set_client_encoding(char const encoding[]) &
void PQXX_COLD
pqxx::connection::set_client_encoding(char const encoding[], sl loc) &

Check notice

Code scanning / CodeQL

No raw arrays in interfaces Note

Raw arrays should not be used in interfaces. A container class should be used instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant