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

Generated on Sat Aug 10 21:52:38 2002 for libpqxx by doxygen1.2.16