libpqxx 4.0
field.hxx
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/field.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definitions for the pqxx::field class.
00008  *   pqxx::field refers to a field in a query result.
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead.
00010  *
00011  * Copyright (c) 2001-2011, 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_FIELD
00020 #define PQXX_H_FIELD
00021 
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024 
00025 #include "pqxx/strconv"
00026 
00027 
00028 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00029  */
00030 
00031 namespace pqxx
00032 {
00033 class result;
00034 class tuple;
00035 
00036 typedef unsigned int tuple_size_type;
00037 typedef signed int tuple_difference_type;
00038 
00040 
00043 class PQXX_LIBEXPORT field
00044 {
00045 public:
00046   typedef size_t size_type;
00047 
00049 
00053   field(const tuple &T, tuple_size_type C) throw ();            //[t1]
00054 
00059 
00060 
00076   bool operator==(const field &) const;                         //[t75]
00077 
00079 
00081   bool operator!=(const field &rhs) const                               //[t82]
00082                                                     {return !operator==(rhs);}
00084 
00089 
00090   const char *name() const;                                             //[t11]
00091 
00093   oid type() const;                                                     //[t7]
00094 
00096   oid table() const;                                                    //[t2]
00097 
00098   tuple_size_type num() const { return col(); }                         //[t82]
00099 
00101   tuple_size_type table_column() const;                                 //[t93]
00103 
00108 
00109 
00114   const char *c_str() const;                                            //[t2]
00115 
00117   template<typename T> bool to(T &Obj) const                            //[t3]
00118   {
00119     const char *const bytes = c_str();
00120     if (!bytes[0] && is_null()) return false;
00121     from_string(bytes, Obj);
00122     return true;
00123   }
00124 
00126   template<typename T> bool operator>>(T &Obj) const                    //[t7]
00127       { return to(Obj); }
00128 
00129 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00130 
00131   template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00132 
00134 
00137   template<> bool to<const char *>(const char *&Obj) const;
00138 #endif
00139 
00141   template<typename T> bool to(T &Obj, const T &Default) const  //[t12]
00142   {
00143     const bool NotNull = to(Obj);
00144     if (!NotNull) Obj = Default;
00145     return NotNull;
00146   }
00147 
00149 
00152   template<typename T> T as(const T &Default) const                     //[t1]
00153   {
00154     T Obj;
00155     to(Obj, Default);
00156     return Obj;
00157   }
00158 
00160   template<typename T> T as() const                                     //[t45]
00161   {
00162     T Obj;
00163     const bool NotNull = to(Obj);
00164     if (!NotNull) Obj = string_traits<T>::null();
00165     return Obj;
00166   }
00167 
00168   bool is_null() const throw ();                                        //[t12]
00169   size_type size() const throw ();                                      //[t11]
00171 
00172 
00173 protected:
00174   const result *home() const throw () { return m_home; }
00175   size_t idx() const throw () { return m_row; }
00176   tuple_size_type col() const throw () { return m_col; }
00177 
00178   tuple_size_type m_col;
00179 
00180 private:
00181   const result *m_home;
00182   size_t m_row;
00183 };
00184 
00185 
00187 template<>
00188 inline bool field::to<PGSTD::string>(PGSTD::string &Obj) const
00189 {
00190   const char *const bytes = c_str();
00191   if (!bytes[0] && is_null()) return false;
00192   Obj = PGSTD::string(bytes, size());
00193   return true;
00194 }
00195 
00197 
00202 template<>
00203 inline bool field::to<const char *>(const char *&Obj) const
00204 {
00205   if (is_null()) return false;
00206   Obj = c_str();
00207   return true;
00208 }
00209 
00210 
00211 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00212   class field_streambuf :
00213 #ifdef PQXX_HAVE_STREAMBUF
00214   public PGSTD::basic_streambuf<CHAR, TRAITS>
00215 #else
00216   public PGSTD::streambuf
00217 #endif
00218 {
00219 public:
00220   typedef CHAR char_type;
00221   typedef TRAITS traits_type;
00222   typedef typename traits_type::int_type int_type;
00223 #ifdef PQXX_HAVE_STREAMBUF
00224   typedef typename traits_type::pos_type pos_type;
00225   typedef typename traits_type::off_type off_type;
00226 #else
00227   typedef streamoff off_type;
00228   typedef streampos pos_type;
00229 #endif
00230   typedef PGSTD::ios::openmode openmode;
00231   typedef PGSTD::ios::seekdir seekdir;
00232 
00233   explicit field_streambuf(const field &F) :                    //[t74]
00234     m_Field(F)
00235   {
00236     initialize();
00237   }
00238 
00239 #ifdef PQXX_HAVE_STREAMBUF
00240 protected:
00241 #endif
00242   virtual int sync() { return traits_type::eof(); }
00243 
00244 protected:
00245   virtual pos_type seekoff(off_type, seekdir, openmode)
00246         { return traits_type::eof(); }
00247   virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00248   virtual int_type overflow(int_type) { return traits_type::eof(); }
00249   virtual int_type underflow() { return traits_type::eof(); }
00250 
00251 private:
00252   const field &m_Field;
00253 
00254   int_type initialize()
00255   {
00256     char_type *G =
00257       reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00258     this->setg(G, G, G + m_Field.size());
00259     return int_type(m_Field.size());
00260   }
00261 };
00262 
00263 
00265 
00273 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00274   class basic_fieldstream :
00275 #ifdef PQXX_HAVE_STREAMBUF
00276     public PGSTD::basic_istream<CHAR, TRAITS>
00277 #else
00278     public PGSTD::istream
00279 #endif
00280 {
00281 #ifdef PQXX_HAVE_STREAMBUF
00282   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00283 #else
00284   typedef PGSTD::istream super;
00285 #endif
00286 
00287 public:
00288   typedef CHAR char_type;
00289   typedef TRAITS traits_type;
00290   typedef typename traits_type::int_type int_type;
00291   typedef typename traits_type::pos_type pos_type;
00292   typedef typename traits_type::off_type off_type;
00293 
00294   basic_fieldstream(const field &F) : super(0), m_Buf(F)
00295         { super::init(&m_Buf); }
00296 
00297 private:
00298   field_streambuf<CHAR, TRAITS> m_Buf;
00299 };
00300 
00301 typedef basic_fieldstream<char> fieldstream;
00302 
00303 } // namespace pqxx
00304 
00305 
00306 #include "pqxx/compiler-internal-post.hxx"
00307 
00308 #endif