3D Repo Bouncer  1.4
repo_bson.h
1 
27 #pragma once
28 
29 #if defined(_WIN32) || defined(_WIN64)
30 #include <WinSock2.h>
31 #include <Windows.h>
32 
33 #define strcasecmp _stricmp
34 #endif
35 
36 #include <mongo/bson/bson.h>
37 #include <unordered_map>
38 
39 #include "../../../lib/repo_log.h"
40 #include "../../../repo_bouncer_global.h"
41 #include "../repo_model_global.h"
42 #include "../repo_node_utils.h"
43 #include "repo_bson_element.h"
44 
45 #define REPO_BSON_MAX_BYTE_SIZE 16770000 //max size is 16MB,but leave a bit for buffer
46 
47 namespace repo {
48  namespace core {
49  namespace model {
50  //TODO: Eventually we should inherit from a generic BSON object.
51  //work seems to have been started in here:https://github.com/jbenet/bson-cpp
52  //alternatively we can use a c++ wrapper on https://github.com/mongodb/libbson
53  class REPO_API_EXPORT RepoBSON : public mongo::BSONObj
54  {
55  public:
56 
60  RepoBSON() : mongo::BSONObj() {}
61 
66  RepoBSON(const mongo::BSONObj &obj,
67  const std::unordered_map<std::string, std::pair<std::string, std::vector<uint8_t>>> &binMapping =
68  std::unordered_map<std::string, std::pair<std::string, std::vector<uint8_t>>>());
69 
74  RepoBSON(mongo::BSONObjBuilder &builder) : mongo::BSONObj(builder.obj()) {}
75 
80  RepoBSON(const std::vector<char> &rawData) : mongo::BSONObj(rawData.data()) {}
81 
85  virtual ~RepoBSON() {}
86 
90  static RepoBSON fromJSON(const std::string &json);
91 
96  RepoBSON& operator=(RepoBSON otherCopy) {
97  swap(otherCopy);
98  return *this;
99  }
104  void swap(RepoBSON otherCopy)
105  {
106  mongo::BSONObj::swap(otherCopy);
107  bigFiles = otherCopy.bigFiles;
108  }
109 
113  static int64_t getCurrentTimestamp();
114 
120  RepoBSONElement getField(const std::string &label) const
121  {
122  return RepoBSONElement(mongo::BSONObj::getField(label));
123  }
124 
131  template <class T>
133  const std::string &field,
134  std::vector<T> &vec) const
135 
136  {
137  bool success = false;
138 
139  if (!hasField(field) || getField(field).type() == ElementType::STRING)
140  {
141  //Try to get it from file mapping.
142  std::vector<uint8_t> bin = getBigBinary(field);
143  if (bin.size() > 0)
144  {
145  vec.resize(bin.size() / sizeof(T));
146  memcpy(vec.data(), &bin[0], bin.size());
147  success = true;
148  }
149  else
150  {
151  repoError << "Trying to retrieve binary from a field that doesn't exist(" << field << ")";
152  return false;
153  }
154  }
155  else{
156  RepoBSONElement bse = getField(field);
157  if (bse.type() == ElementType::BINARY && bse.binDataType() == mongo::BinDataGeneral)
158  {
159  bse.value();
160  int length;
161  const char *binData = bse.binData(length);
162  if (length > 0)
163  {
164  vec.resize(length / sizeof(T));
165  memcpy(vec.data(), binData, length);
166  success = true;
167  }
168  else{
169  repoError << "RepoBSON::getBinaryFieldAsVector : "
170  << "size of binary data (" << length << ") Unable to copy 0 bytes!";
171  }
172  }
173  else{
174  repoError << "RepoBSON::getBinaryFieldAsVector : bson element type is not BinDataGeneral!";
175  }
176  }
177 
178  return success;
179  }
180 
186  repoUUID getUUIDField(const std::string &label) const;
187 
193  std::vector<repoUUID> getUUIDFieldArray(const std::string &label) const;
194 
200  std::vector<float> getFloatArray(const std::string &label) const;
201 
207  std::vector<std::string> getStringArray(const std::string &label) const;
208 
214  int64_t getTimeStampField(const std::string &label) const;
215 
225  std::list<std::pair<std::string, std::string> > getListStringPairField(
226  const std::string &arrLabel,
227  const std::string &fstLabel,
228  const std::string &sndLabel) const;
229 
231  double getEmbeddedDouble(
232  const std::string &embeddedObjName,
233  const std::string &fieldName,
234  const double &defaultValue = 0) const;
235 
237  bool hasEmbeddedField(
238  const std::string &embeddedObjName,
239  const std::string &fieldName) const;
240 
248  bool hasBinField(const std::string &label) const
249  {
250  return hasField(label) || bigFiles.find(label) != bigFiles.end();
251  }
252 
253  virtual RepoBSON cloneAndAddFields(
254  const RepoBSON *changes) const;
255 
256  public:
257 
258  /*
259  * ----------------- BIG FILE MANIPULATION ----------------------------------
260  */
261 
267  RepoBSON cloneAndShrink() const;
268 
269  std::vector<uint8_t> getBigBinary(const std::string &key) const;
270 
276  std::vector<std::pair<std::string, std::string>> getFileList() const;
277 
282  std::unordered_map< std::string, std::pair<std::string, std::vector<uint8_t> > > getFilesMapping() const
283  {
284  return bigFiles;
285  }
286 
291  bool hasOversizeFiles() const
292  {
293  return bigFiles.size() > 0;
294  }
295 
296  protected:
297 
298  std::unordered_map< std::string, std::pair<std::string, std::vector<uint8_t> > > bigFiles;
299  }; // end
300  }// end namespace model
301  } // end namespace core
302 } // end namespace repo
bool hasOversizeFiles() const
Definition: repo_bson.h:291
Definition: repo_bson_element.h:41
RepoBSON(mongo::BSONObjBuilder &builder)
Definition: repo_bson.h:74
RepoBSONElement getField(const std::string &label) const
Definition: repo_bson.h:120
RepoBSON()
Definition: repo_bson.h:60
Definition: repo_connection_pool_mongo.h:32
std::unordered_map< std::string, std::pair< std::string, std::vector< uint8_t > > > getFilesMapping() const
Definition: repo_bson.h:282
virtual ~RepoBSON()
Definition: repo_bson.h:85
void swap(RepoBSON otherCopy)
Definition: repo_bson.h:104
RepoBSON(const std::vector< char > &rawData)
Definition: repo_bson.h:80
Definition: repo_bson.h:53
RepoBSON & operator=(RepoBSON otherCopy)
Definition: repo_bson.h:96
ElementType type() const
Definition: repo_bson_element.cpp:9
bool getBinaryFieldAsVector(const std::string &field, std::vector< T > &vec) const
Definition: repo_bson.h:132
bool hasBinField(const std::string &label) const
Definition: repo_bson.h:248