CollSet.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #include "eyedb_p.h"
00026 #include "ValueCache.h"
00027 #include <assert.h>
00028 #include "AttrNative.h"
00029 
00030 /* CollSet */
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       1/ on regarde si oid est present dans la cache: si oui -> return error
00118       2/ si la collection est realize'e (oid valid) on fait:
00119       collectionGetByValue() -> si found -> return error
00120       3/ on insere dans le cache avec le state `added'
00121       v_items_cnt++;
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     //    cache->insert(item_oid, v_items_cnt, added);
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       1/ on regarde si o est present dans la cache: si oui -> return error
00189       2/ o->getOid() est valid, on regarde si presen dans la cache: si oui ->
00190       return error
00191       3/ si o->getOid() est valid ET si la collection est realize'e (oid 
00192       valid) on fait:
00193       collectionGetByOid() -> si found -> return error
00194       4/ on insere dans le cache avec le state `added'
00195       v_items_cnt++;
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     //    cache->insert(item_o, v_items_cnt, added);
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     //    cache->insert(Value(item_data, item_size), v_items_cnt, added);
00326     cache->insert(Value(item_data, item_size), ValueCache::DefaultItemID, added);
00327     v_items_cnt++;
00328 
00329     return Success;
00330   }
00331 }

Generated on Mon Dec 22 18:15:52 2008 for eyedb by  doxygen 1.5.3