jeudi 2 janvier 2020

ODB query segfaults

I am in the process of implementing a database using ODB ORM

The template file (db.hxx) file looks like so

#ifndef DB_HXX_
#define DB_HXX_

#include <utility>
#include <vector>
#include <string>
#include <memory>

#include <odb/core.hxx>

class Data;

class File;

class Offset;


#pragma db object

class File {
 public:
  File(const long timeStamp, std::string name, std::string path, std::string codeSegmentHash)
          : timeStamp_(timeStamp), name_(std::move(name)), path_(std::move(path)),
            codeSegmentHash_(std::move(codeSegmentHash)) {}

  int id() const { return id_; }

  long timeStamp() { return timeStamp_; }

  std::string &name() { return name_; }

  std::string &path() { return path_; }

  std::string &codeSegmentHash() { return codeSegmentHash_; }

  // Offsets of this file
  std::vector<std::shared_ptr<Offset>> offsets() const { return offsets_; }

  void AddOffset(std::shared_ptr<Offset> offset) { return offsets_.emplace_back(offset); }

 private:
  File() = default;

  friend class odb::access;

#pragma db id auto
  int id_;
#pragma db not_null
  long timeStamp_;
#pragma db not_null
  std::string name_;
#pragma db not_null
  std::string path_;
#pragma db not_null unique
  std::string codeSegmentHash_;

#pragma db inverse(file_)
  std::vector<std::shared_ptr<Offset>> offsets_;
};

#pragma db object
class Offset {
 public:
  Offset(const unsigned int offset, std::shared_ptr<File> file, std::shared_ptr<Data> data)
          : offset_(offset), file_(std::move(file)), data_(std::move(data)) {}

  int id() const { return id_; }

  unsigned int offset() const { return offset_; }

  // Employer.
  const std::shared_ptr<File> &GetFile() const { return file_; }

  void SetFile(std::shared_ptr<File> file) { file_ = std::move(file); }

  // System Calls
  const std::shared_ptr<Data> &data() const { return data_; }

  void SetData(std::shared_ptr<Data> data) { data_ = std::move(data); }

 private:
  Offset() = default;

  friend class odb::access;

#pragma db id auto
  int id_;
#pragma db not_null
  unsigned int offset_;
#pragma db value_not_null
  std::shared_ptr<File> file_;
#pragma db not_null
  std::shared_ptr<Data> data_;
};

#pragma db object
class Data {
 public:
  Data(const unsigned int index, std::string name)
          : index_(index), name_(std::move(name)) {}

  std::string name() const { return name_; }

  unsigned int index() const { return index_; }

  int id() const { return id_; }

  const std::vector<std::shared_ptr<Offset>>& GetOffsets() { return offsets_; }
  const void AddOffset(std::shared_ptr<Offset> offset) { offsets_.emplace_back(offset); }

 private:
  Data() = default;

  friend class odb::access;

#pragma db id auto
  int id_;
#pragma db not_null
  unsigned int index_;
#pragma db not_null
  std::string name_;
#pragma db inverse(data_)
  std::vector<std::shared_ptr<Offset>> offsets_;
};

#endif  // DB_HXX_

I don't know if I did it correctly but the relationship is supposed to be

One File <-> Many Offsets

One Data <-> Many Offsets

Everything works okay except for this function:

std::vector<uint32_t> GetOffsets(const std::string &path, const std::string &codeSegmentHash) {
  typedef odb::query<File> query;
  typedef odb::result<File> result;

  std::vector<uint32_t> offsetsVector;

  odb::transaction t(db->begin());
  try {
    std::shared_ptr<File> file(db->query_one<File>(
        query::path == path && query::codeSegmentHash == codeSegmentHash));
    if (!r.empty()) {
       for (std::shared_ptr<Offset> offset : file->offsets()) {
            std::cout << offset->offset() << std::endl;
       }
    } else {
      throw std::invalid_argument("The offset not exists");
    }
  } catch (const odb::exception &e) {
    throw std::invalid_argument(e.what());
  }
}

The code segfaults as the query_one() line executes,

What am I doing wrong?

Thanks.

Aucun commentaire:

Enregistrer un commentaire