Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

tablewriter.hxx

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

Generated on Sun Oct 5 05:38:08 2003 for libpqxx by doxygen 1.3.2