Сохранение std::vector в postgresql с помощью pqxx и извлечение его из базы данных.
Мне нужно хранить содержимое std::vector<uint8_t>
в базе данных postgresql и иметь возможность получить его снова. Я использую библиотеку pqxx в качестве "оболочки" для подключения к базе данных. Для хранения я делаю это:
std::string query = "INSERT INTO file_pivot(file_id, p_id, deviation) VALUES($1, $2, $3) RETURNING id";
pqxx::binarystring deviation((void*)&(data), data.size());
conn.prepare("file_insert", query);
pqxx::result res = worker.prepared("file_insert")(1)(pivot_id)(deviation).exec();
worker.commit();
Который работает и хранит его в базе данных, насколько я могу судить, проблема с последующим получением чертового вектора снова.
То, что я пытался сделать, это:
pqxx::work sworker(conn);
std::string squery = "SELECT * FROM file_pivot WHERE file_id = $1";
conn.prepare("select_file", squery);
pqxx::result sres = sworker.prepared("select_file")(file_id).exec();
std::vector<uint8_t> rdata;
if(sres.size() > 0)
{
pqxx::binarystring sblob(res[0][3]);
std::vector<uint8_t>*rrdata = (std::vector<uint8_t>*) sblob.data();
rdata = *rrdata;
}
Но когда я тогда сравниваю исходный вектор data
в rdata
как это:
assert(std::equal(data.begin(), data.end(), rdata.begin()));
Я получил ошибку сегментации, я пытался с помощью rrdata->begin()
а также та же проблема. Может кто-то помочь с этим, это начинает действовать мне на нервы.
1 ответ
pqxx::binarystring::data
не возвращает указатель на вектор, поэтому вы не можете просто рассматривать его как тот, который вы делаете здесь:
std::vector<uint8_t>*rrdata = (std::vector<uint8_t>*) sblob.data();
Скорее, data()
Функция возвращает указатель на необработанные данные. Чтобы построить вектор из этого, самый простой способ - использовать итераторы, предоставленные pqxx::binarystring
, вот так:
std::vector<uint8_t> rdata(sblob.begin(), sblob.end());
Поскольку итераторы являются typedef'd как простые старые указатели, std::vector
Конструктор сможет вычесть их, чтобы выделить правильный размер для вектора за один раз.
Обратите внимание, что это делает копию данных; нет никакого способа построить вектор из существующей памяти, потому что вектору всегда принадлежит память, на которую он указывает.
Вместо использования std::vector<uint8_t>
, это может быть проще в использовании std::string
вместо. Строка в C++ - это просто серия char
s (байты), а не символы, и pqxx::binarystring
имеет встроенные преобразования из и в std::string
,
Corner Угол Нитпикера: если вы не используете подходящий пользовательский распределитель. Не рекомендуется.