BSON C++ API  2.5.1
uma::bson
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Document.h
Go to the documentation of this file.
1 #ifndef UMA_BSON_DOCUMENT_H
2 #define UMA_BSON_DOCUMENT_H
3 
4 #include <uma/bson/Object.h>
5 #include <uma/bson/Element.h>
6 #include <uma/bson/ObjectId.h>
7 
8 #include <Poco/Exception.h>
9 #include <Poco/HashMap.h>
10 #include <Poco/SharedPtr.h>
11 
12 #include <iostream>
13 #include <map>
14 
15 
16 namespace uma
17 {
18  namespace bson
19  {
37  class UMA_BSON_API Document : public Object
38  {
39  public:
41  const static std::string OBJECT_ID;
42 
53  Document( const ObjectId& oid = ObjectId() ) :
54  pimpl( new DocumentImpl( oid ) ) {}
55 
62  static Document emptyDocument() { return Document( 0 ); }
63 
71  static Document fromFile( const std::string& filePath );
72 
82  static Document fromBytes( const char* bytes, const int32_t length );
83 
92  static Document fromStream( std::istream& is );
93 
101  static Document fromJson( std::istream& is );
102 
108  bool isEmpty() const { return pimpl->isEmpty(); }
109 
111  typedef std::vector<Element>::const_iterator ConstantIterator;
112 
120  ConstantIterator begin() const { return pimpl->begin(); }
121 
129  ConstantIterator end() const { return pimpl->end(); }
130 
131  const FieldNames getFieldNames() const { return pimpl->getFieldNames(); }
132 
141  bool hasElement( const std::string& name ) const
142  {
143  return pimpl->hasElement( name );
144  }
145 
166  template <typename DataType>
167  Element& create( const std::string& name )
168  {
169  if ( ! hasElement( name ) )
170  {
171  set( Element::createElement( name, new DataType() ) );
172  }
173 
174  return get( name );
175  }
176 
186  const Element& get( const std::string& name ) const
187  {
188  return pimpl->get( name );
189  }
190 
199  Element& get( const std::string& name ) { return pimpl->get( name ); }
200 
211  Element& operator [] ( const std::string& name );
212 
214  const Element& operator [] ( const std::string& name ) const { return get( name ); }
215 
216  Value& getValue( const std::string& name )
217  {
218  return get( name ).getValue<Value>();
219  }
220 
235  bool hasNestedElement( const std::string& name ) const
236  {
237  return pimpl->hasNestedElement( name );
238  }
239 
259  const Element& getNestedElement( const std::string& name ) const
260  {
261  return pimpl->getNestedElement( name );
262  }
263 
280  Document& set( const Element& value, const int32_t index = -1 )
281  {
282  pimpl->set( value, index );
283  return *this;
284  }
285 
287  Document& operator << ( const Element& value ) { return set( value ); }
288 
303  template <typename DataType>
304  Document& set( const std::string& name, const DataType& value,
305  const int32_t index = -1 )
306  {
307  return set( Element( name, value ), index );
308  }
309 
310  void setValue( const std::string& name, const Value& value );
311 
320  const ObjectId& getObjectId() { return pimpl->getObjectId(); }
321 
329  Document& setObjectId( const ObjectId& oid = ObjectId() )
330  {
331  pimpl->setObjectId( oid );
332  return *this;
333  }
334 
347  Element remove( const std::string& name ) { return pimpl->remove( name ); }
348 
354  size_t size() const { return pimpl->size(); }
355 
356  void toBson( std::ostream& os ) const;
357 
371  void toJson( std::ostream& os, bool prettyPrint = false ) const;
372 
389  Document clone() const;
390 
408  bool isEquivalentTo( const Document& doc ) const;
409 
415  int32_t getSize() const { return pimpl->getSize(); }
416 
417  private:
418  Document( const int /* size */ ) : pimpl( new DocumentImpl ) {}
419 
420  void populate( std::istream& /* is */ )
421  {
422  throw Poco::NotImplementedException();
423  }
424 
425  private:
426  class DocumentImpl
427  {
428  public:
429  DocumentImpl() {}
430 
431  DocumentImpl( const ObjectId& oid )
432  {
433  setObjectId( oid );
434  }
435 
436  bool isEmpty() const { return fields.empty(); }
437 
438  Document::ConstantIterator begin() const { return fields.begin(); }
439  Document::ConstantIterator end() const { return fields.end(); }
440 
441  const Document::FieldNames getFieldNames() const;
442 
443  bool hasElement( const std::string& name ) const
444  {
445  return ( names.find( name ) != names.end() );
446  }
447 
448  const ObjectId& getObjectId();
449 
450  void setObjectId( const ObjectId& oid = ObjectId() )
451  {
452  set( Element( OBJECT_ID, oid ), 0 );
453  }
454 
455  Element& get( const std::string& name );
456  const Element& get( const std::string& name ) const;
457 
458  bool hasNestedElement( const std::string& name ) const;
459  const Element& getNestedElement( const std::string& name ) const;
460 
461  void set( const Element& value, const int32_t index = -1 );
462 
463  Element remove( const std::string& name );
464 
465  size_t size() const { return fields.size(); }
466 
467  int32_t getSize() const;
468 
469  private:
470  void insert( const Element& value, const int32_t index );
471  void update( const Element& value, const int32_t index );
472  void updateIndices();
473 
474  private:
475  typedef std::vector<Element> Vector;
476  Vector fields;
477 
478  typedef Poco::HashMap<std::string,std::size_t> NameMap;
479  NameMap names;
480  };
481 
482  typedef Poco::SharedPtr<DocumentImpl> PimplPtr;
483  PimplPtr pimpl;
484  };
485 
494  template <>
495  inline Document& Document::set( const std::string& name,
496  const double& value, const int32_t index )
497  {
498  Element e( name, value );
499  return set( e, index );
500  }
501 
510  template <>
511  inline Document& Document::set( const std::string& name,
512  const std::string& value, const int32_t index )
513  {
514  Element e( name, value );
515  return set( e, index );
516  }
517 
526  template <>
527  inline Document& Document::set( const std::string& name,
528  const bool& value, const int32_t index )
529  {
530  Element e( name, value );
531  return set( e, index );
532  }
533 
542  template <>
543  inline Document& Document::set( const std::string& name,
544  const int32_t& value, const int32_t index )
545  {
546  Element e( name, value );
547  return set( e, index );
548  }
549 
558  template <>
559  inline Document& Document::set( const std::string& name,
560  const int64_t& value, const int32_t index )
561  {
562  Element e( name, value );
563  return set( e, index );
564  }
565 
584  UMA_BSON_API bool operator == ( const Document& lhs, const Document& rhs );
585 
587  inline bool operator != ( const Document& lhs, const Document& rhs )
588  {
589  return ! ( lhs == rhs );
590  }
591 
592  } // namespace bson
593 } // namespace uma
594 
595 #endif // UMA_BSON_DOCUMENT_H