Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

vdbl_vtable.h

Go to the documentation of this file.
00001 // View table implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003 Hermann Schichl
00004 //
00005 // This file is part of the Vienna Database Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the Library GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // Library GNU General Public License for more details.
00015 
00016 // As a special exception, you may use this file as part of a free software
00017 // library without restriction.  Specifically, if other files instantiate
00018 // templates or use macros or inline functions from this file, or you compile
00019 // this file and link it with other files to produce an executable, this
00020 // file does not by itself cause the resulting executable to be covered by
00021 // the Library GNU General Public License.  This exception does not however
00022 // invalidate any other reasons why the executable file might be covered by
00023 // the Library GNU General Public License.
00024 
00030 #ifndef __VDBL_VTABLE_H
00031 #define __VDBL_VTABLE_H
00032 
00033 #include <vdbl_table.h>
00034 #include <vdbl_view.h>
00035 
00036 __VDBL_BEGIN_NAMESPACE
00037 
00038 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00039 #pragma set woff 1209
00040 #endif
00041 
00046 class _VDBL_viewtable : public _VDBL_table
00047 {
00048 private:
00049   typedef _VDBL_table _Base;
00050 
00051   typedef std::pair<_VDBL_colflags,_VDBL_col> _T_col_entry;
00052   typedef std::map<std::string, _VDBL_colid> _T_cols;
00053   typedef std::map<_VDBL_colid, _T_col_entry> _T_defaults;
00054   typedef std::map<_VDBL_colid,__VDBL_index> _T_indices;
00055   typedef std::map<_VDBL_rowid,_VDBL_row> _T_rows;
00056   typedef std::map<_VDBL_rowid,std::map<_VDBL_tableid,_VDBL_rowid> > _T_rowref;
00057   typedef std::map<_VDBL_colid,std::pair<_VDBL_colid,_VDBL_tableid> > _T_colref;
00058 
00059   friend class _VDBL_view;
00060 
00061 public:
00062   typedef std::pair<std::string,_VDBL_col> _T_colspec;
00063 
00064 private:
00065   _VDBL_view* _T_v;
00066   unsigned int _T_v_lastchg;
00067 
00068   _T_indices _T_i;
00069   _T_rows _T_r;
00070 
00071   _T_colref _T_cr;
00072   _T_rowref _T_rr;
00073 
00074   _T_rows _T_rowcache;
00075 
00076 private:
00077   const std::type_info& get_colinfo(const std::string& _C_n,
00078                              triple<bool,_VDBL_colid,_VDBL_colflags>& _r) const
00079   {
00080     const _VDBL_col* _x;
00081     return _T_v->get_colinfo(_C_n, _r);
00082   }
00083   
00084 public:
00085   _VDBL_viewtable(_VDBL_view& _v) : _Base(), _T_v(&_v), _T_i(), _T_r(), _T_cr(),
00086                                     _T_rr(), _T_rowcache()
00087      {
00088        for(_VDBL_view::row_const_iterator __x = _T_v->rows_begin();
00089            __x != _T_v->rows_end(); ++__x)
00090          _T_rr.insert(get_rowid(), *__x);
00091        for(_VDBL_view::default_const_iterator __x = _T_v->defaults_begin();
00092            __x != _T_v->defaults_end(); ++__x)
00093          _T_cr.insert(get_colid(), *__x);
00094        _T_v_lastchg = _T_v->get_change_ctr();
00095      }
00096 
00097   _VDBL_viewtable(const _VDBL_viewtable& __t) : _Base(__t), _T_v(__t._T_v),
00098                                         _T_v_lastchg(__t._T_v_lastchg),
00099                                         _T_i(__t._T_i), _T_r(__t._T_r),
00100                                         _T_cr(__t._T_cr), _T_rr(__t._T_rr)
00101                                         _T_rowcache() {}
00102 
00103   virtual ~_VDBL_viewtable() {}
00104 
00105   bool add_col(const std::string& _C_n, const _VDBL_col& __c,
00106                const _VDBL_colflags& __f)
00107   {
00108     return false;
00109   }
00110 
00111   bool modify_col(const std::string& _C_n, const _VDBL_col& __c,
00112                   const _VDBL_colflags& __f)
00113   {
00114     return false;
00115   }
00116 
00117   bool modify_col(const std::string& _C_n, const _VDBL_col& __c)
00118   {
00119     return false;
00120   }
00121 
00122   bool modify_col(const std::string& _C_n, const _VDBL_colflags& __f)
00123   {
00124     return false;
00125   }
00126 
00127   bool drop_col(const std::string& _C_n)
00128   {
00129     return false;
00130   }
00131 
00132   bool rename_col(const std::string& _C_old, const std::string& _C_new)
00133   {
00134     return false;      // old column name does not exist
00135   }
00136 
00137   bool insert(const std::vector<_T_colspec>& _row)
00138   {
00139     if(_T_v->view_type() == _VDBL_V_window)
00140     {
00141       bool ret = _T_v->insert(_row);
00142       if(ret)
00143         made_change();
00144       return ret;
00145     }
00146     else if(_T_v->view_type() == _VDBL_V_materialized) 
00147       return false;
00148     else 
00149     {
00150       std::vector<_T_colspec>::const_iterator __x;
00151       bool ret = true;
00152       _VDBL_row _r;
00153       std::set<_VDBL_colid> _isdef;
00154 
00155       for(__x = _row.begin(); __x != _row.end(); ++__x)
00156       {
00157         _T_colspec& _c(*__x);
00158         triple<bool, _VDBL_colid, _VDBL_colflags> _ru;
00159         const std::type_info& _rt(get_colinfo(_c.first, _ru));
00160         if(_isdef.find(_ru.second) != _isdef.end())
00161         { // column is doubly defined
00162           ret = false;
00163           break;
00164         }
00165         if(!_ru.first || !VDBL_CMP_TYPEID(_rt, _c.second.return_type_id()))
00166         { // value of the default col and the defined col are incompatible
00167           ret = false;
00168           break;
00169         }
00170         else
00171         {
00172           if(_ru.third.is_master)
00173           {
00174 #if _VDBL_DEBUG
00175             std::cout <<
00176                   "We should check the constraints here in table::insert" <<
00177                   std::endl;
00178 #endif
00179           }
00180           _isdef.insert(_ru.second);
00181           _r.insert(_ru.second,_c.second);
00182         }
00183       }
00184       // now check whether all columns without default are actually defined
00185       if(ret)
00186       {
00187         for(_VDBL_view::defaults_const_iterator __b = _T_v->defaults_begin();
00188             __b != _T_v->defaults_end(); ++__b)
00189         {
00190           const _T_col_entry& __de((*__b).second);
00191           if(!__de.first.has_default &&
00192              _isdef.find((*__b).first) == _isdef.end())
00193           // this col must be defined but isn't
00194           {
00195             ret = false;
00196             break;
00197           }
00198         }
00199       }
00200       if(ret)
00201       {
00202         _T_r.insert(std::make_pair(get_rowid(), _r));
00203         made_change();
00204       }
00205       return ret;
00206     }
00207   }
00208 
00209   bool remove(const _VDBL_rowid _ri)
00210   {
00212     if(_T_v->view_type() == _VDBL_V_window)
00213     {
00214       _T_rowref::iterator _v(_T_rr.find(_ri));
00215       if(_ri == _T_rr.end())
00216         return false;
00217       else
00218       {
00219         std::map<_VDBL_rowid,_VDBL_tableid>& _rowmap(_v.second);
00220         std::map<_VDBL_rowid,_VDBL_tableid>::iterator __r;
00221         bool ret = true;
00222         for(__r = _rowmap.begin(); __r != _rowmap.end(); ++__r)
00223           ret = _T_v->remove(*__r) && ret;
00224         made_change();
00225         return ret;
00226       }
00227     }
00228     else
00229     {
00230       _T_rows::iterator __x = _T_r.find(_ri);
00231       if(__x == _T_r.end())
00232         return false;
00233       else
00234       {
00235         _T_r.erase(__x);
00236         made_change();
00237         return true;
00238       }
00239     }
00240   }
00241 
00242   bool has_col(const std::string& _C_n) const
00243   {
00244     return _T_v->has_col(_C_n);
00245   }
00246 
00247   const _VDBL_row& get_row(const _VDBL_rowid& _ri, bool& error) const
00248   {
00249     _T_rows::const_iterator _x(_T_r.find(_ri));
00250     if(_x == _T_r.end()) // this row is not local -> get it from view
00251     {
00252       if(_T_v->get_change_ctr() == _T_v_lastchg)
00253       {
00254         _x = _T_rowcache.find();
00255         if(_x != _T_rowcache.end()) // this row is in the cache
00256         {
00257           error = false;
00258           return (*_x).second;
00259         }
00260       }
00261       else
00262       { // invalidate (i.e. remove) the cache
00263         _T_rowcache.erase(_T_rowcache.begin(), _T_rowcache.end());
00264       }
00265       _T_rowref::const_iterator _y(_T_rr.find(_ri));
00266       if(_y == _T_rr.end()) // this row is nowhere -> fail
00267       {
00268         error = true;
00269         return ___empty_row_return;
00270       }
00271       const std::map<_VDBL_tableid,_VDBL_rowid>& _yr(_y.second);
00272 
00273       _VDBL_row _rw;
00274       error = false;
00275       std::map<_VDBL_tableid,const _VDBL_row*> _fetched;
00276       std::map<_VDBL_tableid,const _VDBL_row*>::iterator _fit;
00277       for(_T_colref::const_iterator _cr = _T_cr.begin(); _cr != _T_cr.end();
00278           ++_cr)
00279       {
00280         const _VDBL_tableid& _ti((*_cr).second.second);
00281         if((_fit = _fetched.find(_ti)) == _fetched.end())
00282         {
00283           std::map<_VDBL_tableid,_VDBL_rowid>::const_iterator
00284                                                         _rri(_yr.find(_ti));
00285           const _VDBL_row& _rrr(_T_v->get_row(*_rri));
00286           _fit = _fetched.insert(std::make_pair(_ti,&_rrr));
00287         }
00288         const _VDBL_col& _rrc((*_fit).second->get_col((*_cr).second.first,
00289                               error));
00290         if(error)
00291           return ___empty_row_return;
00292         error = _rw.insert((*_cr).first,_rrc);
00293         if(error)
00294           return ___empty_row_return;
00295       }
00296       return _rw;
00297     }
00298     else
00299     {
00300       error = false;
00301       return (*_x).second;
00302     }
00303   }
00304 
00305   const _VDBL_row* get_row_ptr(const _VDBL_rowid& _ri) const
00306   {
00307     _T_rows::const_iterator _x(_T_r.find(_ri));
00308     if(_x == _T_r.end()) // this row is not local -> get it from view
00309     {
00310       if(_T_v->get_change_ctr() == _T_v_lastchg)
00311       {
00312         _x = _T_rowcache.find();
00313         if(_x != _T_rowcache.end()) // this row is in the cache
00314           return &(*_x).second;
00315       }
00316       else
00317       { // invalidate (i.e. remove) the cache
00318         _T_rowcache.erase(_T_rowcache.begin(), _T_rowcache.end());
00319       }
00320       _T_rowref::const_iterator _y(_T_rr.find(_ri));
00321       if(_y == _T_rr.end()) // this row is nowhere -> fail
00322         return NULL;
00323 
00324       const std::map<_VDBL_tableid,_VDBL_rowid>& _yr(_y.second);
00325 
00326       _VDBL_row _rw;
00327       bool error(false);
00328       std::map<_VDBL_tableid,const _VDBL_row*> _fetched;
00329       std::map<_VDBL_tableid,const _VDBL_row*>::iterator _fit;
00330       for(_T_colref::const_iterator _cr = _T_cr.begin(); _cr != _T_cr.end();
00331           ++_cr)
00332       {
00333         const _VDBL_tableid& _ti((*_cr).second.second);
00334         if((_fit = _fetched.find(_ti)) == _fetched.end())
00335         {
00336           std::map<_VDBL_tableid,_VDBL_rowid>::const_iterator
00337                                                         _rri(_yr.find(_ti));
00338           const _VDBL_row& _rrr(_T_v->get_row(*_rri));
00339           _fit = _fetched.insert(std::make_pair(_ti,&_rrr));
00340         }
00341         const _VDBL_col& _rrc((*_fit).second->get_col((*_cr).second.first,
00342                               error));
00343         if(error)
00344           return NULL;
00345         error = _rw.insert((*_cr).first,_rrc);
00346         if(error)
00347           return NULL;
00348       }
00349       return &_rw;
00350     }
00351     else
00352       return &(*_x).second;
00353   }
00354 
00355   _VDBL_row& get_row(const _VDBL_rowid& _ri, bool& error)
00356   {
00357     _T_rows::iterator _x(_T_r.find(_ri));
00358     if(_x == _T_r.end()) // this row is not local -> get it from view
00359     {
00360       if(_T_v->get_change_ctr() == _T_v_lastchg)
00361       {
00362         _x = _T_rowcache.find();
00363         if(_x != _T_rowcache.end()) // this row is in the cache
00364         {
00365           error = false;
00366           return (*_x).second;
00367         }
00368       }
00369       else
00370       { // invalidate (i.e. remove) the cache
00371         _T_rowcache.erase(_T_rowcache.begin(), _T_rowcache.end());
00372       }
00373       _T_rowref::iterator _y(_T_rr.find(_ri));
00374       if(_y == _T_rr.end()) // this row is nowhere -> fail
00375       {
00376         error = true;
00377         return ___empty_row_return;
00378       }
00379       std::map<_VDBL_tableid,_VDBL_rowid>& _yr(_y.second);
00380 
00381       _VDBL_row _rw;
00382       error = false;
00383       std::map<_VDBL_tableid,_VDBL_row*> _fetched;
00384       std::map<_VDBL_tableid,_VDBL_row*>::iterator _fit;
00385       for(_T_colref::const_iterator _cr = _T_cr.begin(); _cr != _T_cr.end();
00386           ++_cr)
00387       {
00388         _VDBL_tableid& _ti((*_cr).second.second);
00389         if((_fit = _fetched.find(_ti)) == _fetched.end())
00390         {
00391           std::map<_VDBL_tableid,_VDBL_rowid>::iterator
00392                                                         _rri(_yr.find(_ti));
00393           _VDBL_row& _rrr(_T_v->get_row(*_rri));
00394           _fit = _fetched.insert(std::make_pair(_ti,&_rrr));
00395         }
00396         _VDBL_col& _rrc((*_fit).second->get_col((*_cr).second.first,
00397                         error));
00398         if(error)
00399           return ___empty_row_return;
00400         error = _rw.insert((*_cr).first,_rrc);
00401         if(error)
00402           return ___empty_row_return;
00403       }
00404       _x = _T_rowcache.insert(_ri,_rw);
00405       return (*_x).second;
00406     }
00407     else
00408     {
00409       error = false;
00410       return (*_x).second;
00411     }
00412   }
00413 
00414   bool retrieve(const _VDBL_rowid& _r, const _VDBL_colid& _c,
00415                 const _VDBL_context& _ctx, _VDBL_alltype_base*& _val) const
00416   {
00417     bool ret;
00418     const _VDBL_row& _row(get_row(_r, ret));
00419     if(ret)
00420       return false;
00421 
00422     const _VDBL_col& _col(_row.get_col(_c, ret));
00423     if(ret)
00424     {           // row does not contain this col -> get default
00425       _T_defaults::const_iterator _x(_T_d.find(_c));
00426       if(_x == _T_d.end())      // there is no default
00427         return false;
00428       _VDBL_col _col2((*_x).second.second);
00429       if(!VDBL_CMP_TYPEID(_col2.return_type_id(), typeid(_R)))
00430         return false;
00431       _col2.setcontext(_ctx, &_row);
00432       _col2.def_copy(_val);
00433       return true;
00434     }
00435     else
00436     {           // row contains this col
00437       if(!VDBL_CMP_TYPEID(_col.return_type_id(), typeid(_R)))
00438         return false;
00439       _col.setcontext(_ctx, &_row);
00440       _col.get_copy(_val);
00441       return true;
00442     }
00443   }
00444 
00445   bool create_index(const std::string& _C_i) { throw "create_index: NYI"; }
00446   bool alter_index(const std::string& _C_i) { throw "alter_index: NYI"; }
00447   bool drop_index(const std::string& _C_i) { throw "drop_index: NYI"; }
00448 };
00449 
00450 class view_table : _VDBL_viewtable
00451 {
00452 public:
00453   typedef _VDBL_row row;
00454   typedef _VDBL_col col;
00455   typedef __VDBL_index index;
00456   typedef _VDBL_context context;
00457   typedef _VDBL_col def;
00458 
00459   typedef _VDBL_table::_T_colspec col_spec;
00460 };
00461 
00462 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00463 #pragma reset woff 1209
00464 #endif
00465 
00466 __VDBL_END_NAMESPACE
00467 
00468 #endif /* __VDBL_VTABLE_H */
00469 
00470 // Local Variables:
00471 // mode:C++
00472 // End:
00473 //

Generated on Tue Nov 4 01:29:11 2003 for Vienna Database Library by doxygen1.2.18