1 // This is brl/bbas/brdb/brdb_relation.h
2 #ifndef brdb_relation_h_
3 #define brdb_relation_h_
4 //:
5 // \file
6 // \brief A database relation (table)
7 // \author Matthew Leotta
8 // \date Tue Jan 26 2005
9 //
10 // \verbatim
11 //  Modifications
12 //   <none yet>
13 // \endverbatim
14 //
15 // updated by Yong Zhao
16 // Apr 4th, 2007
17 // Make it work with the whole database initially based on Matt's sketch.
18 
19 
20 #include <vector>
21 #include <iostream>
22 #include <string>
23 #ifdef _MSC_VER
24 #  include <vcl_msvc_warnings.h>
25 #endif
26 #include <vbl/vbl_ref_count.h>
27 #include <brdb/brdb_tuple_sptr.h>
28 #include <brdb/brdb_relation_sptr.h>
29 #include <vsl/vsl_binary_io.h>
30 
31 // forward declarations
32 class brdb_value;
33 
34 
35 //: A database tuple
36 class brdb_relation : public vbl_ref_count
37 {
38   //======================= Constructors / Destructors ========================
39  public:
40   // Default Constructor
41   brdb_relation();
42 
43   //: Constructor - create an empty relation but define the columns
44   brdb_relation( std::vector<std::string>  names,
45                  std::vector<std::string>  types );
46 
47   //: Constructor - create a relation populated with tuples
48   //  If types are not provided they will be inferred from the tuples.
49   //  All tuples must have the same types and arity.
50   brdb_relation( const std::vector<std::string>& names,
51                  std::vector<brdb_tuple_sptr>  tuples,
52                  std::vector<std::string>  types = std::vector<std::string>() );
53 
54   // Destructor
55   ~brdb_relation() override;
56 
57 
58   //========================= Accessors / Modifiers ===========================
59   //: Return the number of tuples (i.e. the number of rows in the table)
size()60   unsigned int size() const { return static_cast<unsigned>(tuples_.size()); }
61   //: Return the number of attributes in a tuple (i.e. the number of columns in the table)
arity()62   unsigned int arity() const { return static_cast<unsigned>(names_.size()); }
63 
64   //: Return the name for \p index
65   // \note returns the empty string if the index is out of range
66   std::string name(unsigned int index) const;
67 
68   //: Return the index for the attribute with \p name
69   // \note returns the arity (max index + 1) if name is not found
70   unsigned int index(const std::string& name) const;
71 
72   //: Return the type by attribute name
73   std::string type(const std::string& name) const;
74 
75   //: Return the type by index
76   std::string type(unsigned int index) const;
77 
78   //: Return true if there is an attribute in the relation with such a name
79   bool exists(const std::string& name) const;
80 
81   //: Return true if there are no tuples in the relation.
empty()82   bool empty() const {return tuples_.empty();}
83 
84   //: Sort the tuples by a certain attribute name
85   bool order_by(const std::string& name, bool ascending=true);
86 
87   //: Sort the tuples by a certain attribute index
88   bool order_by(unsigned int index, bool ascending=true);
89 
90   //: clear the relation
91   // Keep the names and types, but remove all the tuples
92   void clear();
93 
94   //: Add one tuple to relation
95   bool add_tuple(const brdb_tuple_sptr& new_tuple);
96 
97   //: insert a tuple at certain position
98   bool insert_tuple(const brdb_tuple_sptr& new_tuple, const std::vector<brdb_tuple_sptr>::iterator& pos);
99 
100   //: remove a tuple at certain position from the relation
101   bool remove_tuple(const std::vector<brdb_tuple_sptr>::iterator& pos);
102 
103   //: Set a value by name
104   bool set_value(std::vector<brdb_tuple_sptr>::iterator pos, const std::string& name, const brdb_value& value);
105 
106   //: Convenience function for setting a value by name
107   template<class T>
108   bool set( std::vector<brdb_tuple_sptr>::iterator pos, const std::string& name , const T& value );
109 
110   //: Get a value by name
111   bool get_value(std::vector<brdb_tuple_sptr>::iterator pos, const std::string& name, brdb_value& value) const;
112 
113   //: Convenience function for getting a value by name
114   template<class T>
115   bool get(std::vector<brdb_tuple_sptr>::iterator pos, const std::string& name , const T& value ) ;
116 
117   //: print out the relation
118   void print() const;
119 
120   //: Return an iterator to the beginning of the relation
begin()121   std::vector<brdb_tuple_sptr>::iterator begin() { return tuples_.begin(); }
122 
123   //: Return an iterator to the end of the relation
end()124   std::vector<brdb_tuple_sptr>::iterator end() { return tuples_.end(); }
125 
126   //: binary io read
127   void b_read(vsl_b_istream &is);
128 
129   //: binary io write
130   void b_write(vsl_b_ostream &os) const;
131 
132   //: check whether the time stamp is the most updated, if not, return false, otherwise, return true
133   bool check_timestamp(const unsigned& time_stamp_check) const;
134 
135   //: get time stamp;
get_timestamp()136   unsigned long get_timestamp() const {return this->time_stamp_; }
137 
138   //: check whether another relation is compatible with this relation
139   bool is_compatible(const brdb_relation_sptr& other) const;
140 
141   //: if compatible, add tuples from the other relation into this one
142   bool merge(const brdb_relation_sptr& other);
143 
144  private:
145   //: Verify that the data stored in this class make a valid relation
146   // \note called by the constructors
147   bool is_valid() const;
148 
149   //: Verify that a tuple is valid relative to this relation
150   bool is_valid(const brdb_tuple_sptr& tuple) const;
151 
152   //: update the timestamp of this relation
153   void update_timestamp();
154 
155  private:
156   //: The time stamp of this relation
157   unsigned long time_stamp_;
158   //: The names of the attributes
159   std::vector<std::string> names_;
160   //: The types of the attributes
161   std::vector<std::string> types_;
162   //: The tuples of the attributes
163   std::vector<brdb_tuple_sptr> tuples_;
164 };
165 
166 
167 //: SQL join of two generic relations
168 brdb_relation_sptr brdb_join(const brdb_relation_sptr& r1, const brdb_relation_sptr& r2);
169 
170 
171 #endif // brdb_relation_h_
172