Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

tablewriter.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/tablewriter.h
00005  *
00006  *   DESCRIPTION
00007  *      definition of the pqxx::tablewriter class.
00008  *   pqxx::tablewriter enables optimized batch updates to a database table
00009  *
00010  * Copyright (c) 2001-2003, Jeroen T. Vermeulen <jtv@xs4all.nl>
00011  *
00012  * See COPYING for copyright license.  If you did not receive a file called
00013  * COPYING with this source code, please notify the distributor of this mistake,
00014  * or contact the author.
00015  *
00016  *-------------------------------------------------------------------------
00017  */
00018 #ifndef PQXX_TABLEWRITER_H
00019 #define PQXX_TABLEWRITER_H
00020 
00021 #include "pqxx/config.h"
00022 
00023 #include <numeric>
00024 #include <string>
00025 
00026 #include "pqxx/tablestream.h"
00027 
00028 
00029 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00030  */
00031 
00032 namespace pqxx
00033 {
00034 class tablereader;      // See pqxx/tablereader.h
00035 
00037 
00046 class PQXX_LIBEXPORT tablewriter : public tablestream
00047 {
00048 public:
00049   typedef unsigned size_type;
00050 
00051   tablewriter(transaction_base &Trans, const PGSTD::string &WName);     //[t5]
00052   ~tablewriter();                                                       //[t5]
00053 
00054   template<typename IT> void insert(IT Begin, IT End);                  //[t5]
00055   template<typename TUPLE> void insert(const TUPLE &);                  //[t5]
00056   template<typename IT> void push_back(IT Begin, IT End);               //[t10]
00057   template<typename TUPLE> void push_back(const TUPLE &);               //[t10]
00058 
00059   void reserve(size_type) {}                                            //[t9]
00060 
00061   template<typename TUPLE> tablewriter &operator<<(const TUPLE &);      //[t5]
00062 
00063   // Copy table from one database to another
00064   tablewriter &operator<<(tablereader &);                               //[t6]
00065 
00068   template<typename IT> PGSTD::string ezinekoT(IT Begin, IT End) const; //[t10]
00069   template<typename TUPLE> PGSTD::string ezinekoT(const TUPLE &) const; //[t10]
00070 
00071 private:
00072   void WriteRawLine(const PGSTD::string &);
00073 
00074   class PQXX_LIBEXPORT fieldconverter
00075   {
00076   public:
00077     fieldconverter(const PGSTD::string &N) : Null(N) {}
00078 
00079     template<typename T> PGSTD::string operator()(const PGSTD::string &S,
00080                                                   T i) const
00081     {
00082       PGSTD::string Field(ToString(i));
00083       return S + ((Field == Null) ? PGNull() : Field);
00084     }
00085 
00086 #ifdef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00087     template<> PGSTD::string operator()(const PGSTD::string &S,
00088                                         PGSTD::string i) const;
00089 #endif
00090 
00091     PGSTD::string operator()(const PGSTD::string &S, const char *i) const;
00092 
00093   private:
00094     static PGSTD::string PGNull() { return "\\N"; }
00095     static void Escape(PGSTD::string &);
00096     PGSTD::string Null;
00097   };
00098 };
00099 
00101 typedef tablewriter TableWriter;
00102 
00103 }
00104 
00105 
00106 namespace PGSTD
00107 {
00108 // Specialized back_insert_iterator for tablewriter, doesn't require a 
00109 // value_type to be defined.  Accepts any container type instead.
00110 template<> 
00111   class PQXX_LIBEXPORT back_insert_iterator<pqxx::tablewriter> :        //[t9]
00112         public iterator<output_iterator_tag, void,void,void,void>
00113 {
00114 public:
00115   explicit back_insert_iterator(pqxx::tablewriter &W) : m_Writer(W) {}
00116 
00117   template<typename TUPLE> 
00118   back_insert_iterator &operator=(const TUPLE &T)
00119   {
00120     m_Writer.insert(T);
00121     return *this;
00122   }
00123 
00124   back_insert_iterator &operator++() { return *this; }
00125   back_insert_iterator &operator++(int) { return *this; }
00126   back_insert_iterator &operator*() { return *this; }
00127 
00128 private:
00129   pqxx::tablewriter &m_Writer;
00130 };
00131 
00132 } // namespace
00133 
00134 
00135 namespace pqxx
00136 {
00137 
00138 template<>
00139 inline PGSTD::string 
00140 tablewriter::fieldconverter::operator()(const PGSTD::string &S,
00141                                         PGSTD::string i) const
00142 {
00143   if (i == Null) i = PGNull();
00144   else Escape(i);
00145   return S + i + '\t';
00146 }
00147 
00148 
00149 inline PGSTD::string
00150 tablewriter::fieldconverter::operator()(const PGSTD::string &S, 
00151                                         const char *i) const
00152 {
00153   return operator()(S, PGSTD::string(i));
00154 }
00155 
00156 
00157 inline void tablewriter::fieldconverter::Escape(PGSTD::string &S)
00158 {
00159   const char Special[] = "\n\t\\";
00160 
00161   for (PGSTD::string::size_type j = S.find_first_of(Special);
00162        j != PGSTD::string::npos;
00163        j = S.find_first_of(Special, j+2))
00164     S.insert(j, 1, '\\');
00165 }
00166 
00167 
00168 template<typename IT> 
00169 inline PGSTD::string tablewriter::ezinekoT(IT Begin, IT End) const
00170 {
00171   PGSTD::string Line = PGSTD::accumulate(Begin, 
00172                                          End, 
00173                                          PGSTD::string(), 
00174                                          fieldconverter(NullStr()));
00175 
00176   // Above algorithm generates one separating tab too many.  Take it back.
00177   if (!Line.empty()) Line.erase(Line.size()-1);
00178 
00179   return Line;
00180 }
00181 
00182 
00183 template<typename TUPLE> 
00184 inline PGSTD::string tablewriter::ezinekoT(const TUPLE &T) const
00185 {
00186   return ezinekoT(T.begin(), T.end());
00187 }
00188 
00189 
00190 template<typename IT> inline void tablewriter::insert(IT Begin, IT End)
00191 {
00192   WriteRawLine(ezinekoT(Begin, End));
00193 }
00194 
00195 
00196 template<typename TUPLE> inline void tablewriter::insert(const TUPLE &T)
00197 {
00198   insert(T.begin(), T.end());
00199 }
00200 
00201 template<typename IT> 
00202 inline void tablewriter::push_back(IT Begin, IT End)
00203 {
00204   insert(Begin, End);
00205 }
00206 
00207 template<typename TUPLE> 
00208 inline void tablewriter::push_back(const TUPLE &T)
00209 {
00210   insert(T.begin(), T.end());
00211 }
00212 
00213 template<typename TUPLE> 
00214 inline tablewriter &tablewriter::operator<<(const TUPLE &T)
00215 {
00216   insert(T);
00217   return *this;
00218 }
00219 
00220 }
00221 
00222 #endif
00223 

Generated on Sat Jun 7 00:49:34 2003 for libpqxx by doxygen1.3-rc3