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

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 #endif
00086 
00087     PGSTD::string operator()(const PGSTD::string &S, const char *i) const;
00088 
00089   private:
00090     static PGSTD::string PGNull() { return "\\N"; }
00091     static void Escape(PGSTD::string &);
00092     PGSTD::string Null;
00093   };
00094 };
00095 
00096 }
00097 
00098 
00099 namespace PGSTD
00100 {
00101 // Specialized back_insert_iterator for TableWriter, doesn't require a 
00102 // value_type to be defined.  Accepts any container type instead.
00103 template<> class back_insert_iterator<pqxx::TableWriter> :              //[t9]
00104         public iterator<output_iterator_tag, void,void,void,void>
00105 {
00106 public:
00107   explicit back_insert_iterator(pqxx::TableWriter &W) : m_Writer(W) {}
00108 
00109   template<typename TUPLE> 
00110   back_insert_iterator &operator=(const TUPLE &T)
00111   {
00112     m_Writer.insert(T);
00113     return *this;
00114   }
00115 
00116   back_insert_iterator &operator++() { return *this; }
00117   back_insert_iterator &operator++(int) { return *this; }
00118   back_insert_iterator &operator*() { return *this; }
00119 
00120 private:
00121   pqxx::TableWriter &m_Writer;
00122 };
00123 
00124 } // namespace
00125 
00126 
00127 namespace pqxx
00128 {
00129 
00130 template<>
00131 inline PGSTD::string 
00132 TableWriter::FieldConverter::operator()(const PGSTD::string &S,
00133                                         PGSTD::string i) const
00134 {
00135   if (i == Null) i = PGNull();
00136   else Escape(i);
00137   return S + i + '\t';
00138 }
00139 
00140 
00141 inline PGSTD::string
00142 TableWriter::FieldConverter::operator()(const PGSTD::string &S, 
00143                                         const char *i) const
00144 {
00145   return operator()(S, PGSTD::string(i));
00146 }
00147 
00148 
00149 inline void TableWriter::FieldConverter::Escape(PGSTD::string &S)
00150 {
00151   const char Special[] = "\n\t\\";
00152 
00153   for (PGSTD::string::size_type j = S.find_first_of(Special);
00154        j != PGSTD::string::npos;
00155        j = S.find_first_of(Special, j+2))
00156     S.insert(j, 1, '\\');
00157 }
00158 
00159 
00160 template<typename IT> 
00161 inline PGSTD::string TableWriter::ezinekoT(IT Begin, IT End) const
00162 {
00163   PGSTD::string Line = PGSTD::accumulate(Begin, 
00164                                          End, 
00165                                          PGSTD::string(), 
00166                                          FieldConverter(NullStr()));
00167 
00168   // Above algorithm generates one separating tab too many.  Take it back.
00169   if (!Line.empty()) Line.erase(Line.size()-1);
00170 
00171   return Line;
00172 }
00173 
00174 
00175 template<typename TUPLE> 
00176 inline PGSTD::string TableWriter::ezinekoT(const TUPLE &T) const
00177 {
00178   return ezinekoT(T.begin(), T.end());
00179 }
00180 
00181 
00182 template<typename IT> inline void TableWriter::insert(IT Begin, IT End)
00183 {
00184   WriteRawLine(ezinekoT(Begin, End));
00185 }
00186 
00187 
00188 template<typename TUPLE> inline void TableWriter::insert(const TUPLE &T)
00189 {
00190   insert(T.begin(), T.end());
00191 }
00192 
00193 template<typename IT> 
00194 inline void TableWriter::push_back(IT Begin, IT End)
00195 {
00196   insert(Begin, End);
00197 }
00198 
00199 template<typename TUPLE> 
00200 inline void TableWriter::push_back(const TUPLE &T)
00201 {
00202   insert(T.begin(), T.end());
00203 }
00204 
00205 template<typename TUPLE> 
00206 inline TableWriter &TableWriter::operator<<(const TUPLE &T)
00207 {
00208   insert(T);
00209   return *this;
00210 }
00211 
00212 }
00213 
00214 #endif
00215 

Generated on Mon Mar 17 22:59:04 2003 for libpqxx by doxygen1.3-rc3