Insert vector data as bytea in postgres using libpqxx

207 Views Asked by At

I have a vector which needs to be saved as bytea type in Postgres.

I have seen solutions using binarystring for doing that. But binary string is now deprecated in the latest versions (I am using 7.7.5).

std::vector<int> params_;
params_.push_back(156);
params_.push_back(256*256);

// Creating basic_string for saving data to DB 
std::basic_string<std::byte>a {
            reinterpret_cast<std::byte const *>(std::data(md.params_)), 
2*sizeof(int)};

// Converting back to vector<int>, during reads 
for (i = 0; i < std::size(a); i += 1) {
            int const  z{int(a.at(i))};
            std::cout << "int at: " << i << " " << z << '\n';
            std::cout << "bits at: " << i << " " << a.at(i) << '\n';
        }

Response for the code is:

int at: 0 156
bits at: 0 10011100
int at: 1 0
bits at: 1 00000000
int at: 2 0
bits at: 2 00000000
int at: 3 0
bits at: 3 00000000
int at: 4 0
bits at: 4 00000000
int at: 5 0
bits at: 5 00000000
int at: 6 1
bits at: 6 00000001
int at: 7 0
bits at: 7 00000000

I tried using basic_string (mentioned in docs), But the byte information shown in the above response is bit odd.

For the 156 value in the vector, the byte information at index 0 should be at index 3 and the same goes for another element (some endianess issue).

Is there a sample code for storing bytea data using basic_string or any other way?

Is there anything mistake in the above code?

1

There are 1 best solutions below

0
273K On

You should transform the vector before taking its data. Since you are talking about the byte order, the chosen type int is not suitable. It's also unclear, why std::basic_string<std::byte> instead of std::vector<std::byte> is chosen.

std::vector<unsigned int> params_;
params_.push_back(156);
params_.push_back(256*256);

std::transform(params_.begin(), params_.end(), params_.begin(), [](unsigned int v) { return htonl(v); });

// Creating basic_string for saving data to DB 
std::basic_string<std::byte>a {
            reinterpret_cast<std::byte const *>(std::data(md.params_)), 
2*sizeof(int)};

// Converting back to vector<int>, during reads 
for (i = 0; i < std::size(a); i += 1) {
    int const  z{int(a.at(i))};
    std::cout << "int at: " << i << " " << z << '\n';
    std::cout << "bits at: " << i << " " << a.at(i) << '\n';
}