Чтение / запись большого объекта из postgres с использованием pqxx

#c #iostream #libpqxx #lob #largeobject

#c #iostream #libpqxx #подбросить #largeobject

Вопрос:

Основной API pqxx работает со столбцами как с текстом. Итак, как получить доступ к двоичным данным из больших объектов (LOB) с помощью библиотеки pqxx?

Ответ №1:

Есть несколько способов. Первый способ — перевести данные в / из bytea и работать через общий API pqxx. Если вы знаете, как работать с bytea, вероятно, это ваш путь. Вот пример того, как вставить строку как lob, простой sql, без кода на c :

 select lo_from_bytea(0, 'this is a test'::bytea);
...
select encode(lo_get(190850), 'escape'); -- here 190850 is the oid for lob created by the first line.
  

Другой вариант — использовать API iostream, предоставляемый библиотекой pqxx. Примеров того, как его использовать, не так много, так что поехали:

 // write lob
auto conn = std::make_shared<pqxx::connection>(url);
auto tran = std::make_shared<pqxx::work>(*conn);
auto stream = std::make_shared<pqxx::olostream>(*tran, oid);
stream->write(data, size);
stream->flush();
stream.reset();
tran->commit();

// read lob
stream = std::make_shared<pqxx::ilostream>(*tran, oid);
...
sszie_t get_chunk(shard_ptr<> stream, char *buf, size_t max_len)
{
    while (!stream->eof() amp;amp; len < max_len amp;amp; stream->get(buf[len])) {
        len  ;
    }

    return (len > 0 || !stream->eof()) ? len : -1;
}
  

Примечание: в pqxx ::ilostream есть ошибка, вы можете получить усеченные данные, если байт 0xff в данных попадет на границу внутреннего буфера, он будет ошибочно считаться символом EOF. Ошибка была исправлена в феврале 2020 года, и на данный момент это исправление не попало во все дистрибутивы.