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 #ifndef _UESQL_QUERY__
00026 #define _UESQL_QUERY__
00027
00028 #include <algorithm>
00029 #include <cstdlib>
00030 #include <mpcl/util/strategy/identifier_generator.hh>
00031 #include <mpcl/util/collection/map.hh>
00032 #include "iterator.hh"
00033
00034
00036 namespace uesqlc
00037 {
00038
00046 template < typename TInstance ,
00047 typename TDataSource ,
00048 typename TObjectIdentifierFactory = mpcl::util::strategy::TIdentifierGenerator >
00049 class TQuery :
00050 protected TDataSource ,
00051 public TObjectIdentifierFactory
00052 {
00053
00054 public:
00055
00056 typedef
00057 TInstance
00058 value_type;
00059
00060 typedef
00061 TInstance&
00062 reference;
00063
00064 typedef
00065 const TInstance&
00066 const_reference;
00067
00068 typedef
00069 TIterator<TQuery>
00070 iterator;
00071
00072 typedef
00073 const TIterator<TQuery>
00074 const_iterator;
00075
00076 typedef
00077 typename TIterator<TQuery>::difference_type
00078 difference_type;
00079
00080 typedef
00081 typename TDataSource::size_type
00082 size_type;
00083
00084
00085 protected:
00086
00088 bool gIsDeclared;
00089
00091 bool gIsOpened;
00092
00094 long int liCurrent;
00095
00097 long int liTarget;
00098
00100 mpcl::util::collection::TMap<long int, value_type> tInstanceMap;
00101
00102 value_type tLastInstance;
00103
00105 TString yCursorName;
00106
00108 size_type zTupleCount;
00109
00110
00111 protected:
00112
00113
00114
00115
00116
00118 void close (void)
00119 {
00120 if ( gIsOpened )
00121 {
00122 TDataSource::closeCursor (yCursorName);
00123 gIsOpened = false;
00124 }
00125 }
00126
00127 void fetch (void)
00128 {
00129 if ( !gIsOpened )
00130 {
00131 open();
00132 }
00133 if ( liTarget != liCurrent )
00134 {
00135 TDataSource::setErrorException();
00136 if ( liTarget == liCurrent + 1 )
00137 {
00138 TDataSource::fetchNext (yCursorName, tLastInstance);
00139 }
00140 else
00141 {
00142 TDataSource::fetchAbsolute (yCursorName, tLastInstance, TInteger (liTarget));
00143 }
00144 liCurrent = liTarget;
00145 tInstanceMap.bind (liCurrent, tLastInstance);
00146 }
00147 }
00148
00150 void open (void)
00151 {
00152 if ( gIsDeclared )
00153 {
00154 if ( gIsOpened )
00155 {
00156 close();
00157 }
00158 }
00159 else
00160 {
00161 zTupleCount = TDataSource::declareCursor (yCursorName);
00162 }
00163 TDataSource::openCursor (yCursorName);
00164 gIsDeclared = true;
00165 gIsOpened = true;
00166 }
00167
00168
00169 public:
00170
00171
00172
00173
00174
00175 TQuery (void) :
00176 gIsDeclared (false) ,
00177 gIsOpened (false) ,
00178 liCurrent (-1) ,
00179 liTarget (0) ,
00180 tInstanceMap () ,
00181 tLastInstance () ,
00182 yCursorName (_getObjectIdentifier()) ,
00183 zTupleCount (0) {}
00184
00185 TQuery (const TQuery& rktQUERY) :
00186 gIsDeclared (false) ,
00187 gIsOpened (false) ,
00188 liCurrent (rktQUERY.liCurrent) ,
00189 liTarget (rktQUERY.liTarget) ,
00190 tInstanceMap (rktQUERY.tInstanceMap) ,
00191 tLastInstance (rktQUERY.tLastInstance) ,
00192 yCursorName (_getObjectIdentifier()) ,
00193 zTupleCount (rktQUERY.zTupleCount) {}
00194
00195 virtual ~TQuery (void) {}
00196
00197 iterator begin (void)
00198 {
00199 iterator tRet (this);
00200
00201 return tRet;
00202 }
00203
00204 iterator end (void)
00205 {
00206 iterator tRet (this);
00207
00208 tRet.setPastTheEnd();
00209 return tRet;
00210 }
00211
00216 TQuery& operator = (const TQuery& rktQUERY)
00217 {
00218 gIsDeclared = false;
00219 gIsOpened = false;
00220 liCurrent = rktQUERY.liCurrent;
00221 liTarget = rktQUERY.liTarget;
00222 zTupleCount = rktQUERY.zTupleCount;
00223 tInstanceMap = rktQUERY.tInstanceMap;
00224 tLastInstance = rktQUERY.tLastInstance;
00225 yCursorName = _getObjectIdentifier();
00226 return *this;
00227 }
00228
00233 void swap (TQuery&) {}
00234
00235
00236 protected :
00237
00238
00239
00240
00241
00246 static mpcl::text::TString _getObjectIdentifier (void)
00247 {
00248 mpcl::text::TString yRet = mpcl::text::Format ("cursor_%lu", _luiCounter);
00249
00250 _luiCounter++;
00251 return yRet;
00252 }
00253
00254
00255 public:
00256
00257
00258
00259
00260
00261 bool empty (void) const
00262 {
00263 return ( size() == 0 );
00264 }
00265
00266 size_type max_size (void) const
00267 {
00268 return size_type (-1);
00269 }
00270
00271 bool operator == (const TQuery& rktQUERY) const
00272 {
00273 bool gRet = false;
00274
00275 if ( size() == rktQUERY.size() )
00276 {
00277 gRet = std::equal<iterator, iterator> (begin(), end(), rktQUERY.begin());
00278 }
00279 return gRet;
00280 }
00281
00282 bool operator != (const TQuery& rktQUERY) const
00283 {
00284 return !(operator == (rktQUERY));
00285 }
00286
00287 bool operator < (const TQuery& rktQUERY) const
00288 {
00289 return
00290 std::lexicographical_compare<iterator, iterator>
00291 (
00292 begin() ,
00293 end() ,
00294 rktQUERY.begin() ,
00295 rktQUERY.end()
00296 );
00297 }
00298
00299 bool operator > (const TQuery& rktQUERY) const
00300 {
00301 return rktQUERY < *this;
00302 }
00303
00304 bool operator <= (const TQuery& rktQUERY) const
00305 {
00306 return !(operator > (rktQUERY));
00307 }
00308
00309 bool operator >= (const TQuery& rktQUERY) const
00310 {
00311 return !(operator < (rktQUERY));
00312 }
00313
00314 size_type size (void)
00315 {
00316 if ( !gIsDeclared )
00317 {
00318 zTupleCount = TDataSource::declareCursor (yCursorName);
00319 gIsDeclared = true;
00320 }
00321 return zTupleCount;
00322 }
00323
00324 reference operator [] (long int liITEM)
00325 {
00326 if ( !tInstanceMap.isBound (liITEM) )
00327 {
00328 liTarget = liITEM;
00329 fetch();
00330 }
00331 return tInstanceMap [liITEM];
00332 }
00333
00334 const_reference operator [] (long int liITEM) const
00335 {
00336 if ( !tInstanceMap.isBound (liITEM) )
00337 {
00338 liTarget = liITEM;
00339 fetch();
00340 }
00341 return tInstanceMap [liITEM];
00342 }
00343
00344 };
00345
00346 }
00347
00348
00350 namespace std
00351 {
00352
00353 template < typename TIterator ,
00354 typename TDataSource ,
00355 typename TObjectIdentifierFactory >
00356 inline void swap
00357 (
00358 uesqlc::TQuery<TIterator, TDataSource, TObjectIdentifierFactory>& rtQUERY1 ,
00359 uesqlc::TQuery<TIterator, TDataSource, TObjectIdentifierFactory>& rtQUERY2
00360 )
00361 {
00362 rtQUERY1.swap (rtQUERY2);
00363 }
00364
00365 }
00366
00367
00368 #endif // not _UESQL_QUERY__