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  *-------------------------------------------------------------------------
00013  */
00014 #ifndef PQXX_TABLEWRITER_H
00015 #define PQXX_TABLEWRITER_H
00016 
00017 #include "config.h"
00018 
00019 #include <numeric>
00020 #include <string>
00021 
00022 #include "pqxx/tablestream.h"
00023 
00024 
00025 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00026  */
00027 
00028 namespace pqxx
00029 {
00030 class TableReader;      // See pqxx/tablereader.h
00031 
00033 
00042 class PQXX_LIBEXPORT TableWriter : public TableStream
00043 {
00044 public:
00045   typedef unsigned size_type;
00046 
00047   TableWriter(TransactionItf &Trans, const PGSTD::string &WName);       //[t5]
00048   ~TableWriter();                                                       //[t5]
00049 
00050   template<typename IT> void insert(IT Begin, IT End);                  //[t5]
00051   template<typename TUPLE> void insert(const TUPLE &);                  //[t5]
00052   template<typename IT> void push_back(IT Begin, IT End);               //[t10]
00053   template<typename TUPLE> void push_back(const TUPLE &);               //[t10]
00054 
00055   void reserve(size_type) {}                                            //[t9]
00056 
00057   template<typename TUPLE> TableWriter &operator<<(const TUPLE &);      //[t5]
00058 
00059   // Copy table from one database to another
00060   TableWriter &operator<<(TableReader &);                               //[t6]
00061 
00064   template<typename IT> PGSTD::string ezinekoT(IT Begin, IT End) const; //[t10]
00065   template<typename TUPLE> PGSTD::string ezinekoT(const TUPLE &) const; //[t10]
00066 
00067 private:
00068   void WriteRawLine(const PGSTD::string &);
00069 
00070   class FieldConverter
00071   {
00072   public:
00073     FieldConverter(const PGSTD::string &N) : Null(N) {}
00074 
00075     template<typename T> PGSTD::string operator()(const PGSTD::string &S,
00076                                                   T i) const
00077     {
00078       PGSTD::string Field(ToString(i));
00079       return S + ((Field == Null) ? PGNull() : Field);
00080     }
00081 
00082 #ifdef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00083     template<> PGSTD::string operator()(const PGSTD::string &S,
00084                                         PGSTD::string i) const
00085     {
00086       if (i == Null) i = PGNull();
00087       else Escape(i);
00088       return S + i + '\t';
00089     }
00090 #endif
00091 
00092     PGSTD::string operator()(const PGSTD::string &S, const char *i) const
00093 #ifdef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00094     {
00095       return operator()(S, PGSTD::string(i));
00096     }
00097 #else
00098     ;
00099 #endif
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<> class back_insert_iterator<pqxx::TableWriter> :              //[t9]
00116         public iterator<output_iterator_tag, void,void,void,void>
00117 {
00118 public:
00119   explicit back_insert_iterator(pqxx::TableWriter &W) : m_Writer(W) {}
00120 
00121   template<typename TUPLE> 
00122   back_insert_iterator &operator=(const TUPLE &T)
00123   {
00124     m_Writer.insert(T);
00125     return *this;
00126   }
00127 
00128   back_insert_iterator &operator++() { return *this; }
00129   back_insert_iterator &operator++(int) { return *this; }
00130   back_insert_iterator &operator*() { return *this; }
00131 
00132 private:
00133   pqxx::TableWriter &m_Writer;
00134 };
00135 
00136 } // namespace
00137 
00138 
00139 namespace pqxx
00140 {
00141 
00142 #ifndef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
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 #endif
00162 
00163 
00164 inline void TableWriter::FieldConverter::Escape(PGSTD::string &S)
00165 {
00166   const char Special[] = "\n\t\\";
00167 
00168   for (PGSTD::string::size_type j = S.find_first_of(Special);
00169        j != PGSTD::string::npos;
00170        j = S.find_first_of(Special, j+2))
00171     S.insert(j, 1, '\\');
00172 }
00173 
00174 
00175 template<typename IT> 
00176 inline PGSTD::string TableWriter::ezinekoT(IT Begin, IT End) const
00177 {
00178   PGSTD::string Line = PGSTD::accumulate(Begin, 
00179                                          End, 
00180                                          PGSTD::string(), 
00181                                          FieldConverter(NullStr()));
00182 
00183   // Above algorithm generates one separating tab too many.  Take it back.
00184   if (!Line.empty()) Line.erase(Line.size()-1);
00185 
00186   return Line;
00187 }
00188 
00189 
00190 template<typename TUPLE> 
00191 inline PGSTD::string TableWriter::ezinekoT(const TUPLE &T) const
00192 {
00193   return ezinekoT(T.begin(), T.end());
00194 }
00195 
00196 
00197 template<typename IT> inline void TableWriter::insert(IT Begin, IT End)
00198 {
00199   WriteRawLine(ezinekoT(Begin, End));
00200 }
00201 
00202 
00203 template<typename TUPLE> inline void TableWriter::insert(const TUPLE &T)
00204 {
00205   insert(T.begin(), T.end());
00206 }
00207 
00208 template<typename IT> 
00209 inline void TableWriter::push_back(IT Begin, IT End)
00210 {
00211   insert(Begin, End);
00212 }
00213 
00214 template<typename TUPLE> 
00215 inline void TableWriter::push_back(const TUPLE &T)
00216 {
00217   insert(T.begin(), T.end());
00218 }
00219 
00220 template<typename TUPLE> 
00221 inline TableWriter &TableWriter::operator<<(const TUPLE &T)
00222 {
00223   insert(T);
00224   return *this;
00225 }
00226 
00227 }
00228 
00229 #endif
00230 

Generated on Fri Feb 28 19:23:32 2003 for libpqxx by doxygen1.3-rc3