Сохранение 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++ - это просто серия chars (байты), а не символы, и pqxx::binarystring имеет встроенные преобразования из и в std::string,


Corner Угол Нитпикера: если вы не используете подходящий пользовательский распределитель. Не рекомендуется.

Другие вопросы по тегам