00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef PQXX_TABLEWRITER_H
00019 #define PQXX_TABLEWRITER_H
00020
00021 #include "pqxx/config.h"
00022
00023 #include <numeric>
00024 #include <string>
00025
00026 #include "pqxx/tablestream.h"
00027
00028
00029
00030
00031
00032 namespace pqxx
00033 {
00034 class tablereader;
00035
00037
00046 class PQXX_LIBEXPORT tablewriter : public tablestream
00047 {
00048 public:
00049 typedef unsigned size_type;
00050
00051 tablewriter(transaction_base &Trans, const PGSTD::string &WName);
00052 ~tablewriter();
00053
00054 template<typename IT> void insert(IT Begin, IT End);
00055 template<typename TUPLE> void insert(const TUPLE &);
00056 template<typename IT> void push_back(IT Begin, IT End);
00057 template<typename TUPLE> void push_back(const TUPLE &);
00058
00059 void reserve(size_type) {}
00060
00061 template<typename TUPLE> tablewriter &operator<<(const TUPLE &);
00062
00063
00064 tablewriter &operator<<(tablereader &);
00065
00068 template<typename IT> PGSTD::string ezinekoT(IT Begin, IT End) const;
00069 template<typename TUPLE> PGSTD::string ezinekoT(const TUPLE &) const;
00070
00071 private:
00072 void WriteRawLine(const PGSTD::string &);
00073
00074 class PQXX_LIBEXPORT fieldconverter
00075 {
00076 public:
00077 fieldconverter(const PGSTD::string &N) : Null(N) {}
00078
00079 template<typename T> PGSTD::string operator()(const PGSTD::string &S,
00080 T i) const
00081 {
00082 PGSTD::string Field(ToString(i));
00083 return S + ((Field == Null) ? PGNull() : Field);
00084 }
00085
00086 #ifdef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00087 template<> PGSTD::string operator()(const PGSTD::string &S,
00088 PGSTD::string i) const;
00089 #endif
00090
00091 PGSTD::string operator()(const PGSTD::string &S, const char *i) const;
00092
00093 private:
00094 static PGSTD::string PGNull() { return "\\N"; }
00095 static void Escape(PGSTD::string &);
00096 PGSTD::string Null;
00097 };
00098 };
00099
00101 typedef tablewriter TableWriter;
00102
00103 }
00104
00105
00106 namespace PGSTD
00107 {
00108
00109
00110 template<>
00111 class PQXX_LIBEXPORT back_insert_iterator<pqxx::tablewriter> :
00112 public iterator<output_iterator_tag, void,void,void,void>
00113 {
00114 public:
00115 explicit back_insert_iterator(pqxx::tablewriter &W) : m_Writer(W) {}
00116
00117 template<typename TUPLE>
00118 back_insert_iterator &operator=(const TUPLE &T)
00119 {
00120 m_Writer.insert(T);
00121 return *this;
00122 }
00123
00124 back_insert_iterator &operator++() { return *this; }
00125 back_insert_iterator &operator++(int) { return *this; }
00126 back_insert_iterator &operator*() { return *this; }
00127
00128 private:
00129 pqxx::tablewriter &m_Writer;
00130 };
00131
00132 }
00133
00134
00135 namespace pqxx
00136 {
00137
00138 template<>
00139 inline PGSTD::string
00140 tablewriter::fieldconverter::operator()(const PGSTD::string &S,
00141 PGSTD::string i) const
00142 {
00143 if (i == Null) i = PGNull();
00144 else Escape(i);
00145 return S + i + '\t';
00146 }
00147
00148
00149 inline PGSTD::string
00150 tablewriter::fieldconverter::operator()(const PGSTD::string &S,
00151 const char *i) const
00152 {
00153 return operator()(S, PGSTD::string(i));
00154 }
00155
00156
00157 inline void tablewriter::fieldconverter::Escape(PGSTD::string &S)
00158 {
00159 const char Special[] = "\n\t\\";
00160
00161 for (PGSTD::string::size_type j = S.find_first_of(Special);
00162 j != PGSTD::string::npos;
00163 j = S.find_first_of(Special, j+2))
00164 S.insert(j, 1, '\\');
00165 }
00166
00167
00168 template<typename IT>
00169 inline PGSTD::string tablewriter::ezinekoT(IT Begin, IT End) const
00170 {
00171 PGSTD::string Line = PGSTD::accumulate(Begin,
00172 End,
00173 PGSTD::string(),
00174 fieldconverter(NullStr()));
00175
00176
00177 if (!Line.empty()) Line.erase(Line.size()-1);
00178
00179 return Line;
00180 }
00181
00182
00183 template<typename TUPLE>
00184 inline PGSTD::string tablewriter::ezinekoT(const TUPLE &T) const
00185 {
00186 return ezinekoT(T.begin(), T.end());
00187 }
00188
00189
00190 template<typename IT> inline void tablewriter::insert(IT Begin, IT End)
00191 {
00192 WriteRawLine(ezinekoT(Begin, End));
00193 }
00194
00195
00196 template<typename TUPLE> inline void tablewriter::insert(const TUPLE &T)
00197 {
00198 insert(T.begin(), T.end());
00199 }
00200
00201 template<typename IT>
00202 inline void tablewriter::push_back(IT Begin, IT End)
00203 {
00204 insert(Begin, End);
00205 }
00206
00207 template<typename TUPLE>
00208 inline void tablewriter::push_back(const TUPLE &T)
00209 {
00210 insert(T.begin(), T.end());
00211 }
00212
00213 template<typename TUPLE>
00214 inline tablewriter &tablewriter::operator<<(const TUPLE &T)
00215 {
00216 insert(T);
00217 return *this;
00218 }
00219
00220 }
00221
00222 #endif
00223