Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

Table.h

Go to the documentation of this file.
00001 #ifndef TABLE_H 00002 #define TABLE_H 00003 00004 #include <db_cxx.h> 00005 #include <string> 00006 00007 #include "Expression.h" 00008 #include "SQLSelect.h" 00009 #include "TupleDescription.h" 00010 #include "xercesDomUtil.h" 00011 #include "Params.h" 00012 00013 BOREALIS_NAMESPACE_BEGIN; 00014 00015 class AuroraNode; 00016 class SQLSelect; 00017 class SQLUpdate; 00018 class Table; 00019 00044 class SelectQueryHandle { 00045 public: 00046 virtual void doQuery(const char *tuple) = 0; 00047 00049 virtual bool avail() const = 0; 00050 00053 virtual void evalInto(char *buf) = 0; 00054 00056 virtual SelectQueryHandle& operator ++ () = 0; 00057 00058 virtual ~SelectQueryHandle() {} 00059 }; 00060 00061 class UpdateQueryHandle { 00062 public: 00063 virtual void doUpdate(const char *tuple) = 0; 00064 virtual bool avail() const = 0; 00065 virtual void updateRow() = 0; 00066 00067 // TODO: Check to make sure this specification is acceptable. 00068 // Only valid before updateRow is called. 00069 virtual const char *old_row() const = 0; 00070 // Only valid after updateRow is called. 00071 virtual const char *new_row() const = 0; 00072 00074 virtual UpdateQueryHandle& operator ++ () = 0; 00075 00076 virtual void doWholeUpdate(const char *tuple); 00077 virtual ~UpdateQueryHandle() {} 00078 }; 00079 00080 class ScanQueryHandle { 00081 public: 00082 virtual void doScan() = 0; 00083 00085 virtual bool avail() const = 0; 00086 00088 virtual const char *data() const = 0; 00089 00091 virtual ScanQueryHandle& operator ++ () = 0; 00092 00093 virtual ~ScanQueryHandle() {} 00094 }; 00095 00096 class DbHandle { 00097 public: 00098 DbHandle(DbEnv *dbe, int flags) : _open(false), _db(new Db(dbe, flags)) {} 00099 ~DbHandle() 00100 { 00101 if (_open) { 00102 try { 00103 DEBUG << "Closing DbHandle"; 00104 _db->close(0); 00105 } catch (DbException &e) { 00106 NOTICE << "Caught DbException: " << e.what(); 00107 } 00108 } 00109 delete _db; 00110 } 00111 // TODO: This is lame. Get it right. 00112 void mark_open() { _open = true; } 00113 Db *operator->() const { return _db; } 00114 Db *get() const { return _db; } 00115 private: 00116 DbHandle(const DbHandle &); 00117 DbHandle &operator=(const DbHandle &); 00118 bool _open; 00119 Db *_db; 00120 }; 00121 00122 class TableEnvironment { 00123 public: 00124 TableEnvironment(AuroraNode &node); 00125 ~TableEnvironment() 00126 { 00127 if (_open) { 00128 try { 00129 _db_env->close(0); 00130 } catch (DbException &e) { 00131 NOTICE << "Caught DbException: " << e.what(); 00132 } 00133 } 00134 delete _db_env; 00135 } 00136 DbEnv *getDbEnv() { return _db_env; } 00137 const DbEnv *getDbEnv() const { return _db_env; } 00138 private: 00139 static void db_err_callback(const char *errpfx, char *msg); 00140 TableEnvironment(const TableEnvironment &); 00141 TableEnvironment &operator=(const TableEnvironment &); 00142 AuroraNode &_node; 00143 bool _open; // If true, table needs to be closed. 00144 DbEnv *_db_env; 00145 }; 00146 00147 class TableIndex { 00148 public: 00149 TableIndex(ptr<TableEnvironment> tenv, Table &table, 00150 string field_name); 00151 ~TableIndex() {} 00152 00153 void insertRow(const Dbt &pkey, const Dbt &value); 00154 00155 void deleteRow(const Dbt &pkey, const Dbt &value); 00156 00157 string as_string() const 00158 { 00159 return "TableIndex(field=" + to_string(*_field) + ")"; 00160 } 00161 00162 string getFieldName() const 00163 { 00164 return _field->getName(); 00165 } 00166 00167 size_t getKeyLength() const { return _field->getSize(); } 00168 00169 Dbc *getDbCursor(); 00170 00171 private: 00172 TableIndex(TableIndex &); 00173 TableIndex(); 00174 TableIndex &operator=(TableIndex &); 00175 00176 ptr<TableEnvironment> _tenv; 00177 Table &_table; 00178 DbHandle _db; 00179 const TupleDescription::Field *_field; 00180 }; 00181 00182 00183 class Table { 00184 public: 00186 Table(string name, const TupleDescription schema, 00187 const DOMElement *element, ptr<TableEnvironment> tenv); 00188 00189 Table(string name, TupleDescription schema, DBTYPE db_type, 00190 int db_open_flags, ptr<TableEnvironment> tenv); 00191 00192 void Table::addIndex(const DOMElement *elt); 00193 00195 ~Table(); 00196 00197 string getName() const { return _name; } 00198 00199 const TupleDescription getSchema() const { return _schema; } 00200 00201 void insert(const void *tuple); 00202 // TODO: This might want an ExprContext. 00203 ptr<SelectQueryHandle> compileSelect(ptr<SQLSelect> select); 00204 ptr<UpdateQueryHandle> compileUpdate(ptr<SQLUpdate> select); 00205 ptr<ScanQueryHandle> getScanQueryHandle(); 00206 00208 void sync(); 00209 00210 // For queue tables 00211 unsigned int deleteFromHead(unsigned int head); 00212 void insertIntoQueue(const void *tuple) throw (AuroraException); 00213 00214 unsigned int getSize() throw (AuroraException); 00215 00216 string as_string() const 00217 { 00218 return "Table{name=" + _name + "; schema=" + _schema.getName() + "}"; 00219 } 00220 00221 // The following methods are used by the cursors. They 00222 // should probably be protected in some way or another. 00223 Dbc *getDbCursor(); 00224 const vector<string> &getKeyFieldNames() const 00225 { return _key_field_names; } 00226 vector<ptr<TableIndex> > &getIndexes() { return _indexes; } 00227 void insertIntoIndexes(const Dbt &_key, const Dbt &_value); 00228 void deleteFromIndexes(const Dbt &_key, const Dbt &_value); 00229 00230 protected: 00231 void evalKey(char *buf, const char *row); 00232 00233 private: 00234 string _name; 00235 Params _params; 00236 TupleDescription _schema; 00237 ptr<TableEnvironment> _tenv; 00238 DbHandle _db; 00239 DBTYPE _db_type; 00240 int _db_open_flags; 00241 00242 vector<string> _key_field_names; 00243 vector<TupleDescription::Field> _key_fields; 00244 int _key_length; 00245 char *_key_buffer; 00246 00247 vector<ptr<TableIndex> > _indexes; 00248 00249 // Working buffer for new rows, used by doUpdate. 00250 // TODO: This might be vestigial. 00251 char *_row_buffer; 00252 00253 void init(); 00254 00255 public: 00256 // Abstract base class for cursors. 00257 // TODO: Make cursors not share evalcontexts. 00258 class Cursor { 00259 public: 00263 virtual void setTuple(const char *tuple) = 0; 00264 00267 virtual void reset() = 0; 00268 00270 virtual bool avail() const = 0; 00271 00274 virtual const char *rowData() const = 0; 00275 00278 virtual void deleteRow() const = 0; 00279 00281 virtual string as_string() const 00282 { 00283 return to_string(typeid(*this)); 00284 } 00285 00287 virtual Cursor& operator ++ () = 0; 00288 00289 virtual ~Cursor() {} 00290 private: 00292 Cursor operator ++ (int); 00293 }; 00294 00295 private: 00296 ptr<Cursor> cursorFactory(ptr<SQLWhereClause> wc); 00297 }; 00298 00299 BOREALIS_NAMESPACE_END; 00300 00301 static inline string to_string(const Dbt &dbt) { 00302 return "Dbt(" + to_escaped_string(dbt.get_data(), 00303 dbt.get_size()) + ")"; 00304 } 00305 00306 #endif

Generated on Fri Nov 12 15:15:22 2004 for Borealis by doxygen 1.3.8