CollectionClass.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 <assert.h>
00027 #include "AttrNative.h"
00028 #include "CollectionBE.h"
00029 
00030 using namespace std;
00031 
00032 //
00033 // collection_class
00034 //
00035 
00036 namespace eyedb {
00037 
00038 const char *
00039 CollectionClass::make_name(const char *prefix, Class* coll_class,
00040                               Bool isref, int dim, Bool _alias)
00041 {
00042   static char name[256];
00043   const char *s = _alias ? coll_class->getAliasName() : coll_class->getName();
00044   if (dim <= 1)
00045     sprintf(name, "%s<%s%s>", prefix, s , (isref ? "*" : ""));
00046   else
00047     sprintf(name, "%s<%s%s[%d]>", prefix, s, (isref ? "*" : ""), dim);
00048   return name;
00049 }
00050 
00051 const char *CollectionClass::getCName(Bool) const
00052 {
00053 #define NN 12
00054   static char c_name[NN][128];
00055   static int which;
00056 
00057   if (which >= NN)
00058     which = 0;
00059 
00060   char *sname = c_name[which++];
00061   sprintf(sname, "%s_%s%s", getClass()->getName(),
00062           coll_class->asBasicClass() ? coll_class->getName() :
00063           coll_class->getCName(), (isref ? "_ref" : ""));
00064 
00065   if (dim > 1)
00066     {
00067       char tok[32];
00068       sprintf(tok, "_%d", dim);
00069       strcat(sname, tok);
00070     }
00071 
00072   return sname;
00073 }
00074 
00075 int
00076 get_item_size(const Class *coll_class, int dim)
00077 {
00078   Size psize, vsize, isize;
00079   coll_class->getIDRObjectSize(&psize, &vsize, &isize);
00080   return (psize - isize - IDB_OBJ_HEAD_SIZE) * dim;
00081 }
00082 
00083 Status
00084 CollectionClass::check(Class *_coll_class, Bool _isref, int _dim)
00085 {
00086   Status s = Success;
00087 
00088   if (_dim <= 0)
00089     s = Exception::make(IDB_COLLECTION_ERROR,
00090                         "invalid dimension: %d", _dim);
00091   else if (_dim > 1 && (!_coll_class || !_coll_class->asCharClass()))
00092     s = Exception::make(IDB_COLLECTION_ERROR,
00093                         "dimension > 1 are supported only for collection of bounded strings");
00094   else if (_coll_class &&
00095            !_isref &&
00096            !_coll_class->asBasicClass() &&
00097            !_coll_class->asEnumClass()) {
00098     // check for : no vardim
00099     unsigned int attr_cnt;
00100     const Attribute **attrs = _coll_class->getAttributes(attr_cnt);
00101     for (int n = 0; n < attr_cnt; n++)
00102       if (attrs[n]->isVarDim()) {
00103         s = Exception::make(IDB_COLLECTION_ERROR,
00104                             "variable dimension attribute %s::%s is not supported in collection of litterals", _coll_class->getName(),
00105                             attrs[n]->getName());
00106         break;
00107       }
00108   }
00109 
00110   return s;
00111 }
00112 
00113 CollectionClass::CollectionClass(Class *_coll_class, Bool _isref, const char *prefix) : Class("")
00114 {
00115   Exception::Mode mode = Exception::setMode(Exception::StatusMode);
00116   _status = check(_coll_class, _isref, 1);
00117   Exception::setMode(mode);
00118 
00119   if (_status)
00120     return;
00121 
00122   coll_class = _coll_class;
00123   if (coll_class && coll_class->isSystem())
00124     m_type = System;
00125 
00126   isref = _isref;
00127   dim = 1;
00128   free(name);
00129 
00130   name = strdup(make_name(prefix, coll_class, isref, 1, False));
00131   aliasname = strdup(make_name(prefix, coll_class, isref, 1, True));
00132 
00133   cl_oid.invalidate();
00134 
00135   if (isref)
00136     item_size = sizeof(Oid);
00137   else
00138     item_size = get_item_size(coll_class, dim);
00139 
00140   AttrNative::copy(CollectionITEMS, items, items_cnt, this);
00141 
00142   // should be in a method
00143   // WARNING/ERROR: assigning a non null value to psize makes
00144   // things wrong in the IDB_objectReadLocal() function.
00145   idr_psize = IDB_OBJ_HEAD_SIZE + sizeof(Oid);
00146   idr_vsize = sizeof(Object *);
00147   idr_inisize = 0;
00148   idr_objsz = idr_vsize + idr_psize;
00149 }
00150 
00151 CollectionClass::CollectionClass(Class *_coll_class, int _dim, const char *prefix) : Class("")
00152 {
00153   Exception::Mode mode = Exception::setMode(Exception::StatusMode);
00154   _status = check(_coll_class, False, _dim);
00155   Exception::setMode(mode);
00156 
00157   if (_status)
00158     return;
00159 
00160   coll_class = _coll_class;
00161   if (coll_class && coll_class->isSystem())
00162     m_type = System;
00163 
00164   isref = False;
00165   dim = _dim;
00166   free(name);
00167   name = strdup(make_name(prefix, coll_class, isref, dim, False));
00168   aliasname = strdup(make_name(prefix, coll_class, isref, dim, True));
00169 
00170   parent = Class_Class;
00171   cl_oid.invalidate();
00172 
00173   item_size = get_item_size(coll_class, dim);
00174 
00175   AttrNative::copy(CollectionITEMS, items, items_cnt, this);
00176 
00177   idr_psize = IDB_OBJ_HEAD_SIZE + sizeof(Oid);
00178   idr_vsize = sizeof(Object *);
00179   idr_inisize = 0;
00180   idr_objsz = idr_vsize + idr_psize;
00181 }
00182 
00183 void
00184 CollectionClass::copy_realize(const CollectionClass &cl)
00185 {
00186   coll_class = cl.coll_class;
00187   if (coll_class && coll_class->isSystem())
00188     m_type = System;
00189   isref = cl.isref;
00190   dim = cl.dim;
00191   cl_oid = cl.cl_oid;
00192   item_size = cl.item_size;
00193   _status = cl._status;
00194 }
00195 
00196 CollectionClass::CollectionClass(const CollectionClass &cl)
00197   : Class(cl)
00198 {
00199   coll_class = 0;
00200   isref = False;
00201   dim = 0;
00202   cl_oid.invalidate();
00203   item_size = 0;
00204   _status = NULL;
00205 
00206   copy_realize(cl);
00207 }
00208 
00209 Status
00210 CollectionClass::loadComplete(const Class *cl)
00211 {
00212   assert(cl->asCollectionClass());
00213   Status s = Class::loadComplete(cl);
00214   if (s) return s;
00215   copy_realize(*cl->asCollectionClass());
00216   return Success;
00217 }
00218 
00219 CollectionClass::CollectionClass(const Oid &_oid, const char *_name) :
00220 Class(_oid, _name)
00221 {
00222 }
00223 
00224 CollectionClass& CollectionClass::operator=(const CollectionClass &cl)
00225 {
00226   this->Class::operator=(cl);
00227   copy_realize(cl);
00228   return *this;
00229 }
00230 
00231 #define RECURS_BUG // added the 11/06/99
00232 
00233 Bool CollectionClass::compare_perform(const Class *cl,
00234                                       Bool compClassOwner,
00235                                       Bool compNum,
00236                                       Bool compName,
00237                                       Bool inDepth) const
00238 {
00239   if (!cl->asCollectionClass())
00240     return False;
00241 
00242 #ifdef RECURS_BUG
00243   if (state & Realizing)
00244     return True;
00245 #endif
00246 
00247 #ifdef RECURS_BUG
00248   ((CollectionClass *)this)->state |= Realizing;
00249 #endif
00250 
00251   Bool cl_isref;
00252   eyedblib::int16 cl_dim, cl_item_size;
00253   const Class *cl_collclass = cl->asCollectionClass()->
00254     getCollClass(&cl_isref, &cl_dim, &cl_item_size);
00255 
00256   if (cl_isref != isref || cl_dim != dim || cl_item_size != item_size)
00257     {
00258 #ifdef RECURS_BUG
00259       ((CollectionClass *)this)->state &= ~Realizing;
00260 #endif
00261       return False;
00262     }
00263 
00264   Bool r = coll_class->compare(cl_collclass, compClassOwner,
00265                                compNum, compName, inDepth);
00266 #ifdef RECURS_BUG
00267   ((CollectionClass *)this)->state &= ~Realizing;
00268 #endif
00269   return r;
00270 }
00271 
00272 Status
00273 CollectionClass::create()
00274 {
00275   if (oid.isValid())
00276     return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating collection_class '%s'", name);
00277 
00278   IDB_CHECK_WRITE(db);
00279   /*
00280   printf("creating COLLCLASS %s cl_oid %s %s\n", name, cl_oid.toString(),
00281          coll_class->getName());
00282   */
00283   RPCStatus rpc_status;
00284   Size alloc_size;
00285   Offset offset, cl_oid_offset;
00286   ObjectHeader hdr;
00287   Status status;
00288 
00289   alloc_size = 0;
00290   //idr->idr = 0;
00291   idr->setIDR((Size)0);
00292   Data data = 0;
00293 
00294   /*
00295   offset = IDB_CLASS_MAG_ORDER;
00296   int32_code (&data, &offset, &alloc_size, (eyedblib::int32 *)&mag_order);
00297   */
00298   offset = IDB_CLASS_IMPL_TYPE;
00299   status = IndexImpl::code(data, offset, alloc_size, *idximpl);
00300   if (status) return status;
00301 
00302   offset = IDB_CLASS_MTYPE;
00303   eyedblib::int32 mt = m_type;
00304   int32_code (&data, &offset, &alloc_size, &mt);
00305 
00306   offset = IDB_CLASS_DSPID;
00307   eyedblib::int16 dspid = get_instdspid();
00308   int16_code (&data, &offset, &alloc_size, &dspid);
00309 
00310   offset = IDB_CLASS_HEAD_SIZE;
00311   
00312   if (!cl_oid.isValid())
00313     {
00314       coll_class = db->getSchema()->getClass(coll_class->getName());
00315       if (!coll_class)
00316         return Exception::make(IDB_ERROR, "creating collection_class '%s'",
00317                                     name);
00318       cl_oid = coll_class->getOid();
00319       if (!cl_oid.isValid() && !db->isBackEnd())
00320         {
00321           Status s = coll_class->create();
00322           if (s)
00323             return s;
00324           cl_oid = coll_class->getOid();
00325         }
00326     }
00327 
00328   // to avoid recursion!
00329   if (oid.isValid())
00330     return Success;
00331 
00332   status = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
00333                                &alloc_size, name);
00334   if (status) return status;
00335 
00336   cl_oid_offset = offset;
00337   oid_code   (&data, &offset, &alloc_size, cl_oid.getOid());
00338   /* isref */
00339   char kc = (char)isref;
00340   char_code (&data, &offset, &alloc_size, &kc);
00341 
00342   /* dim */
00343   int16_code (&data, &offset, &alloc_size, &dim);
00344 
00345   int idr_sz = offset;
00346   idr->setIDR(idr_sz, data);
00347   headerCode(type, idr_sz);
00348 
00349   rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(), data, oid.getOid());
00350   
00351   if (rpc_status == RPCSuccess && !cl_oid.isValid() && strcmp(coll_class->getName(), "object"))
00352     {
00353       Status status;
00354       
00355       if (status = coll_class->setDatabase(db))
00356         return status;
00357       
00358       if (status = coll_class->create())
00359         return status;
00360       
00361       cl_oid = coll_class->getOid();
00362       offset = cl_oid_offset;
00363       oid_code   (&data, &offset, &alloc_size, cl_oid.getOid());
00364       rpc_status = objectWrite(db->getDbHandle(), data, oid.getOid());
00365     }
00366 
00367   if (rpc_status == RPCSuccess)
00368     gbx_locked = gbxTrue;
00369 
00370   return StatusMake(rpc_status);
00371 }
00372 
00373 void
00374 CollectionClass::invalidateCollClassOid()
00375 {
00376   //printf("found coll class oid: %s\n", name);
00377   cl_oid.invalidate();
00378   touch();
00379 }
00380 
00381 Status
00382 CollectionClass::update()
00383 {
00384   /*
00385   printf("updating collclass %s %s modify=%d\n", name, cl_oid.toString(),
00386          modify);
00387   */
00388 
00389   if (cl_oid.isValid() && !modify)
00390     return Success;
00391 
00392   Offset offset = 0;
00393   Size alloc_size = sizeof(eyedblib::int16);
00394   unsigned char data[sizeof(eyedblib::int16)];
00395   unsigned char *pdata = data;
00396 
00397   eyedblib::int16 dspid = get_instdspid();
00398   int16_code (&pdata, &offset, &alloc_size, &dspid);
00399 
00400   //printf("setting dspid to %d\n", dspid);
00401   offset = IDB_CLASS_DSPID;
00402   RPCStatus rpc_status = 
00403     dataWrite(db->getDbHandle(), offset, sizeof(eyedblib::int16),
00404                   data, oid.getOid());
00405   if (rpc_status) return StatusMake(rpc_status);
00406 
00407   if (cl_oid.isValid())
00408     return Success;
00409 
00410   if (!coll_class) {
00411     Status s = wholeComplete();
00412     if (s) return s;
00413     if (!coll_class)
00414       return Exception::make(IDB_ERROR, "updating collection_class '%s'",
00415                              name);
00416   }
00417 
00418   string clsName = coll_class->getName();
00419   coll_class = db->getSchema()->getClass(coll_class->getName());
00420   if (!coll_class)
00421     return Exception::make(IDB_ERROR, "updating collection_class '%s' [class '%s']",
00422                               name, clsName.c_str());
00423 
00424   if (!coll_class->getOid().isValid())
00425     {
00426       //printf("ok we create now %s\n", coll_class->getName());
00427       Status status;
00428       if (status = coll_class->setDatabase(db))
00429         return status;
00430       
00431       if (status = coll_class->create())
00432         return status;
00433     }
00434 
00435   cl_oid = coll_class->getOid();
00436 
00437   offset = IDB_CLASS_HEAD_SIZE + IDB_CLASS_NAME_TOTAL_LEN;
00438 
00439 #ifdef E_XDR
00440   eyedbsm::Oid oid_x;
00441   eyedbsm::h2x_oid(&oid_x, cl_oid.getOid());
00442 #else
00443   eyedbsm::Oid oid_x = *cl_oid.getOid();
00444 #endif
00445   rpc_status = 
00446     dataWrite(db->getDbHandle(), offset, sizeof(eyedbsm::Oid),
00447                   (Data)&oid_x, oid.getOid());
00448   return StatusMake(rpc_status);
00449 }
00450 
00451 Status CollectionClass::trace(FILE* fd, unsigned int flags, const RecMode *rcm) const
00452 {
00453   fprintf(fd, "%s ", oid.getString());
00454   return trace_realize(fd, INDENT_INC, flags, rcm);
00455 }
00456 
00457 Status CollectionClass::trace_realize(FILE* fd, int indent, unsigned int flags, const RecMode *rcm) const
00458 {
00459   char *indent_str = make_indent(indent);
00460 
00461   if (state & Tracing)
00462     {
00463       fprintf(fd, "%s%s;\n", indent_str, oid.getString());
00464       delete_indent(indent_str);
00465       return Success;
00466     }
00467 
00468   Status status = Success;
00469   char *lastindent_str = make_indent(indent - INDENT_INC);
00470 
00471   const_cast<CollectionClass *>(this)->state |= Tracing;
00472 
00473   fprintf(fd, "%s%s", lastindent_str, name);
00474 
00475   const Class *p = getParent();
00476   while (p)
00477     {
00478       fprintf(fd, " : %s", p->getName());
00479       p = p->getParent();
00480     }
00481 
00482   fprintf(fd, " { ");
00483   status = trace_common(fd, indent, flags, rcm);
00484   if (status) goto out;
00485   
00486   if (dim > 1)
00487     fprintf(fd, "%sclass = \"%s[%d]\";\n", indent_str,
00488             coll_class->getName(), dim);
00489   else
00490     fprintf(fd, "%scoll_class = \"%s%s\";\n", indent_str,
00491             coll_class->getName(), (isref ? "*" : ""));
00492 
00493   fprintf(fd, "%s};\n", lastindent_str);
00494 
00495  out:
00496   delete_indent(indent_str);
00497   delete_indent(lastindent_str);
00498   const_cast<CollectionClass *>(this)->state &= ~Tracing;
00499   return status;
00500 }
00501 
00502 Status
00503 CollectionClass::remove(const RecMode*rcm)
00504 {
00505   return Class::remove(rcm);
00506 }
00507 
00508 Class *CollectionClass::getCollClass(Bool *_isref, eyedblib::int16 *_dim,
00509                                      eyedblib::int16 *_item_size)
00510 {
00511   if (_isref)
00512     *_isref = isref;
00513 
00514   if (_dim)
00515     *_dim = dim;
00516 
00517   if (_item_size)
00518     *_item_size = item_size;
00519 
00520   return coll_class;
00521 }
00522 
00523 const Class *
00524 CollectionClass::getCollClass(Bool *_isref, eyedblib::int16 *_dim,
00525                                      eyedblib::int16 *_item_size) const
00526 {
00527   if (_isref)
00528     *_isref = isref;
00529 
00530   if (_dim)
00531     *_dim = dim;
00532 
00533   if (_item_size)
00534     *_item_size = item_size;
00535 
00536   return coll_class;
00537 }
00538 
00539 Status
00540 CollectionClass::make(Database *db, Class **cls)
00541 {
00542   assert(*cls);
00543 
00544   Class *cl;
00545   if (cl = db->getSchema()->getClass((*cls)->getName())) {
00546     *cls = cl;
00547     return Success;
00548   }
00549   
00550   if ((*cls)->isUnrealizable()) {
00551     int type = (*cls)->get_Type();
00552     CollectionClass *mcoll = (CollectionClass *)*cls;
00553     if (mcoll->dim == 1) {
00554       switch(type) {
00555       case _CollSetClass_Type:
00556         *cls = new CollSetClass(mcoll->coll_class, mcoll->isref);
00557         break;
00558 
00559       case _CollBagClass_Type:
00560         *cls = new CollBagClass(mcoll->coll_class, mcoll->isref);
00561         break;
00562 
00563       case _CollArrayClass_Type:
00564         *cls = new CollArrayClass(mcoll->coll_class, mcoll->isref);
00565         break;
00566 
00567       case _CollListClass_Type:
00568         *cls = new CollListClass(mcoll->coll_class, mcoll->isref);
00569         break;
00570 
00571       default:
00572         assert(0);
00573       }
00574     }
00575     else {
00576       switch(type) {
00577       case _CollSetClass_Type:
00578         *cls = new CollSetClass(mcoll->coll_class, mcoll->dim);
00579         break;
00580 
00581       case _CollBagClass_Type:
00582         *cls = new CollBagClass(mcoll->coll_class, mcoll->dim);
00583         break;
00584 
00585       case _CollArrayClass_Type:
00586         *cls = new CollArrayClass(mcoll->coll_class, mcoll->dim);
00587         break;
00588 
00589       case _CollListClass_Type:
00590         *cls = new CollListClass(mcoll->coll_class, mcoll->dim);
00591         break;
00592 
00593       default:
00594         assert(0);
00595       }
00596     }
00597   }
00598 
00599   Status status;
00600   status = (*cls)->setDatabase(db);
00601 
00602   if (status)
00603     return status;
00604 
00605   ClassPeer::setMType(*cls, Class::System);
00606 
00607   status = db->getSchema()->addClass(*cls);
00608   return status;
00609 }
00610 
00611 LinkedList *CollectionClass::mcoll_list;
00612 
00613 void
00614 CollectionClass::init()
00615 {
00616   mcoll_list = new LinkedList();
00617 }
00618 
00619 struct CollClassLink {
00620   char *name;
00621   CollectionClass *coll;
00622 
00623   CollClassLink(const char *_name, CollectionClass *_coll) {
00624     name = strdup(_name);
00625     coll = _coll;
00626   }
00627 
00628   ~CollClassLink() {
00629     free(name);
00630     coll->release();
00631   }
00632 };
00633 
00634 void
00635 CollectionClass::_release()
00636 {
00637   CollClassLink *l;
00638 
00639   LinkedListCursor c(mcoll_list);
00640 
00641   while (mcoll_list->getNextObject(&c, (void *&)l))
00642     delete l;
00643 
00644   delete mcoll_list;
00645 }
00646 
00647 void
00648 CollectionClass::set(const char *prefix, Class *coll_class,
00649                         Bool isref, int dim, CollectionClass *coll)
00650 {
00651   const char *_name = make_name(prefix, coll_class, isref, dim, False);
00652 
00653   ObjectPeer::setUnrealizable(coll, True);
00654   mcoll_list->insertObjectLast(new CollClassLink(_name, coll));
00655   //printf("CollectionClass::set(%s in list)\n", _name);
00656 }
00657 
00658 int
00659 CollectionClass::genODL(FILE *fd, Schema *) const
00660 {
00661   return 0;
00662 }
00663 
00664 CollectionClass *
00665 CollectionClass::get(const char *prefix, Class *coll_class,
00666                         Bool isref, int dim)
00667 {
00668   const char *name = make_name(prefix, coll_class, isref, dim, False);
00669   Status status;
00670 
00671   CollClassLink *l;
00672 
00673   LinkedListCursor c(mcoll_list);
00674   while (c.getNext((void *&)l))
00675     if (!strcmp(l->name, name))
00676       return l->coll;
00677 
00678   //printf("CollectionClass::get(%s) -> NOT FOUND\n", name);
00679   return 0;
00680 }
00681 
00682 //
00683 // bag_class
00684 //
00685 
00686 CollectionClass *
00687 CollBagClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00688 {
00689   status = 0;
00690   CollectionClass *coll;
00691   if (coll = get("bag", coll_class, isref, dim))
00692     return coll;
00693 
00694   if (dim > 1)
00695     coll = new CollBagClass(coll_class, dim);
00696   else
00697     coll = new CollBagClass(coll_class, isref);
00698 
00699   if (coll->getStatus()) {
00700     status = coll->getStatus();
00701     return 0;
00702   }
00703 
00704   set("bag", coll_class, isref, dim, coll);
00705   return coll;
00706 }
00707 
00708 CollBagClass::CollBagClass(Class *_coll_class, Bool _isref) :
00709 CollectionClass(_coll_class, _isref, "bag")
00710 {
00711   type = _CollBagClass_Type;
00712   setClass(CollBagClass_Class);
00713   parent = CollBag_Class;
00714 }
00715 
00716 CollBagClass::CollBagClass(Class *_coll_class, int _dim) :
00717 CollectionClass(_coll_class, _dim, "bag")
00718 {
00719   type = _CollBagClass_Type;
00720   setClass(CollBagClass_Class);
00721   parent = CollBag_Class;
00722 }
00723 
00724 CollBagClass::CollBagClass(const CollBagClass &cl)
00725   : CollectionClass(cl)
00726 {
00727 }
00728 
00729 CollBagClass::CollBagClass(const Oid &_oid, const char *_name) :
00730 CollectionClass(_oid, _name)
00731 {
00732   type = _CollBagClass_Type;
00733 }
00734 
00735 CollBagClass& CollBagClass::operator=(const CollBagClass &cl)
00736 {
00737   this->CollectionClass::operator=(cl);
00738   return *this;
00739 }
00740 
00741 Object *CollBagClass::newObj(Database *_db) const
00742 {
00743   CollBag *t;
00744 
00745   if (isref)  t = new CollBag(_db, "", coll_class, True);
00746   else        t = new CollBag(_db, "", coll_class, dim );
00747 
00748   ObjectPeer::make(t, this, 0, _CollBag_Type, idr_objsz,
00749                       idr_psize, idr_vsize);
00750   return t;
00751 }
00752 
00753 Object *CollBagClass::newObj(Data data, Bool _copy) const
00754 {
00755   CollBag *t;
00756 
00757   if (isref)  t = new CollBag("", coll_class, True);
00758   else        t = new CollBag("", coll_class, dim );
00759 
00760   ObjectPeer::make(t, this, data, _CollBag_Type, idr_objsz,
00761                       idr_psize, idr_vsize, _copy);
00762   return t;
00763 }
00764 
00765 //
00766 // array_class
00767 //
00768 
00769 CollectionClass *
00770 CollArrayClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00771 {
00772   status = 0;
00773   CollectionClass *coll;
00774   if (coll = get("array", coll_class, isref, dim))
00775     return coll;
00776 
00777   if (dim > 1)
00778     coll = new CollArrayClass(coll_class, dim);
00779   else
00780     coll = new CollArrayClass(coll_class, isref);
00781 
00782   if (coll->getStatus()) {
00783     status = coll->getStatus();
00784     return 0;
00785   }
00786 
00787   set("array", coll_class, isref, dim, coll);
00788   return coll;
00789 }
00790 
00791 CollArrayClass::CollArrayClass(Class *_coll_class, Bool _isref) :
00792 CollectionClass(_coll_class, _isref, "array")
00793 {
00794   type = _CollArrayClass_Type;
00795   setClass(CollArrayClass_Class);
00796   parent = CollArray_Class;
00797 }
00798 
00799 CollArrayClass::CollArrayClass(Class *_coll_class, int _dim) :
00800 CollectionClass(_coll_class, _dim, "array")
00801 {
00802   type = _CollArrayClass_Type;
00803   setClass(CollArrayClass_Class);
00804   parent = CollArray_Class;
00805 }
00806 
00807 CollArrayClass::CollArrayClass(const CollArrayClass &cl)
00808   : CollectionClass(cl)
00809 {
00810 }
00811 
00812 CollArrayClass::CollArrayClass(const Oid &_oid, const char *_name) :
00813 CollectionClass(_oid, _name)
00814 {
00815   type = _CollArrayClass_Type;
00816 }
00817 
00818 CollArrayClass& CollArrayClass::operator=(const CollArrayClass &cl)
00819 {
00820   this->CollectionClass::operator=(cl);
00821   return *this;
00822 }
00823 
00824 Object *CollArrayClass::newObj(Database *_db) const
00825 {
00826   CollArray *t;
00827 
00828   if (isref)  t = new CollArray(_db, "", coll_class, True);
00829   else        t = new CollArray(_db, "", coll_class, dim );
00830 
00831   ObjectPeer::make(t, this, 0, _CollArray_Type, idr_objsz,
00832                       idr_psize, idr_vsize);
00833   return t;
00834 }
00835 
00836 Object *CollArrayClass::newObj(Data data, Bool _copy) const
00837 {
00838   CollArray *t;
00839 
00840   if (isref)  t = new CollArray("", coll_class, True);
00841   else        t = new CollArray("", coll_class, dim );
00842 
00843   ObjectPeer::make(t, this, data, _CollArray_Type, idr_objsz,
00844                       idr_psize, idr_vsize, _copy);
00845   return t;
00846 }
00847 
00848 //
00849 // set_class
00850 //
00851 
00852 CollectionClass *
00853 CollSetClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00854 {
00855   status = 0;
00856   CollectionClass *coll;
00857   if (coll = get("set", coll_class, isref, dim))
00858     return coll;
00859 
00860   if (dim > 1)
00861     coll = new CollSetClass(coll_class, dim);
00862   else
00863     coll = new CollSetClass(coll_class, isref);
00864 
00865   if (coll->getStatus()) {
00866     status = coll->getStatus();
00867     return 0;
00868   }
00869 
00870   set("set", coll_class, isref, dim, coll);
00871   return coll;
00872 }
00873 
00874 CollSetClass::CollSetClass(Class *_coll_class, Bool _isref) :
00875 CollectionClass(_coll_class, _isref, "set")
00876 {
00877   type = _CollSetClass_Type;
00878   setClass(CollSetClass_Class);
00879   parent = CollSet_Class;
00880 }
00881 
00882 CollSetClass::CollSetClass(Class *_coll_class, int _dim) :
00883 CollectionClass(_coll_class, _dim, "set")
00884 {
00885   type = _CollSetClass_Type;
00886   setClass(CollSetClass_Class);
00887   parent = CollSet_Class;
00888 }
00889 
00890 CollSetClass::CollSetClass(const CollSetClass &cl)
00891   : CollectionClass(cl)
00892 {
00893 }
00894 
00895 CollSetClass::CollSetClass(const Oid &_oid, const char *_name) :
00896 CollectionClass(_oid, _name)
00897 {
00898   type = _CollSetClass_Type;
00899 }
00900 
00901 CollSetClass& CollSetClass::operator=(const CollSetClass &cl)
00902 {
00903   this->CollectionClass::operator=(cl);
00904   return *this;
00905 }
00906 
00907 Object *CollSetClass::newObj(Database *_db) const
00908 {
00909   CollSet *t;
00910 
00911   if (isref)  t = new CollSet(_db, "", coll_class, True);
00912   else        t = new CollSet(_db, "", coll_class, dim );
00913 
00914   ObjectPeer::make(t, this, 0, _CollSet_Type, idr_objsz,
00915                       idr_psize, idr_vsize);
00916   return t;
00917 }
00918 
00919 Object *CollSetClass::newObj(Data data, Bool _copy) const
00920 {
00921   CollSet *t;
00922 
00923   if (isref)  t = new CollSet("", coll_class, True);
00924   else        t = new CollSet("", coll_class, dim );
00925 
00926   ObjectPeer::make(t, this, data, _CollSet_Type, idr_objsz,
00927                       idr_psize, idr_vsize, _copy);
00928   return t;
00929 }
00930 
00931 //
00932 // list_class
00933 //
00934 
00935 CollectionClass *
00936 CollListClass::make(Class *coll_class, Bool isref, int dim, Status &status)
00937 {
00938   status = 0;
00939   CollectionClass *coll;
00940   if (coll = get("list", coll_class, isref, dim))
00941     return coll;
00942 
00943   if (dim > 1)
00944     coll = new CollListClass(coll_class, dim);
00945   else
00946     coll = new CollListClass(coll_class, isref);
00947 
00948   if (coll->getStatus()) {
00949     status = coll->getStatus();
00950     return 0;
00951   }
00952 
00953   set("list", coll_class, isref, dim, coll);
00954   return coll;
00955 }
00956 
00957 CollListClass::CollListClass(Class *_coll_class, Bool _isref) :
00958 CollectionClass(_coll_class, _isref, "list")
00959 {
00960   type = _CollListClass_Type;
00961   setClass(CollListClass_Class);
00962   parent = CollList_Class;
00963 }
00964 
00965 CollListClass::CollListClass(Class *_coll_class, int _dim) :
00966 CollectionClass(_coll_class, _dim, "list")
00967 {
00968   type = _CollListClass_Type;
00969   setClass(CollListClass_Class);
00970   parent = CollList_Class;
00971 }
00972 
00973 CollListClass::CollListClass(const CollListClass &cl)
00974   : CollectionClass(cl)
00975 {
00976 }
00977 
00978 CollListClass::CollListClass(const Oid &_oid, const char *_name) :
00979 CollectionClass(_oid, _name)
00980 {
00981   type = _CollListClass_Type;
00982 }
00983 
00984 CollListClass& CollListClass::operator=(const CollListClass &cl)
00985 {
00986   this->CollectionClass::operator=(cl);
00987   return *this;
00988 }
00989 
00990 Object *CollListClass::newObj(Database *_db) const
00991 {
00992   CollList *t;
00993 
00994   if (isref)  t = new CollList(_db, "", coll_class, True);
00995   else        t = new CollList(_db, "", coll_class, dim );
00996 
00997   ObjectPeer::make(t, this, 0, _CollList_Type, idr_objsz,
00998                       idr_psize, idr_vsize);
00999   return t;
01000 }
01001 
01002 Object *CollListClass::newObj(Data data, Bool _copy) const
01003 {
01004   CollList *t;
01005 
01006   if (isref)  t = new CollList("", coll_class, True);
01007   else        t = new CollList("", coll_class, dim );
01008 
01009   ObjectPeer::make(t, this, data, _CollList_Type, idr_objsz,
01010                       idr_psize, idr_vsize, _copy);
01011   return t;
01012 }
01013 
01014 Status
01015 CollectionClass::setName(const char *s)
01016 {
01017   return setNameRealize(s);
01018 }
01019 
01020 //
01021 // make function
01022 //
01023 
01024 Status
01025 collectionClassMake(Database *db, const Oid *oid, Object **o,
01026                     const RecMode *rcm, const ObjectHeader *hdr,
01027                     Data idr, LockMode lockmode, const Class*)
01028 {
01029   RPCStatus rpc_status;
01030   Status status;
01031   Data temp;
01032 
01033   if (!idr)
01034     {
01035       temp = (unsigned char *)malloc(hdr->size);
01036       object_header_code_head(temp, hdr);
01037 
01038       rpc_status = objectRead(db->getDbHandle(), temp, 0, 0, oid->getOid(),
01039                                   0, lockmode, 0);
01040     }
01041   else
01042     {
01043       temp = idr;
01044       rpc_status = RPCSuccess;
01045     }
01046 
01047   if (rpc_status != RPCSuccess)
01048     return StatusMake(rpc_status);
01049 
01050   if (hdr && (hdr->xinfo & IDB_XINFO_REMOVED))
01051     return Exception::make(IDB_INTERNAL_ERROR,
01052                            "collection class %s is removed", oid->toString());
01053 
01054   char *s;
01055   Offset offset;
01056 
01057   /*
01058   eyedblib::int32 mag_order;
01059   offset = IDB_CLASS_MAG_ORDER;
01060   int32_decode (temp, &offset, &mag_order);
01061   */
01062 
01063   IndexImpl *idximpl;
01064   offset = IDB_CLASS_IMPL_TYPE;
01065   status = IndexImpl::decode(db, temp, offset, idximpl);
01066   if (status) return status;
01067 
01068   eyedblib::int32 mt;
01069   offset = IDB_CLASS_MTYPE;
01070   int32_decode (temp, &offset, &mt);
01071 
01072   eyedblib::int16 dspid;
01073   offset = IDB_CLASS_DSPID;
01074   int16_decode (temp, &offset, &dspid);
01075 
01076   offset = IDB_CLASS_HEAD_SIZE;
01077 
01078   status = class_name_decode(db->getDbHandle(), temp, &offset, &s);
01079   if (status) return status;
01080 
01081   CollectionClass *mcoll;
01082 
01083   eyedbsm::Oid _cl_oid;
01084   oid_decode(temp, &offset, &_cl_oid);
01085   Oid cl_oid(_cl_oid);
01086 
01087   Class *coll_class;
01088 
01089   coll_class = db->getSchema()->getClass(cl_oid, True);
01090 
01091   if (!coll_class)
01092     coll_class = Object_Class;
01093 
01094   char isref;
01095   char_decode(temp, &offset, &isref);
01096   eyedblib::int16 dim;
01097   int16_decode(temp, &offset, &dim);
01098 
01099   switch(hdr->type)
01100     {
01101     case _CollSetClass_Type:
01102       if (dim > 1)
01103         mcoll = new CollSetClass(coll_class, (int)dim);
01104       else
01105         mcoll = new CollSetClass(coll_class, (Bool)isref);
01106       break;
01107 
01108     case _CollBagClass_Type:
01109       if (dim > 1)
01110         mcoll = new CollBagClass(coll_class, (int)dim);
01111       else
01112         mcoll = new CollBagClass(coll_class, (Bool)isref);
01113       break;
01114 
01115     case _CollArrayClass_Type:
01116       if (dim > 1)
01117         mcoll = new CollArrayClass(coll_class, (int)dim);
01118       else
01119         mcoll = new CollArrayClass(coll_class, (Bool)isref);
01120       break;
01121 
01122     case _CollListClass_Type:
01123       if (dim > 1)
01124         mcoll = new CollListClass(coll_class, (int)dim);
01125       else
01126         mcoll = new CollListClass(coll_class, (Bool)isref);
01127       break;
01128 
01129     default:
01130       abort();
01131     }
01132 
01133   mcoll->setExtentImplementation(idximpl, True);
01134   if (idximpl)
01135     idximpl->release();
01136   //mcoll->setMagOrder(mag_order);
01137   mcoll->setInstanceDspid(dspid);
01138 
01139   Bool addedClass = False;
01140   if (!db->getSchema()->getClass(*oid))
01141     {
01142       ObjectPeer::setOid(mcoll, *oid);
01143       db->getSchema()->addClass_nocheck(mcoll, True);
01144       addedClass = True;
01145     }
01146 
01147   Class *cl = NULL;
01148   Bool classAdded = False;
01149   if (!db->isOpeningState() && !db->isBackEnd())
01150     {
01151       status = mcoll->setDatabase(db);
01152       if (status)
01153         return status;
01154     }
01155   else
01156     {
01157       /* changes about the 18/10/97 */
01158       /* THIS MAKE A BIG BORDEL! */
01159       Exception::Mode mode = Exception::setMode(Exception::StatusMode);
01160       void (*handler)(Status, void *) = Exception::getHandler();
01161       Exception::setHandler(NULL);
01162 
01163       Exception::setHandler(handler);
01164       Exception::setMode(mode);
01165     }
01166 
01167   status = ClassPeer::makeColls(db, mcoll, temp);
01168 
01169   if (addedClass)
01170     db->getSchema()->suppressClass(mcoll);
01171 
01172   *o = (Object *)mcoll;
01173 
01174   if (!idr)
01175     {
01176       if (!status)
01177         ObjectPeer::setIDR(*o, temp, hdr->size);
01178     }
01179 
01180   free(s); s = 0;
01181   return status;
01182 }
01183 
01184 #include "CollectionBE.h"
01185 
01186 Status classCollectionMake(Database *db, const Oid &colloid,
01187                                       Collection **coll)
01188 {
01189   if (!colloid.isValid())
01190     {
01191       *coll = 0;
01192       return Success;
01193     }
01194 
01195   ObjectHeader hdr;
01196 
01197   RPCStatus rpc_status;
01198 
01199   rpc_status = objectHeaderRead(db->getDbHandle(), colloid.getOid(), &hdr);
01200 
01201   if (rpc_status != RPCSuccess)
01202     return StatusMake(rpc_status);
01203 
01204   return collectionMake(db, &colloid, (Object **)coll, 0, &hdr, 0, 
01205                             DefaultLock, 0);
01206 }
01207 }

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