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 "Attribute_p.h"
00027 #include <assert.h>
00028
00029 #define ATTR_COMPLETE(DB, X) \
00030 if (!(X)->cls) \
00031 const_cast<Attribute *>(X)->cls = \
00032 (DB)->getSchema()->getClass((X)->oid_cl); \
00033 if (!(X)->class_owner) \
00034 const_cast<Attribute *>(X)->class_owner = \
00035 (DB)->getSchema()->getClass((X)->oid_cl_own)
00036
00037 namespace eyedb {
00038
00039 static const char fmt_error[] = "storage manager error '%s' reported when creating index in attribute '%s' in agregat class '%s'";
00040
00041 static Status
00042 literalCollUpdate(Database *db, Object *o, Attribute *attr,
00043 Index *idx, int from, const Oid &oid)
00044 {
00045 Status s;
00046 eyedbsm::Status se_s;
00047 Collection *coll = 0;
00048 Bool isnull;
00049 eyedbsm::Idx *se_idx = idx->idx;
00050
00051 if (!o) {
00052 s = db->loadObject(oid, o);
00053 if (s) return s;
00054 }
00055 if (s = attr->getValue
00056 (o, (Data *)&coll, 1, from, &isnull))
00057 return s;
00058
00059 Iterator iter(coll);
00060 for (;;)
00061 {
00062 Bool found;
00063 Oid elem_oid;
00064 s = iter.scanNext(found, elem_oid);
00065 if (s) return s;
00066
00067 if (!found)
00068 break;
00069
00070 IDB_LOG(IDB_LOG_IDX_INSERT,
00071 (Attribute::log_item_entry_fmt,
00072 idx->getAttrpath().c_str(),
00073 oid.toString(), attr->dumpData((Data)&elem_oid), from,
00074 (isnull ? "null data" : "not null data")));
00075
00076 if (se_s = se_idx->insert(&elem_oid, &oid))
00077 return Exception::make(IDB_INDEX_ERROR, fmt_error,
00078 eyedbsm::statusGet(se_s),
00079 attr->getName(),
00080 attr->getClassOwner()->getName());
00081 }
00082
00083 return Success;
00084 }
00085
00086 Status
00087 Attribute::createEntries(Database *db, const Oid &oid,
00088 Object *o,
00089 AttrIdxContext &idx_ctx,
00090 Attribute *attrs[],
00091 int depth, int last,
00092 unsigned char entry[],
00093 Index *idx)
00094 {
00095 Status s;
00096 Attribute *attr = attrs[depth];
00097 assert(attr);
00098 Size sz = 0;
00099
00100 if (depth != last) {
00101 Bool was_null;
00102 if (!o) {
00103 s = db->loadObject(oid, o);
00104 if (s) return s;
00105 was_null = True;
00106 }
00107 else
00108 was_null = False;
00109
00110 if (attr->isVarDim()) {
00111 s = attr->getSize(o, sz);
00112 if (s) return s;
00113 }
00114 else
00115 sz = attr->getTypeModifier().pdims;
00116
00117 for (int from = 0; from < sz; from++) {
00118 Object *x = 0;
00119 if (s = attr->getValue(o, (Data *)&x, 1, from, 0)) {
00120 if (was_null) o->release();
00121 return s;
00122 }
00123
00124 if (s = createEntries(db, oid, x, idx_ctx, attrs,
00125 depth+1, last, entry, idx)) {
00126 if (was_null) o->release();
00127 return s;
00128 }
00129 }
00130
00131 if (was_null)
00132 o->release();
00133
00134 return Success;
00135 }
00136
00137 return createEntries_realize(db, attr, oid, o, idx_ctx, entry, idx);
00138 }
00139
00140 Status
00141 Attribute::createEntries_realize(Database *db,
00142 Attribute *attr,
00143 const Oid &oid,
00144 Object *o,
00145 AttrIdxContext &idx_ctx,
00146 unsigned char entry[],
00147 Index *idx)
00148 {
00149 Status s;
00150 Bool isnull;
00151 eyedbsm::Status se_s;
00152 Size sz;
00153 eyedbsm::Idx *se_idx = idx->idx;
00154 assert(se_idx);
00155
00156 if (!attr->isVarDim())
00157 sz = attr->getTypeModifier().pdims;
00158
00159 if (attr->isString()) {
00160 if (o) {
00161
00162 if (attr->isVarDim()) {
00163 s = attr->getSize(o, sz);
00164 if (s) return s;
00165 entry = !sz ? new unsigned char[2] : new unsigned char[sz+1];
00166 }
00167
00168
00169
00170
00171
00172
00173 if (s = attr->getValue(o, (Data *)&entry[1], sz, 0, &isnull)) {
00174 if (attr->isVarDim())
00175 delete [] entry;
00176 return s;
00177 }
00178 }
00179 else {
00180
00181 int nb;
00182 unsigned char *data = 0;
00183 if (attr->isVarDim()) {
00184 nb = Attribute::wholeData;
00185 s = attr->getTValue(db, oid, &data, nb, 0, &isnull, &sz);
00186 } else {
00187 nb = attr->getTypeModifier().pdims;
00188 s = attr->getTValue(db, oid, (Data *)&entry[1], nb, 0,
00189 &isnull, &sz);
00190 }
00191
00192 if (s) return s;
00193
00194 if (attr->isVarDim()) {
00195 if (sz) {
00196 entry = new unsigned char[sz+1];
00197 memcpy(&entry[1], data, sz);
00198 delete [] data;
00199 } else {
00200 entry = new unsigned char[2];
00201 entry[1] = 0;
00202 }
00203 }
00204 }
00205
00206 IDB_LOG(IDB_LOG_IDX_INSERT,
00207 (Attribute::log_comp_entry_fmt,
00208 idx->getAttrpath().c_str(),
00209 oid.toString(), &entry[1],
00210 (isnull ? "null data" : "not null data")));
00211
00212 entry[0] = (isnull ? idxNull : idxNotNull);
00213
00214 se_s = se_idx->insert(entry, &oid);
00215
00216 if (attr->isVarDim())
00217 delete[] entry;
00218
00219 if (se_s)
00220 return Exception::make(IDB_INDEX_ERROR, fmt_error,
00221 eyedbsm::statusGet(se_s),
00222 attr->name, attr->class_owner->getName());
00223 return Success;
00224 }
00225
00226
00227
00228 if (!attr->isString()) {
00229 if (attr->getClass()->asCollectionClass()) {
00230 for (int from = 0; from < sz; from++) {
00231 s = literalCollUpdate(db, o, attr, idx, from, oid);
00232 if (s) return s;
00233 }
00234 }
00235 else {
00236 for (int from = 0; from < sz; from++) {
00237 if (o) {
00238
00239 s = attr->getValue
00240 (o, (Data *)&entry[sizeof(char)+sizeof(eyedblib::int32)],
00241 1, from, &isnull);
00242 if (s) return s;
00243 } else {
00244 unsigned int dummy;
00245 s = attr->getTValue(db, oid,
00246 (Data *)&entry[sizeof(char)+sizeof(eyedblib::int32)],
00247 1, from, &isnull, &dummy);
00248
00249 if (s) return s;
00250 }
00251
00252 entry[0] = (isnull ? idxNull : idxNotNull);
00253 memcpy(&entry[1], &from, sizeof(eyedblib::int32));
00254
00255 IDB_LOG(IDB_LOG_IDX_INSERT,
00256 (Attribute::log_item_entry_fmt,
00257 idx->getAttrpath().c_str(),
00258 oid.toString(), attr->dumpData(&entry[5]), from,
00259 (isnull ? "null data" : "not null data")));
00260
00261 if (se_s = se_idx->insert(entry, &oid))
00262 return Exception::make(IDB_INDEX_ERROR, fmt_error,
00263 eyedbsm::statusGet(se_s),
00264 attr->name, attr->class_owner->getName());
00265 }
00266 }
00267 }
00268
00269 return Success;
00270 }
00271
00272 Status
00273 Attribute::updateIndexEntries(Database *db, AttrIdxContext &idx_ctx)
00274 {
00275 Status s;
00276 ClassSeqItem *classSeqItem;
00277
00278 Class *cl = db->getSchema()->getClass(idx_ctx.getClassOwner());
00279
00280 assert(cl);
00281 Attribute **attrs = new Attribute*[idx_ctx.getAttrCount()];
00282 Class *tcl = cl;
00283 for (int i = 0; i < idx_ctx.getAttrCount(); i++) {
00284 attrs[i] = (Attribute *)tcl->getAttribute(idx_ctx.getAttrName(i));
00285 tcl = (Class *)attrs[i]->getClass();
00286 }
00287
00288 Attribute *attr = attrs[idx_ctx.getAttrCount()-1];
00289
00290 Index *idx;
00291 s = attr->indexPrologue(db, idx_ctx, idx, True);
00292 if (s) return s;
00293 assert(idx);
00294
00295 unsigned char *entry;
00296
00297 if (attr->isString()) {
00298 if (attr->isVarDim())
00299 entry = 0;
00300 else
00301 entry = new unsigned char[1 + attr->getTypeModifier().pdims];
00302 }
00303 else {
00304 Offset dummy_off;
00305 Size idr_item_psize, dummy_size;
00306 attr->getPersistentIDR(dummy_off, idr_item_psize, dummy_size, dummy_size);
00307
00308 entry = new unsigned char[sizeof(char) + sizeof(eyedblib::int32) +
00309 idr_item_psize];
00310
00311 }
00312
00313 Iterator q(cl, False);
00314
00315 for (;;) {
00316 Oid oid;
00317 Bool found;
00318
00319 if (s = q.scanNext(found, oid)) {
00320 delete [] entry;
00321 delete [] attrs;
00322 return s;
00323 }
00324
00325 if (!found)
00326 break;
00327
00328 s = createEntries(db, oid, 0, idx_ctx,
00329 attrs, 0, idx_ctx.getAttrCount()-1, entry, idx);
00330
00331 if (s) {
00332 delete [] entry;
00333 delete [] attrs;
00334 return s;
00335 }
00336
00337
00338 }
00339
00340 delete [] entry;
00341 delete [] attrs;
00342 return Success;
00343 }
00344 }