Attribute_idx.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 "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       //printf("STRING VIA A LITERAL!\n");
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       if (!sz) {
00170         entry[1] = 0;
00171         isnull = True;
00172       }
00173       else*/ 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       //printf("STRING DIRECT\n");
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   //assert(!attr->isIndirect());
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           //printf("NON STRING VIA A LITERAL\n");
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           //printf("NON STRING DIRECT sz=%d\n", sz);
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   //printf("class_owner = '%s'\n", idx_ctx.getClassOwner());
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     //printf("allocating entry %d\n", idr_item_psize);
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     //o->release();
00338   }
00339 
00340   delete [] entry;
00341   delete [] attrs;
00342   return Success;
00343 }
00344 }

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