00001
#ifndef TABLE_CURSORS_H
00002
#define TABLE_CURSORS_H
00003
00004
#include "Table.h"
00005
00008 class TableScanCursor :
public Table::Cursor {
00009
public:
00010
static ptr<TableScanCursor>
factory(
Table *table,
00011 ptr<SQLWhereClause> wc);
00012
00014 bool avail()
const {
00015
return _avail;
00016 }
00017
00020 const char *
rowData()
const {
00021 ASSERT(
avail());
00022
return (
char *)_row.get_data();
00023 }
00024
00027 virtual void deleteRow()
const {
00028
try {
00029 _table->
deleteFromIndexes(_key, _row);
00030 _dbc->del(0);
00031 }
catch (DbException &e) {
00032
Throw(AuroraBadEntityException, string() +
00033
"DbException while deleting row: "
00034 + e.what());
00035 }
00036 }
00037
00038 virtual void setTuple(
const char *tuple) {
00039 _ctxt.
setTuple(0, tuple);
00040 }
00041
00042 virtual void reset() {
00043
try {
00044
int ret = _dbc->get(&_key, &_row, DB_FIRST);
00045
if (ret == DB_NOTFOUND) {
00046
00047 _avail =
false;
00048 }
else if (ret == 0) {
00049 _ctxt.
setTuple(1, (
const char *)_row.get_data());
00050
if (!_where_clause ||
00051 _where_clause->eval<
bool>(_ctxt)) {
00052 DEBUG <<
"Satisfied the where clause";
00053 _avail =
true;
00054 }
else {
00055
00056 ++(*this);
00057 }
00058 }
else {
00059
00060 ASSERT(
false);
00061 }
00062 }
catch (DbException &e) {
00063
Throw(AuroraBadEntityException, string() +
00064
"DbException while resetting cursor: "
00065 + e.what());
00066 }
00067 }
00068
00071 virtual TableScanCursor&
operator ++ () {
00072
try {
00073
int ret;
00074
while ((ret = _dbc->get(&_key, &_row, DB_NEXT)) == 0) {
00075
00076 _ctxt.
reset();
00077 _ctxt.
setTuple(1, (
const char *)_row.get_data());
00078
00079
if (!_where_clause ||
00080 _where_clause->eval<
bool>(_ctxt)) {
00081 DEBUG <<
"Satisfied the where clause";
00082 _avail =
true;
00083
return *
this;
00084 }
00085 }
00086
if (ret == DB_NOTFOUND) {
00087 DEBUG <<
"No more results available in table";
00088 _avail =
false;
00089 }
00090
return *
this;
00091 }
catch (DbException &e) {
00092
Throw(AuroraBadEntityException, string() +
00093
"DbException while retrieving next result from table: "
00094 + e.what());
00095 }
00096 }
00097
00098 virtual string
as_string()
const {
00099
return "TableScanCursor(where=" +
00100
to_string(_where_clause) +
")" ;
00101 }
00102
00103
00104 TableScanCursor(
Table *table,
00105 ptr<Expression> where_clause) :
00106 _table(table), _dbc(_table->getDbCursor()),
00107 _where_clause(where_clause), _ctxt(2)
00108 {
00109 }
00110
00113 virtual ~TableScanCursor() {
00114 _dbc->close();
00115 }
00116
00117
private:
00118
Table *_table;
00119 Dbc *_dbc;
00120 ptr<Expression> _where_clause;
00121
EvalContext _ctxt;
00122 Dbt _key;
00123 Dbt _row;
00124
bool _avail;
00125 };
00126
00129 class KeyEqualCursor :
public Table::Cursor {
00130
public:
00131
static ptr<KeyEqualCursor>
factory(
Table *table,
00132 ptr<SQLWhereClause> wc);
00133
00135 bool avail()
const {
00136
return _avail;
00137 }
00138
00141 const char *
rowData()
const {
00142 ASSERT(
avail());
00143
return (
char *)_row.get_data();
00144 }
00145
00148 virtual void deleteRow()
const {
00149
try {
00150 _table->
deleteFromIndexes(_key, _row);
00151 _dbc->del(0);
00152 }
catch (DbException &e) {
00153
Throw(AuroraBadEntityException, string() +
00154
"DbException while deleting row: "
00155 + e.what());
00156 }
00157 }
00158
00159 virtual void setTuple(
const char *tuple) {
00160 _ctxt.
setTuple(0, tuple);
00161 }
00162
00163 virtual void reset() {
00164
try {
00165
Expression::evalVectorInto(_values, _key_buf, _ctxt);
00166 _key.set_data(_key_buf);
00167 _key.set_size(_key_size);
00168
00169
int ret = _dbc->get(&_key, &_row, DB_SET);
00170
if (ret == DB_NOTFOUND) {
00171
00172 DEBUG <<
"No rows on reset for key "
00173 << to_hex_string(_key_buf, _key_size);
00174 _avail =
false;
00175 }
else if (ret == 0) {
00176
00177
00178 _ctxt.
setTuple(1, (
const char *)_row.get_data());
00179
00180 DEBUG <<
"Satisfied the where clause";
00181 _avail =
true;
00182 }
else {
00183
00184 ASSERT(
false);
00185 }
00186 }
catch (DbException &e) {
00187
Throw(AuroraBadEntityException, string() +
00188
"DbException while resetting cursor: "
00189 + e.what());
00190 }
00191 }
00192
00195 virtual KeyEqualCursor&
operator ++ () {
00196
00197 _avail =
false;
00198
return *
this;
00199 }
00200
00201 virtual string
as_string()
const {
00202
return "KeyEqualCursor(values=" +
to_string(_values) +
")";
00203 }
00204
00205
00206 KeyEqualCursor(
Table *table, size_t key_size,
00207 ptr<Expression> value) :
00208 _table(table),
00209 _dbc(_table->getDbCursor()), _values(1),
00210 _ctxt(2), _key_size(key_size)
00211 {
00212 _values[0] = value;
00213 _key_buf =
new char[_key_size];
00214 }
00215
00216
00217 KeyEqualCursor(
Table *table, size_t key_size,
00218 vector<ptr<Expression> > values) :
00219 _table(table), _dbc(_table->getDbCursor()), _values(values),
00220 _ctxt(2), _key_size(key_size)
00221 {
00222 _key_buf =
new char[_key_size];
00223 }
00224
00227 virtual ~KeyEqualCursor() {
00228 _dbc->close();
00229
delete[] _key_buf;
00230 }
00231
00232
private:
00233
Table *_table;
00234 Dbc *_dbc;
00235 vector<ptr<Expression> > _values;
00236
EvalContext _ctxt;
00237 size_t _key_size;
00238
char *_key_buf;
00239 Dbt _key;
00240 Dbt _row;
00241
bool _avail;
00242 };
00243
00246 class IndexKeyEqualCursor :
public Table::Cursor {
00247
public:
00248
static ptr<IndexKeyEqualCursor>
factory(
Table *table,
00249 ptr<SQLWhereClause> wc);
00250
00252 virtual bool avail()
const {
00253
return _avail;
00254 }
00255
00258 const char *
rowData()
const {
00259 ASSERT(
avail());
00260
return (
char *)_row.get_data();
00261 }
00262
00265 virtual void deleteRow()
const {
00266
try {
00267 _table->
deleteFromIndexes(_pkey, _row);
00268 _pdbc->del(0);
00269 }
catch (DbException &e) {
00270
Throw(AuroraBadEntityException, string() +
00271
"DbException while deleting row: "
00272 + e.what());
00273 }
00274 }
00275
00276 virtual void setTuple(
const char *tuple) {
00277 _ctxt.
setTuple(0, tuple);
00278 }
00279
00280 virtual void reset() {
00281
try {
00282 _value->evalInto(_key_buf, _ctxt);
00283 _skey.set_data(_key_buf);
00284 _skey.set_size(_key_size);
00285
00286
int ret = _sdbc->get(&_skey, &_pkey, DB_SET);
00287
if (ret == DB_NOTFOUND) {
00288
00289 DEBUG <<
"No rows on reset for secondary key "
00290 << _skey;
00291 _avail =
false;
00292 }
else if (ret == 0) {
00293 getPrimaryRow();
00294
return;
00295 }
else {
00296
00297 ASSERT(
false);
00298 }
00299 }
catch (DbException &e) {
00300
Throw(AuroraBadEntityException, string() +
00301
"DbException while resetting cursor: "
00302 + e.what());
00303 }
00304 }
00305
00308 virtual IndexKeyEqualCursor&
operator ++ () {
00309
00310
00311
int ret = _sdbc->get(&_skey, &_pkey, DB_NEXT_DUP);
00312
if (ret == DB_NOTFOUND) {
00313
00314 _avail =
false;
00315 }
else if (ret == 0) {
00316 getPrimaryRow();
00317 }
else {
00318
00319 ASSERT(
false);
00320 }
00321
return *
this;
00322 }
00323
00324 virtual string
as_string()
const {
00325
return "IndexKeyEqualCursor(value=" +
to_string(_value) +
")";
00326 }
00327
00328
00329 IndexKeyEqualCursor(
Table *table,
TableIndex *table_index,
00330 size_t key_size, ptr<Expression> value) :
00331 _table(table), _table_index(table_index),
00332 _pdbc(_table->getDbCursor()),
00333 _sdbc(_table_index->getDbCursor()),
00334 _value(value), _ctxt(2), _key_size(key_size),
00335 _key_buf(new char[_key_size]), _avail(false)
00336 {}
00337
00340 virtual ~IndexKeyEqualCursor() {
00341 _pdbc->close();
00342 _sdbc->close();
00343
delete[] _key_buf;
00344 }
00345
00346
private:
00348
void getPrimaryRow() {
00349
int ret = _pdbc->get(&_pkey, &_row, DB_SET);
00350
if (ret == DB_NOTFOUND) {
00351
00352 FATAL <<
"No rows for primary key " << _pkey;
00353 }
else if (ret == 0) {
00354
00355
00356 _ctxt.
setTuple(1, (
const char *)_row.get_data());
00357
00358 DEBUG <<
"Satisfied the where clause";
00359 _avail =
true;
00360 }
else {
00361
00362 ASSERT(
false);
00363 }
00364 }
00365
00366
Table *_table;
00367
TableIndex *_table_index;
00368 Dbc *_pdbc;
00369 Dbc *_sdbc;
00370 ptr<Expression> _value;
00371
EvalContext _ctxt;
00372 size_t _key_size;
00373
char *_key_buf;
00374 Dbt _pkey;
00375 Dbt _skey;
00376 Dbt _row;
00377
bool _avail;
00378 };
00379
00380
#endif