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 "IteratorBE.h"
00027 #include "CollectionBE.h"
00028 #include <iostream>
00029
00030 namespace eyedb {
00031
00032
00033
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
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
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
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
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
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
00272
00273
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