00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "eyedb_p.h"
00026 #include "CollectionBE.h"
00027 #include "OQLBE.h"
00028 #include "BEQueue.h"
00029 #include "kernel.h"
00030
00031 #include "Attribute_p.h"
00032
00033 #define COLLBE_BTREE
00034
00035 namespace eyedb {
00036
00037 CollectionBE::CollectionBE(Database *_db, DbHandle *_dbh,
00038 const Oid *_oid,
00039 Class *_class,
00040 const Oid& _idx1_oid,
00041 const Oid& _idx2_oid,
00042 eyedbsm::Idx *_idx1, eyedbsm::Idx *_idx2,
00043 int _items_cnt, Bool _locked,
00044 const Oid& _inv_oid,
00045 eyedblib::int16 _inv_num_item,
00046 IndexImpl *_idximpl,
00047 Data idx_data, Size idx_data_size,
00048 Bool _is_literal,
00049 Bool _is_pure_literal) :
00050 cls(_class),
00051 db(_db), dbh(_dbh), oid(*_oid),
00052 idx1_oid(_idx1_oid),
00053 idx2_oid(_idx2_oid), idx1(_idx1), idx2(_idx2),
00054 items_cnt(_items_cnt), locked(_locked),
00055 inv_oid(_inv_oid),
00056 inv_num_item(_inv_num_item),
00057 inv_item(NULL),
00058 idximpl(_idximpl),
00059 is_literal(_is_literal),
00060 is_pure_literal(_is_pure_literal),
00061 inv_item_done(False)
00062 {
00063 status = Success;
00064 if (!cls) {
00065 isref = True;
00066 dim = 1;
00067 item_size = sizeof(eyedbsm::Oid);
00068 }
00069 else
00070 coll_class = cls->asCollectionClass()->getCollClass(&isref, &dim,
00071 &item_size);
00072
00073 buff = (unsigned char *)malloc(item_size);
00074 idx_ctx = new AttrIdxContext(idx_data, idx_data_size);
00075
00076
00077
00078
00079
00080
00081 type = (IteratorAtomType)0;
00082
00083 if (is_pure_literal) {
00084 assert(inv_oid.isValid());
00085 assert(idx_data_size);
00086 }
00087 }
00088
00089 CollectionBE::CollectionBE(Database *_db, DbHandle *_dbh,
00090 const Oid *_oid,
00091 Bool _locked) :
00092 db(_db), dbh(_dbh), oid(*_oid), locked(_locked), inv_item(NULL), inv_item_done(False)
00093 {
00094
00095 static const int _size = IDB_COLL_SIZE_HEAD + sizeof(char) + sizeof(eyedblib::int16);
00096 unsigned char temp[_size];
00097
00098 buff = 0;
00099 idx_ctx = 0;
00100 idx1 = idx2 = 0;
00101 RPCStatus rpc_status = dataRead(db->getDbHandle(), 0, _size,
00102 temp, 0, oid.getOid());
00103 status = StatusMake(rpc_status);
00104 if (status)
00105 return;
00106
00107 Offset offset;
00108
00109 eyedbsm::Oid oid_cl = ClassOidDecode(temp);
00110 cls = db->getSchema()->getClass(oid_cl);
00111 if (!cls) {
00112 isref = True;
00113 dim = 1;
00114 item_size = sizeof(eyedbsm::Oid);
00115 }
00116 else
00117 coll_class = ((CollectionClass *)cls)->getCollClass(&isref, &dim, &item_size);
00118
00119 offset = IDB_COLL_OFF_ITEMS_CNT;
00120 int32_decode(temp, &offset, &items_cnt);
00121
00122 offset = IDB_COLL_OFF_IDX1_OID;
00123 oid_decode(temp, &offset, idx1_oid.getOid());
00124
00125 offset = IDB_COLL_OFF_IDX2_OID;
00126 oid_decode(temp, &offset, idx2_oid.getOid());
00127
00128 offset = IDB_COLL_OFF_INV_OID;
00129 eyedbsm::Oid se_inv_oid;
00130 oid_decode(temp, &offset, &se_inv_oid);
00131 inv_oid.setOid(se_inv_oid);
00132 int16_decode(temp, &offset, &inv_num_item);
00133
00134 is_literal = False;
00135 is_pure_literal = False;
00136 if (db->getVersionNumber() >= 20414) {
00137 offset = IDB_COLL_OFF_COLL_NAME;
00138 char x;
00139 char_decode(temp, &offset, &x);
00140 Collection::decodeLiteral(x, is_literal, is_pure_literal);
00141
00142 eyedblib::int16 idx_data_size;
00143 int16_decode(temp, &offset, &idx_data_size);
00144 assert(offset == sizeof(temp));
00145
00146 if (is_pure_literal) {
00147 assert(inv_oid.isValid());
00148 assert(idx_data_size);
00149 }
00150
00151 if (idx_data_size) {
00152 unsigned char *x = (unsigned char*)malloc(idx_data_size);
00153 rpc_status = dataRead(db->getDbHandle(), _size, idx_data_size,
00154 x, 0, oid.getOid());
00155 status = StatusMake(rpc_status);
00156 if (status)
00157 return;
00158
00159 idx_ctx = new AttrIdxContext(x, idx_data_size);
00160 free(x);
00161
00162
00163
00164 }
00165 }
00166
00167
00168
00169
00170
00171
00172 offset = IDB_COLL_OFF_IMPL_BEGIN;
00173 IndexImpl::decode(db, temp, offset, idximpl);
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 if (isBIdx())
00184 idx1 = new eyedbsm::BIdx
00185 (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00186 *idx1_oid.getOid());
00187 else
00188 idx1 = new eyedbsm::HIdx
00189 (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00190 idx1_oid.getOid(), 0, 0);
00191
00192 static const char fmt_error[] = "storage manager error '%s' reported when opening index in back end collection";
00193
00194 if (idx1->status())
00195 {
00196 status = Exception::make(IDB_COLLECTION_BACK_END_ERROR, fmt_error, eyedbsm::statusGet(idx1->status()));
00197 delete idx1;
00198 idx1 = 0;
00199 idx2 = 0;
00200 return;
00201 }
00202
00203 if (idx2_oid.isValid()) {
00204 #ifdef COLLBE_BTREE
00205 if (1)
00206 #else
00207 if (isBIdx())
00208 #endif
00209 idx2 = new eyedbsm::BIdx
00210 (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00211 *idx2_oid.getOid());
00212 else
00213 idx2 = new eyedbsm::HIdx
00214 (get_eyedbsm_DbHandle((DbHandle *)db->getDbHandle()->u.dbh),
00215 idx2_oid.getOid(), 0, 0);
00216
00217 if (idx2->status()) {
00218 status = Exception::make(IDB_COLLECTION_BACK_END_ERROR, fmt_error, eyedbsm::statusGet(idx2->status()));
00219 delete idx1;
00220 delete idx2;
00221 idx1 = 0;
00222 idx2 = 0;
00223 return;
00224 }
00225 }
00226 else
00227 idx2 = 0;
00228
00229 status = Success;
00230 type = (IteratorAtomType)0;
00231 buff = (unsigned char *)malloc(item_size);
00232 }
00233
00234
00235 IteratorAtomType
00236 CollectionBE::getType()
00237 {
00238 if (type)
00239 return type;
00240
00241 if (isref && dim == 1)
00242 return IteratorAtom_OID;
00243
00244 if (!cls)
00245 return IteratorAtom_IDR;
00246
00247 const char *name = cls->asCollectionClass()->getCollClass()->getName();
00248
00249 if (!strcmp(name, char_class_name) && dim > 1)
00250 return IteratorAtom_STRING;
00251
00252 assert(dim == 1);
00253
00254 if (!strcmp(name, char_class_name))
00255 return IteratorAtom_CHAR;
00256
00257 if (!strcmp(name, int16_class_name))
00258 return IteratorAtom_INT16;
00259
00260 if (!strcmp(name, int32_class_name))
00261 return IteratorAtom_INT32;
00262
00263 if (!strcmp(name, int64_class_name))
00264 return IteratorAtom_INT64;
00265
00266 if (!strcmp(name, float_class_name))
00267 return IteratorAtom_DOUBLE;
00268
00269 return IteratorAtom_IDR;
00270 }
00271
00272 void
00273 CollectionBE::decode(const void* k, IteratorAtom &atom)
00274 {
00275 type = getType();
00276
00277 atom.type = type;
00278
00279 Offset offset = 0;
00280
00281 if (type == IteratorAtom_OID)
00282 oid_decode((Data)k, &offset, &atom.oid);
00283
00284 else if (type == IteratorAtom_INT16)
00285 int16_decode((Data)k, &offset, &atom.i16);
00286
00287 else if (type == IteratorAtom_INT32)
00288 int32_decode((Data)k, &offset, &atom.i32);
00289
00290 else if (type == IteratorAtom_INT64)
00291 int64_decode((Data)k, &offset, &atom.i64);
00292
00293 else if (type == IteratorAtom_DOUBLE)
00294 double_decode((Data)k, &offset, &atom.d);
00295
00296 else if (type == IteratorAtom_CHAR)
00297 memcpy(&atom.c, k, item_size);
00298
00299 else if (type == IteratorAtom_STRING)
00300 atom.str = strdup((char *)k);
00301
00302 else if (type == IteratorAtom_IDR) {
00303 atom.data.size = item_size;
00304 atom.data.idr = (unsigned char *)malloc(item_size);
00305 memcpy(atom.data.idr, k, item_size);
00306 }
00307
00308 else
00309 assert(0);
00310 }
00311
00312 void
00313 CollectionBE::decode(const void* k, Data idr)
00314 {
00315 IteratorAtom atom;
00316 decode(k, atom);
00317
00318 if (type == IteratorAtom_OID)
00319 memcpy(idr, &atom.oid, item_size);
00320
00321 else if (type == IteratorAtom_INT16)
00322 memcpy(idr, &atom.i16, item_size);
00323
00324 else if (type == IteratorAtom_INT32)
00325 memcpy(idr, &atom.i32, item_size);
00326
00327 else if (type == IteratorAtom_INT64)
00328 memcpy(idr, &atom.i64, item_size);
00329
00330 else if (type == IteratorAtom_DOUBLE)
00331 memcpy(idr, &atom.d, item_size);
00332
00333 else if (type == IteratorAtom_CHAR)
00334 memcpy(idr, &atom.c, item_size);
00335
00336 else if (type == IteratorAtom_STRING)
00337 memcpy(idr, atom.str, item_size);
00338
00339 else if (type == IteratorAtom_IDR)
00340 memcpy(idr, atom.data.idr, item_size);
00341
00342 else
00343 assert(0);
00344 }
00345
00346 Status
00347 CollectionBE::getInvItem(Database *_db,
00348 const Attribute *&_inv_item,
00349 Oid& _inv_oid, eyedbsm::Idx *&se_idx) const
00350 {
00351 _inv_oid = inv_oid;
00352
00353 if (!inv_oid.isValid()) {
00354 _inv_item = 0;
00355 assert(!is_pure_literal);
00356 return Success;
00357 }
00358
00359 Index *idx = 0;
00360 Status s;
00361 if (inv_item_done) {
00362 _inv_item = inv_item;
00363 if (inv_item && idx_ctx) {
00364 s = const_cast<Attribute *>(inv_item)->indexPrologue(db, *idx_ctx, idx, True);
00365 if (s) return s;
00366 }
00367
00368 se_idx = (idx ? idx->idx : 0);
00369 return Success;
00370 }
00371
00372
00373 Oid inv_cls_oid;
00374
00375 if (s = _db->getObjectClass(inv_oid, inv_cls_oid))
00376 return s;
00377
00378 Bool removed;
00379 if (s = _db->isRemoved(inv_cls_oid, removed))
00380 return s;
00381
00382 if (removed) {
00383 const_cast<CollectionBE *>(this)->inv_item = 0;
00384 const_cast<CollectionBE *>(this)->inv_item_done = True;
00385 _inv_item = inv_item;
00386 se_idx = 0;
00387 return Success;
00388 }
00389
00390
00391 Class *inv_class;
00392
00393 if (s = _db->getObjectClass(inv_oid, inv_class))
00394 return s;
00395
00396 const_cast<CollectionBE *>(this)->inv_item =
00397 (idx_ctx && idx_ctx->getClassOwner() ? idx_ctx->getAttribute(inv_class) :
00398 inv_class->getAttributes()[inv_num_item]);
00399
00400 const_cast<CollectionBE *>(this)->inv_item_done = True;
00401 assert(inv_item);
00402
00403 _inv_item = inv_item;
00404
00405 if (idx_ctx) {
00406 s = const_cast<Attribute *>(inv_item)->indexPrologue(db, *idx_ctx, idx, True);
00407 if (s) return s;
00408 }
00409
00410 se_idx = (idx ? idx->idx : 0);
00411
00412 return Success;
00413 }
00414
00415 CollectionBE::~CollectionBE()
00416 {
00417
00418 db->getBEQueue()->removeCollection(this, dbh);
00419 if (idximpl)
00420 idximpl->release();
00421 idximpl = 0;
00422 free(buff);
00423 delete idx1;
00424 delete idx2;
00425 delete idx_ctx;
00426 idx1 = idx2 = 0;
00427 idx_ctx = 0;
00428 }
00429
00430 Class *CollectionBE::getClass(Bool &_isref,
00431 int &_dim,
00432 eyedblib::int16 &_item_size) const
00433 {
00434 _isref = isref;
00435 _dim = dim;
00436 _item_size = item_size;
00437 return cls;
00438 }
00439
00440 void CollectionBE::getIdx(eyedbsm::Idx **ridx1, eyedbsm::Idx **ridx2)
00441 {
00442 if (ridx1)
00443 *ridx1 = idx1;
00444 if (ridx2)
00445 *ridx2 = idx2;
00446 }
00447
00448 Data CollectionBE::getTempBuff()
00449 {
00450 return buff;
00451 }
00452
00453 eyedblib::int16 CollectionBE::getItemSize() const
00454 {
00455 return item_size;
00456 }
00457
00458 Bool CollectionBE::getIsRef() const
00459 {
00460 return isref;
00461 }
00462
00463 const Oid& CollectionBE::getOid() const
00464 {
00465 return oid;
00466 }
00467
00468 Database *CollectionBE::getDatabase()
00469 {
00470 return db;
00471 }
00472
00473 DbHandle *CollectionBE::getDbHandle()
00474 {
00475 return dbh;
00476 }
00477
00478 Status CollectionBE::getStatus() const
00479 {
00480 return status;
00481 }
00482 }