-
Notifications
You must be signed in to change notification settings - Fork 249
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
Allow parsing arrays without connection #841
Comments
There is a constructor libpqxx/include/pqxx/array.hxx Lines 203 to 223 in 9f378c0
However, it is a private API, cannot be used by applications. |
The reason is that so far, encodings and encoding groups are entirely hidden from the application. If we're going to introduce it into the API, then we'll have to answer some questions:
|
Adding the following constructor can alleviate the problem:
|
Yes, I suppose using the encoding's name would solve it. I'd probably want a way for the caller to move that string lookup out of loops though. We'd also need to check lifetime guarantees. If that encoding name happens to live inside a buffer held by the libpq-level connection struct somewhere, then closing the connection would invalidate that memory and we'd be back to the original problem. I wonder if it would help to encapsulate encoding in a class. You'd construct an object using an encoding name, but internally it might store just the encoding group. No transparency of enums, no persistent storage of the numerical values. |
It probably will. That said, I would go one step further and allow for programmatically setting a "global" persistent encoding that would be used whenever The existing interface will use the encoding from the supplied connection, and the new one (that does not accept a connection parameter) will use the globally set encoding. |
the problem we're trying to solve here is we're unable to write something like this:
because if you could create template specification for e.g.:
changing |
It seems that we only pass connections for encoding in template<...>
class array final
{
public:
explicit array(std::string_view data) :
array{data, m_default_enc_group}
{}
static void set_default_encoding(std::string_view encoding_name) {
m_default_enc_group = pqxx::internal::enc_group(encoding_name); // may throw
m_default_enc_name = std::string(encoding_name);
}
static [[nodiscard]] const std::string& get_default_encoding() {
return m_default_enc_name;
}
private:
static std::string m_default_enc_name{"UTF8"};
static pqxx::internal::encoding_group m_default_enc_group{UTF8};
}; Alternatively, the "default encoding" could be a static property of |
C++20 ranges would be nice :) |
This cannot happen with UTF-8. I am not familiar with other multi-byte encodings. That said, the problem we are trying to solve is array parsing without an active connection, when both the client and server encodings are known. |
@fallenworld1 the problem with specialising |
@alexolog two points that I want to get out of the way:
Now, one thing we could try doing, is make
That still leaves us with the problem of passing the encoding into the string conversions. This is in a way the hard one: it affects the string conversion API, and therefore it may affect people who have written their own string conversions. |
Phew. I finally got the documentation working again. That's been a big de-motivating factor for the last three months. @alexolog @fallenworld1 I'd like to focus on this issue next, barring any urgent problems elsewhere, since we seem to have a clear direction. |
Again there were lots of things to distract me but I did discover that So I'm now thinking along the lines of @fallenworld1's idea. First step: Add a completely separate function for reading an SQL array field as a This new function would have an entirely new name. That means you can't use it in row-at-a-time conversions. So yes, its utility would be limited. Unless I find it's entirely safe to provide conversions such as Second step: Start integrating the new function into the existing field conversions system, so you can use the regular Supporting conversion straight to some "C++-native" type like Third step: Make this work with streaming queries. If we're lucky we can actually do this before the second step. We'll see. Fourth step: Can we make this work with |
I'm trying the first step. (At the second step I run into the problem that I need a partial template specialisation for |
@alexolog, @fallenworld1, @tt4g — I think #854 would take care of the first step. Any thoughts? |
@jtv couple of thoughts on second step - you can hide your encoding type inside
|
LGTM. |
@fallenworld1 I think this is more or less what we've already discussed. Be aware however that |
Thanks @tt4g! |
@alexolog I suppose |
It's annoying that there is already a `field::as_array()`, which returns an obsolete `array_parser` with its clunky API. I'm being aggressive in deprecating that one, so that eventually the _new_ function can assume its name without clashing.
There's more work to be done, but not quite as urgent I suppose. |
Hi @jtv Unfortunately we lost track of this issue, so I apologize for the late reply. This does not really work for us since we use the Can you please take another look? |
@alexolog that's that part that's not so easy. I think it requires...
I've just filed #948 for this problem. I happen to be facing a similar problem for the introduction of |
Not necessarily. Concepts give you better error messages, but they are not required for correctness. |
I'm not just talking about what is required to get something that compiles. It also has to be maintainable and fit in with my plans. |
Currently, parsing an array requires an active connection, which is used only to retrieve the client encoding. This prevents using containers inside tuples for automatic conversion and requires jumping through hoops to parse arrays.
This also applies to
pqxx::array
constructor.However, in many cases the encoding is known in advance, especially when developing a product where both the client and the server are controlled by the same actor.
I believe it would be better if we could have a standalone function to globally set the encoding to a constant or from a connection, and it would persist until changed.
The text was updated successfully, but these errors were encountered: