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 "ValueCache.h"
00027 #include <assert.h>
00028 #include "AttrNative.h"
00029
00030
00031
00032 namespace eyedb {
00033
00034 void CollSet::init()
00035 {
00036 allow_dup = False;
00037 ordered = False;
00038 type = _CollSet_Type;
00039 if (!status)
00040 setClass(CollSetClass::make(coll_class, isref, dim, status));
00041 }
00042
00043 CollSet::CollSet(const char *n, Class *_class,
00044 const Oid& _idx1_oid,
00045 const Oid& _idx2_oid,
00046 int icnt,
00047 int _bottom, int _top,
00048 const IndexImpl *_idximpl,
00049 Object *_card,
00050 Bool _is_literal,
00051 Bool _is_pure_literal,
00052 Data _idx_data, Size _idx_data_size)
00053 : Collection(n, _class, _idx1_oid, _idx2_oid, icnt,
00054 _bottom, _top, _idximpl, _card, _is_literal, _is_pure_literal, _idx_data,
00055 _idx_data_size)
00056 {
00057 init();
00058 setClass(_class);
00059 }
00060
00061 CollSet::CollSet(const char *n, Class *_coll_class, Bool _isref,
00062 const IndexImpl *_idximpl) :
00063 Collection(n, _coll_class, _isref, _idximpl)
00064 {
00065 init();
00066 }
00067
00068 CollSet::CollSet(const char *n, Class *_coll_class, int _dim,
00069 const IndexImpl *_idximpl) :
00070 Collection(n, _coll_class, _dim, _idximpl)
00071 {
00072 init();
00073 }
00074
00075 CollSet::CollSet(Database *_db, const char *n, Class *_coll_class, Bool _isref, const IndexImpl *_idximpl)
00076 : Collection(n, _coll_class, _isref, _idximpl)
00077 {
00078 init();
00079 if (!status)
00080 status = setDatabase(_db);
00081 }
00082
00083 CollSet::CollSet(Database *_db, const char *n, Class *_coll_class, int _dim, const IndexImpl *_idximpl) :
00084 Collection(n, _coll_class, _dim, _idximpl)
00085 {
00086 init();
00087 if (!status)
00088 status = setDatabase(_db);
00089 }
00090
00091 CollSet::CollSet(const CollSet& o) : Collection(o)
00092 {
00093 allow_dup = False;
00094 ordered = False;
00095 type = _CollSet_Type;
00096 }
00097
00098 CollSet& CollSet::operator=(const CollSet& o)
00099 {
00100 *(Collection *)this = (Collection &)o;
00101 allow_dup = False;
00102 ordered = False;
00103 type = _CollSet_Type;
00104 return *this;
00105 }
00106
00107 const char *CollSet::getClassName() const
00108 {
00109 return CollSet_Class->getName();
00110 }
00111
00112 Status CollSet::insert_p(const Oid &item_oid, Bool noDup)
00113 {
00114 if (status)
00115 return Exception::make(status);
00116
00117
00118
00119
00120
00121
00122
00123
00124 if (CollectionPeer::isLocked(this))
00125 return Exception::make(IDB_COLLECTION_LOCKED, "collection '%s' is locked for writing", name);
00126
00127 Status s = check(item_oid, IDB_COLLECTION_INSERT_ERROR);
00128 if (s) return s;
00129
00130 ValueItem *item;
00131
00132 IDB_COLL_LOAD_DEFERRED();
00133 touch();
00134
00135 if (cache && (item = cache->get(item_oid)))
00136 {
00137 if (item->getState() != removed)
00138 {
00139 if (noDup)
00140 return Success;
00141 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "item '%s' is already in collection", item_oid.getString());
00142 }
00143
00144
00145 item->setState(added);
00146 v_items_cnt++;
00147 return Success;
00148 }
00149
00150 if (getOidC().isValid())
00151 {
00152 int found, ind;
00153
00154 RPCStatus rpc_status;
00155
00156 if ((rpc_status = collectionGetByOid(db->getDbHandle(),
00157 getOidC().getOid(),
00158 item_oid.getOid(), &found, &ind)) ==
00159 RPCSuccess)
00160 {
00161 if (found)
00162 {
00163 if (noDup)
00164 return Success;
00165
00166 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "item '%s' is already in collection", item_oid.getString());
00167 }
00168 }
00169 else
00170 {
00171 return StatusMake(IDB_COLLECTION_INSERT_ERROR, rpc_status);
00172 }
00173 }
00174
00175 create_cache();
00176
00177 cache->insert(item_oid, ValueCache::DefaultItemID, added);
00178 v_items_cnt++;
00179
00180 return Success;
00181 }
00182
00183 Status CollSet::insert_p(const Object *item_o, Bool noDup)
00184 {
00185 if (status)
00186 return Exception::make(status);
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 if (!isref) {
00199 Status s = check(item_o, IDB_COLLECTION_INSERT_ERROR);
00200 if (s) return s;
00201 return insert_p(item_o->getIDR() + IDB_OBJ_HEAD_SIZE, noDup);
00202 }
00203
00204 if (CollectionPeer::isLocked(this))
00205 return Exception::make(IDB_COLLECTION_LOCKED, "collection '%s' is locked for writing", name);
00206
00207 Status s = check(item_o, IDB_COLLECTION_INSERT_ERROR);
00208 if (s) return s;
00209
00210 IDB_COLL_LOAD_DEFERRED();
00211 touch();
00212 ValueItem *item;
00213
00214 if (cache && (item = cache->get(item_o))){
00215 if (item->getState() != removed) {
00216 if (noDup)
00217 return Success;
00218
00219 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "item 0x%x is already in the collection cache", item_o);
00220 }
00221
00222 #if 0
00223 cache->suppressObject(item);
00224 cache->insert(item_o, item->getInd(), added);
00225 #else
00226 item->setState(added);
00227 #endif
00228 v_items_cnt++;
00229 return Success;
00230 }
00231
00232 Oid item_oid = item_o->getOid();
00233 Bool valid = item_oid.isValid();
00234
00235 if (valid && cache && (item = cache->get(item_oid)))
00236 {
00237 if (noDup)
00238 return Success;
00239 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "item '%s' is already in collection", item_oid.getString());
00240 }
00241
00242 if (valid && getOidC().isValid())
00243 {
00244 int found, ind;
00245
00246 RPCStatus rpc_status;
00247
00248 if ((rpc_status = collectionGetByOid(db->getDbHandle(), getOidC().getOid(),
00249 item_oid.getOid(), &found, &ind)) ==
00250 RPCSuccess)
00251 {
00252 if (found)
00253 {
00254 if (noDup)
00255 return Success;
00256 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "item '%s' is already in collection '%s'", item_oid.getString(), name);
00257 }
00258 }
00259 else
00260 return StatusMake(IDB_COLLECTION_INSERT_ERROR, rpc_status);
00261 }
00262
00263 create_cache();
00264
00265 cache->insert(item_o, ValueCache::DefaultItemID, added);
00266 v_items_cnt++;
00267
00268 return Success;
00269 }
00270
00271 Status CollSet::insert_p(Data val, Bool noDup, Size size)
00272 {
00273 if (status)
00274 return Exception::make(status);
00275
00276 if (CollectionPeer::isLocked(this))
00277 return Exception::make(IDB_COLLECTION_LOCKED, "collection '%s' is locked for writing", name);
00278
00279 Status s = check(val, size, IDB_COLLECTION_INSERT_ERROR);
00280 if (s) return s;
00281
00282 IDB_COLL_LOAD_DEFERRED();
00283 touch();
00284 ValueItem *item;
00285
00286 Data item_data = make_data(val, size, True);
00287
00288 if (!item_data)
00289 return Exception::make(IDB_COLLECTION_ERROR, "data too long for collection insertion");
00290
00291 if (cache && (item = cache->get(item_data, item_size))) {
00292 int s = item->getState();
00293 if (s != removed) {
00294 if (noDup)
00295 return Success;
00296 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "value is already in the cache");
00297 }
00298
00299 item->setState(added);
00300 v_items_cnt++;
00301 return Success;
00302 }
00303
00304 if (getOidC().isValid()) {
00305 int found, ind;
00306
00307 RPCStatus rpc_status;
00308
00309 if ((rpc_status = collectionGetByValue(db->getDbHandle(), getOidC().getOid(),
00310 item_data, item_size, &found,
00311 &ind)) ==
00312 RPCSuccess)
00313 {
00314 if (found) {
00315 if (noDup)
00316 return Success;
00317 return Exception::make(IDB_COLLECTION_DUPLICATE_INSERT_ERROR, "value is already in the collection");
00318 }
00319 }
00320 else
00321 return StatusMake(IDB_COLLECTION_INSERT_ERROR, rpc_status);
00322 }
00323
00324 create_cache();
00325
00326 cache->insert(Value(item_data, item_size), ValueCache::DefaultItemID, added);
00327 v_items_cnt++;
00328
00329 return Success;
00330 }
00331 }