00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00026
00027
00028 namespace pqxx
00029 {
00030 class TableReader;
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);
00048 ~TableWriter();
00049
00050 template<typename IT> void insert(IT Begin, IT End);
00051 template<typename TUPLE> void insert(const TUPLE &);
00052 template<typename IT> void push_back(IT Begin, IT End);
00053 template<typename TUPLE> void push_back(const TUPLE &);
00054
00055 void reserve(size_type) {}
00056
00057 template<typename TUPLE> TableWriter &operator<<(const TUPLE &);
00058
00059
00060 TableWriter &operator<<(TableReader &);
00061
00064 template<typename IT> PGSTD::string ezinekoT(IT Begin, IT End) const;
00065 template<typename TUPLE> PGSTD::string ezinekoT(const TUPLE &) const;
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
00114
00115 template<> class back_insert_iterator<pqxx::TableWriter> :
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 }
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
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