Enum.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 "IteratorBE.h"
00027 #include "CollectionBE.h"
00028 #include <iostream>
00029 
00030 namespace eyedb {
00031 
00032   //
00033   // Enum methods
00034   //
00035 
00036   Enum::Enum(Database *_db, const Dataspace *_dataspace) :
00037     Instance(_db, _dataspace)
00038   {
00039     val = NULL;
00040   }
00041 
00042   Enum::Enum(const Enum &o) : Instance(o)
00043   {
00044     val = o.val;
00045   }
00046 
00047   Enum& Enum::operator=(const Enum &o)
00048   {
00049     if (&o == this)
00050       return *this;
00051 
00052     //garbageRealize();
00053 
00054     *(Instance *)this = Instance::operator=((const Instance &)o);
00055 
00056     val = o.val;
00057 
00058     return *this;
00059   }
00060 
00061   Status Enum::setValue(Data data)
00062   {
00063     int i;
00064     memcpy(&i, data, sizeof(eyedblib::int32));
00065     val = ((EnumClass *)getClass())->getEnumItemFromVal(i);
00066     printf("Enum::setValue(%d)\n", i);
00067     return Success;
00068   }
00069 
00070   Status Enum::getValue(Data *data) const
00071   {
00072     printf("Enum::getValue(%p)\n", val);
00073     if (val) {
00074       int i = val->getValue();
00075       memcpy(data, &i, sizeof(eyedblib::int32));
00076     }
00077     return Success;
00078   }
00079 
00080   Status Enum::setValue(unsigned int v)
00081   {
00082     const EnumItem *item;
00083     if ((item = ((EnumClass *)getClass())->getEnumItemFromVal(v)))
00084       {
00085         val = item;
00086         return Success;
00087       }
00088 
00089     return Exception::make(IDB_ENUM_ERROR, "invalid value `%d' for enum '%s'", v,
00090                            getClass()->getName());
00091   }
00092 
00093   Status Enum::getValue(unsigned int *v) const
00094   {
00095     if (val)
00096       {
00097         *v = val->value;
00098         return Success;
00099       }
00100 
00101     *v = 0;
00102     return Success;
00103     //  return Exception::make(IDB_ENUM_ERROR, "enum not initialized");
00104   }
00105 
00106   Status Enum::setValue(const char *name)
00107   {
00108     const EnumItem *item;
00109     if ((item = ((EnumClass *)getClass())->getEnumItemFromName(name)))
00110       {
00111         val = item;
00112         return Success;
00113       }
00114 
00115     return Exception::make(IDB_ENUM_ERROR, "invalid value '%s' for enum '%s'",
00116                            name, getClass()->getName());
00117   }
00118 
00119   Status Enum::getValue(const char **s) const
00120   {
00121     if (val)
00122       {
00123         *s = val->name;
00124         return Success;
00125       }
00126 
00127     *s = 0;
00128     return Success;
00129     //  return Exception::make(IDB_ERROR, "enum not initialized");
00130   }
00131 
00132   Status Enum::setValue(const EnumItem *it)
00133   {
00134     val = it;
00135     return Success;
00136   }
00137 
00138   Status Enum::getValue(const EnumItem **pit) const
00139   {
00140     if (val)
00141       {
00142         *pit = val;
00143         return Success;
00144       }
00145 
00146     *pit = 0;
00147     return Success;
00148     //  return Exception::make(IDB_ERROR, "enum not initialized");
00149   }
00150 
00151   Status Enum::create()
00152   {
00153     if (!getClass())
00154       return Exception::make(IDB_NO_CLASS);
00155 
00156     IDB_CHECK_WRITE(db);
00157     if (oid.isValid())
00158       return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating enum of class '%s'", getClass()->getName());
00159 
00160     if (!getClass()->getOid().isValid())
00161       return Exception::make(IDB_CLASS_NOT_CREATED, "creating enum of class '%s'", getClass()->getName());
00162 
00163     Offset offset = IDB_OBJ_HEAD_SIZE;
00164     Size alloc_size = idr->getSize();
00165     Data data = idr->getIDR();
00166 
00167     char k;
00168 
00169     if (val)
00170       {
00171         k = 1;
00172         char_code(&data, &offset, &alloc_size, &k);
00173         int32_code(&data, &offset, &alloc_size, &val->num);
00174       }
00175     else
00176       {
00177         k = 0;
00178         char_code(&data, &offset, &alloc_size, &k);
00179       }
00180 
00181     classOidCode();
00182 
00183     RPCStatus rpc_status;
00184     rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(), data, oid.getOid());
00185 
00186     return StatusMake(rpc_status);
00187   }
00188 
00189   Status Enum::update()
00190   {
00191     return Success;
00192   }
00193 
00194   Status Enum::remove(const RecMode*)
00195   {
00196     return Success;
00197   }
00198 
00199   Status Enum::trace(FILE *fd, unsigned int flags, const RecMode *rcm) const
00200   {
00201     char *indent_str = make_indent(INDENT_INC);
00202     EnumItem *item;
00203     int n;
00204 
00205     fprintf(fd, "%s %s = { ", oid.getString(), getClass()->getName(), val);
00206     trace_flags(fd, flags);
00207     fprintf(fd, "\n");
00208 
00209     if (traceRemoved(fd, indent_str))
00210       goto out;
00211 
00212     if (val)
00213       fprintf(fd, "%s%s <%d>;\n", indent_str, val->name, val->value);
00214     else
00215       fprintf(fd, "%s<uninitialized>;\n", indent_str);
00216     fprintf(fd, "};\n");
00217 
00218   out:
00219     delete_indent(indent_str);
00220     return Success;
00221   }
00222 
00223   Status Enum::trace_realize(FILE*, int, unsigned int flags, const RecMode *rcm) const
00224   {
00225     return Success;
00226   }
00227 
00228   void Enum::garbage()
00229   {
00230   }
00231 
00232   Enum::~Enum()
00233   {
00234     garbageRealize();
00235   }
00236 
00237   //
00238   // functions
00239   // 
00240 
00241   Status
00242   enumClassMake(Database *db, const Oid *oid, Object **o,
00243                     const RecMode *rcm, const ObjectHeader *hdr,
00244                     Data idr, LockMode lockmode, const Class*)
00245   {
00246     RPCStatus rpc_status;
00247     Data temp;
00248 
00249     if (!idr)
00250       {
00251         temp = (unsigned char *)malloc(hdr->size);
00252         object_header_code_head(temp, hdr);
00253       
00254         rpc_status = objectRead(db->getDbHandle(), temp, 0, 0, oid->getOid(),
00255                                     0, lockmode, 0);
00256       }
00257     else
00258       {
00259         temp = idr;
00260         rpc_status = RPCSuccess;
00261       }
00262 
00263     if (rpc_status == RPCSuccess)
00264       {
00265         eyedblib::int32 cnt;
00266         char *s;
00267         EnumClass *me;
00268         Offset offset;
00269 
00270         /*
00271           eyedblib::int32 mag_order;
00272           offset = IDB_CLASS_MAG_ORDER;
00273           int32_decode (temp, &offset, &mag_order);
00274         */
00275         IndexImpl *idximpl;
00276         offset = IDB_CLASS_IMPL_TYPE;
00277         Status status = IndexImpl::decode(db, temp, offset, idximpl);
00278         if (status) return status;
00279 
00280         eyedblib::int32 mt;
00281         offset = IDB_CLASS_MTYPE;
00282         int32_decode (temp, &offset, &mt);
00283 
00284         eyedblib::int16 dspid;
00285         offset = IDB_CLASS_DSPID;
00286         int16_decode (temp, &offset, &dspid);
00287 
00288         offset = IDB_CLASS_HEAD_SIZE;
00289 
00290         status = class_name_decode(db->getDbHandle(), temp, &offset, &s);
00291         if (status) return status;
00292 #if 0
00293         if (Class::isBoolClass(s) && db->getSchema()) {
00294           printf("BOOL LOADING\n");
00295           if (!idr)
00296             free(temp);
00297           me = (EnumClass *)db->getSchema()->getClass(s);
00298           *o = (Object *)me;
00299           me->setMagOrder(mag_order);
00300           me->setExtentImplementation(idximpl, True);
00301           if (idximpl)
00302             idximpl->release();
00303           me->setInstanceDspid(dspid);
00304 
00305           ClassPeer::setMType(me, (Class::MType)mt);
00306           return RPCSuccess;
00307         }
00308 #endif
00309         int32_decode(temp, &offset, &cnt);
00310 
00311         me = new EnumClass(s);
00312 
00313         free(s); s = 0;
00314         me->items = (EnumItem **)malloc(sizeof(EnumItem *) * cnt);
00315         me->items_cnt = cnt;
00316 
00317         me->setExtentImplementation(idximpl, True);
00318         if (idximpl)
00319           idximpl->release();
00320         me->setInstanceDspid(dspid);
00321 
00322         ClassPeer::setMType(me, (Class::MType)mt);
00323 
00324         for (int i = 0; i < cnt; i++)
00325           {
00326             eyedblib::int32 val;
00327             string_decode(temp, &offset, &s);
00328             int32_decode(temp, &offset, &val);
00329             me->items[i] = new EnumItem(s, val, i);
00330           }
00331 
00332         *o = (Object *)me;
00333 
00334         status = ClassPeer::makeColls(db, (Class *)*o, temp);
00335 
00336         if (status)
00337           {
00338             if (!idr)
00339               free(temp);
00340             return status;
00341           }
00342       }
00343 
00344     if (!idr)
00345       {
00346         if (!rpc_status)
00347           ObjectPeer::setIDR(*o, temp, hdr->size);
00348       }
00349     return StatusMake(rpc_status);
00350   }
00351 
00352   Status
00353   enumMake(Database *db, const Oid *oid, Object **o,
00354                const RecMode *rcm, const ObjectHeader *hdr, Data idr,
00355                LockMode lockmode, const Class *_class)
00356   {
00357     RPCStatus rpc_status;
00358 
00359     if (!_class)
00360       _class = db->getSchema()->getClass(hdr->oid_cl, True);
00361 
00362     if (!_class)
00363       return Exception::make(IDB_CLASS_NOT_FOUND, "enum class '%s'",
00364                              OidGetString(&hdr->oid_cl));
00365 
00366     Enum *e;
00367 
00368     if (idr && !ObjectPeer::isRemoved(*hdr))
00369       *o = _class->newObj(idr + IDB_OBJ_HEAD_SIZE, False);
00370     else
00371       *o = _class->newObj();
00372 
00373     e = (Enum *)*o;
00374     Status status = e->setDatabase(db);
00375     if (status)
00376       return status;
00377 
00378     if (idr)
00379       rpc_status = RPCSuccess;
00380     else
00381       rpc_status = objectRead(db->getDbHandle(), e->getIDR(), 0, 0,
00382                                   oid->getOid(), 0, lockmode, 0);
00383 
00384     if (rpc_status == RPCSuccess)
00385       {
00386         char k;
00387         Offset offset = IDB_OBJ_HEAD_SIZE;
00388         Data idr = e->getIDR();
00389         char_decode(idr, &offset, &k);
00390         if (k)
00391           {
00392             eyedblib::int32 k;
00393             int32_decode(idr, &offset, &k);
00394             int cnt;
00395             e->setValue(((EnumClass *)_class)->getEnumItems(cnt)[k]);
00396           }
00397       }
00398 
00399     return StatusMake(rpc_status);
00400   }
00401 }
00402 
00403 
00404   

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