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
00068
00069
virtual const char *
old_row()
const = 0;
00070
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
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;
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
00203 ptr<SelectQueryHandle>
compileSelect(ptr<SQLSelect> select);
00204 ptr<UpdateQueryHandle>
compileUpdate(ptr<SQLUpdate> select);
00205 ptr<ScanQueryHandle>
getScanQueryHandle();
00206
00208
void sync();
00209
00210
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
00222
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
00250
00251
char *_row_buffer;
00252
00253
void init();
00254
00255
public:
00256
00257
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