cursor.hxx

00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/cursor.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definition of the iterator/container-style cursor classes
00008  *   C++-style wrappers for SQL cursors
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead.
00010  *
00011  * Copyright (c) 2004-2015, Jeroen T. Vermeulen <jtv@xs4all.nl>
00012  *
00013  * See COPYING for copyright license.  If you did not receive a file called
00014  * COPYING with this source code, please notify the distributor of this mistake,
00015  * or contact the author.
00016  *
00017  *-------------------------------------------------------------------------
00018  */
00019 #ifndef PQXX_H_CURSOR
00020 #define PQXX_H_CURSOR
00021 
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024 
00025 #include <limits>
00026 #include <stdexcept>
00027 
00028 #include "pqxx/result"
00029 #include "pqxx/transaction_base"
00030 
00031 
00032 namespace pqxx
00033 {
00034 class dbtransaction;
00035 
00036 
00038 
00049 class PQXX_LIBEXPORT cursor_base
00050 {
00051 public:
00052   typedef result::size_type size_type;
00053   typedef result::difference_type difference_type;
00054 
00056 
00059   enum accesspolicy
00060   {
00062     forward_only,
00064     random_access
00065   };
00066 
00068 
00071   enum updatepolicy
00072   {
00074     read_only,
00076     update
00077   };
00078 
00080 
00098   enum ownershippolicy
00099   {
00101     owned,
00103     loose
00104   };
00105 
00110 
00111 
00114   static difference_type all() PQXX_NOEXCEPT;                           //[t81]
00116 
00118   static difference_type next() PQXX_NOEXCEPT { return 1; }             //[t81]
00120 
00122   static difference_type prior() PQXX_NOEXCEPT { return -1; }           //[t0]
00124 
00126   static difference_type backward_all() PQXX_NOEXCEPT;                  //[t0]
00127 
00129 
00131 
00136   const std::string &name() const PQXX_NOEXCEPT { return m_name; }      //[t81]
00137 
00138 protected:
00139   cursor_base(connection_base &,
00140         const std::string &Name,
00141         bool embellish_name=true);
00142 
00143   const std::string m_name;
00144 
00145 private:
00147   cursor_base();
00149   cursor_base(const cursor_base &);
00151   cursor_base &operator=(const cursor_base &);
00152 };
00153 
00154 
00155 inline cursor_base::difference_type cursor_base::all() PQXX_NOEXCEPT
00156 {
00157   return std::numeric_limits<int>::max()-1;
00158 }
00159 
00160 inline cursor_base::difference_type cursor_base::backward_all() PQXX_NOEXCEPT
00161 {
00162   return std::numeric_limits<int>::min()+1;
00163 }
00164 
00165 
00166 namespace internal
00167 {
00169 
00183 class PQXX_LIBEXPORT sql_cursor : public cursor_base
00184 {
00185 public:
00186   sql_cursor(transaction_base &t,
00187         const std::string &query,
00188         const std::string &cname,
00189         cursor_base::accesspolicy ap,
00190         cursor_base::updatepolicy up,
00191         cursor_base::ownershippolicy op,
00192         bool hold);
00193 
00194   sql_cursor(transaction_base &t,
00195         const std::string &cname,
00196         cursor_base::ownershippolicy op);
00197 
00198   ~sql_cursor() PQXX_NOEXCEPT { close(); }
00199 
00200   result fetch(difference_type rows, difference_type &displacement);
00201   result fetch(difference_type rows)
00202                                 { difference_type d=0; return fetch(rows, d); }
00203   difference_type move(difference_type rows, difference_type &displacement);
00204   difference_type move(difference_type rows)
00205                                 { difference_type d=0; return move(rows, d); }
00206 
00208 
00214   difference_type pos() const PQXX_NOEXCEPT { return m_pos; }
00215 
00217 
00223   difference_type endpos() const PQXX_NOEXCEPT { return m_endpos; }
00224 
00226   const result &empty_result() const PQXX_NOEXCEPT { return m_empty_result; }
00227 
00228   void close() PQXX_NOEXCEPT;
00229 
00230 private:
00231   difference_type adjust(difference_type hoped, difference_type actual);
00232   static std::string stridestring(difference_type);
00234   void init_empty_result(transaction_base &);
00235 
00237   connection_base &m_home;
00238 
00240   result m_empty_result;
00241 
00242   result m_cached_current_row;
00243 
00245   bool m_adopted;
00246 
00248   cursor_base::ownershippolicy m_ownership;
00249 
00251   int m_at_end;
00252 
00254   difference_type m_pos;
00255 
00257   difference_type m_endpos;
00258 };
00259 
00260 
00261 PQXX_LIBEXPORT result::size_type obtain_stateless_cursor_size(sql_cursor &);
00262 PQXX_LIBEXPORT result stateless_cursor_retrieve(
00263         sql_cursor &,
00264         result::difference_type size,
00265         result::difference_type begin_pos,
00266         result::difference_type end_pos);
00267 
00268 } // namespace internal
00269 
00270 
00272 
00278 template<cursor_base::updatepolicy up, cursor_base::ownershippolicy op>
00279 class stateless_cursor
00280 {
00281 public:
00282   typedef result::size_type size_type;
00283   typedef result::difference_type difference_type;
00284 
00286   stateless_cursor(
00287         transaction_base &trans,
00288         const std::string &query,
00289         const std::string &cname,
00290         bool hold) :
00291     m_cur(trans, query, cname, cursor_base::random_access, up, op, hold)
00292   {
00293   }
00294 
00296   stateless_cursor(
00297         transaction_base &trans,
00298         const std::string adopted_cursor) :
00299     m_cur(trans, adopted_cursor, op)
00300   {
00301     // Put cursor in known position
00302     m_cur.move(cursor_base::backward_all());
00303   }
00304 
00305   void close() PQXX_NOEXCEPT { m_cur.close(); }
00306 
00308 
00311   size_type size() { return internal::obtain_stateless_cursor_size(m_cur); }
00312 
00314 
00325   result retrieve(difference_type begin_pos, difference_type end_pos)
00326   {
00327     return internal::stateless_cursor_retrieve(
00328         m_cur,
00329         result::difference_type(size()),
00330         begin_pos,
00331         end_pos);
00332   }
00333 
00334   const std::string &name() const PQXX_NOEXCEPT { return m_cur.name(); }
00335 
00336 private:
00337   internal::sql_cursor m_cur;
00338 };
00339 
00340 
00341 class icursor_iterator;
00342 
00343 
00344 namespace internal
00345 {
00346 namespace gate
00347 {
00348 class icursor_iterator_icursorstream;
00349 class icursorstream_icursor_iterator;
00350 } // namespace internal::gate
00351 } // namespace internal
00352 
00353 
00355 
00370 class PQXX_LIBEXPORT icursorstream
00371 {
00372 public:
00373   typedef cursor_base::size_type size_type;
00374   typedef cursor_base::difference_type difference_type;
00375 
00377 
00388   icursorstream(transaction_base &context,
00389       const std::string &query,
00390       const std::string &basename,
00391       difference_type sstride=1);                                       //[t81]
00392 
00394 
00418   icursorstream(transaction_base &context,
00419       const field &cname,
00420       difference_type sstride=1,
00421       cursor_base::ownershippolicy op=cursor_base::owned);              //[t84]
00422 
00423   operator bool() const PQXX_NOEXCEPT { return !m_done; }
00424 
00426 
00432   icursorstream &get(result &res) { res = fetchblock(); return *this; } //[t81]
00434 
00440   icursorstream &operator>>(result &res) { return get(res); }           //[t81]
00441 
00443 
00447   icursorstream &ignore(std::streamsize n=1);                           //[t81]
00448 
00450 
00453   void set_stride(difference_type stride);                              //[t81]
00454   difference_type stride() const PQXX_NOEXCEPT { return m_stride; }     //[t81]
00455 
00456 private:
00457   result fetchblock();
00458 
00459   friend class internal::gate::icursorstream_icursor_iterator;
00460   size_type forward(size_type n=1);
00461   void insert_iterator(icursor_iterator *) PQXX_NOEXCEPT;
00462   void remove_iterator(icursor_iterator *) const PQXX_NOEXCEPT;
00463 
00464   void service_iterators(difference_type);
00465 
00466   internal::sql_cursor m_cur;
00467 
00468   difference_type m_stride;
00469   difference_type m_realpos, m_reqpos;
00470 
00471   mutable icursor_iterator *m_iterators;
00472 
00473   bool m_done;
00474 };
00475 
00476 
00478 
00504 class PQXX_LIBEXPORT icursor_iterator :
00505   public std::iterator<std::input_iterator_tag,
00506         result,
00507         cursor_base::size_type,
00508         const result *,
00509         const result &>
00510 {
00511 public:
00512   typedef icursorstream istream_type;
00513   typedef istream_type::size_type size_type;
00514   typedef istream_type::difference_type difference_type;
00515 
00516   icursor_iterator() PQXX_NOEXCEPT;                                     //[t84]
00517   explicit icursor_iterator(istream_type &) PQXX_NOEXCEPT;              //[t84]
00518   icursor_iterator(const icursor_iterator &) PQXX_NOEXCEPT;             //[t84]
00519   ~icursor_iterator() PQXX_NOEXCEPT;
00520 
00521   const result &operator*() const { refresh(); return m_here; }         //[t84]
00522   const result *operator->() const { refresh(); return &m_here; }       //[t84]
00523   icursor_iterator &operator++();                                       //[t84]
00524   icursor_iterator operator++(int);                                     //[t84]
00525   icursor_iterator &operator+=(difference_type);                        //[t84]
00526   icursor_iterator &operator=(const icursor_iterator &) PQXX_NOEXCEPT;  //[t84]
00527 
00528   bool operator==(const icursor_iterator &rhs) const;                   //[t84]
00529   bool operator!=(const icursor_iterator &rhs) const PQXX_NOEXCEPT      //[t84]
00530         { return !operator==(rhs); }
00531   bool operator<(const icursor_iterator &rhs) const;                    //[t84]
00532   bool operator>(const icursor_iterator &rhs) const                     //[t84]
00533         { return rhs < *this; }
00534   bool operator<=(const icursor_iterator &rhs) const                    //[t84]
00535         { return !(*this > rhs); }
00536   bool operator>=(const icursor_iterator &rhs) const                    //[t84]
00537         { return !(*this < rhs); }
00538 
00539 private:
00540   void refresh() const;
00541 
00542   friend class internal::gate::icursor_iterator_icursorstream;
00543   difference_type pos() const PQXX_NOEXCEPT { return m_pos; }
00544   void fill(const result &);
00545 
00546   icursorstream *m_stream;
00547   result m_here;
00548   difference_type m_pos;
00549   icursor_iterator *m_prev, *m_next;
00550 };
00551 
00552 
00553 } // namespace pqxx
00554 
00555 #include "pqxx/compiler-internal-post.hxx"
00556 
00557 #endif
00558 

Generated on 17 Mar 2017 for libpqxx by  doxygen 1.6.1