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