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 namespace pqxx
00031 {
00032 class tablereader;
00033
00035
00044 class PQXX_LIBEXPORT tablewriter : public tablestream
00045 {
00046 public:
00047 typedef unsigned size_type;
00048
00049 tablewriter(transaction_base &Trans, const PGSTD::string &WName);
00050 ~tablewriter();
00051
00052 template<typename IT> void insert(IT Begin, IT End);
00053 template<typename TUPLE> void insert(const TUPLE &);
00054 template<typename IT> void push_back(IT Begin, IT End);
00055 template<typename TUPLE> void push_back(const TUPLE &);
00056
00057 void reserve(size_type) {}
00058
00059 template<typename TUPLE> tablewriter &operator<<(const TUPLE &);
00060
00061
00062 tablewriter &operator<<(tablereader &);
00063
00064 #ifdef PQXX_DEPRECATED_HEADERS
00065
00066 template<typename IT> PGSTD::string ezinekoT(IT Begin, IT End) const
00067 { return generate(Begin, End); }
00069 template<typename TUPLE> PGSTD::string ezinekoT(const TUPLE &T) const
00070 { return generate(T); }
00071 #endif
00072
00075 template<typename IT> PGSTD::string generate(IT Begin, IT End) const;
00076 template<typename TUPLE> PGSTD::string generate(const TUPLE &) const;
00077
00078
00079 private:
00080 void WriteRawLine(const PGSTD::string &);
00081
00082 class PQXX_LIBEXPORT fieldconverter
00083 {
00084 public:
00085 fieldconverter(const PGSTD::string &N) : Null(N) {}
00086
00087 template<typename T> PGSTD::string operator()(const PGSTD::string &S,
00088 T i) const
00089 {
00090 PGSTD::string Field(ToString(i));
00091 return S + ((Field == Null) ? PGNull() : Field);
00092 }
00093
00094 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00095 template<> PGSTD::string operator()(const PGSTD::string &S,
00096 PGSTD::string i) const;
00097 #endif
00098
00099 PGSTD::string operator()(const PGSTD::string &S, const char *i) const;
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<>
00116 class back_insert_iterator<pqxx::tablewriter> :
00117 public iterator<output_iterator_tag, void,void,void,void>
00118 {
00119 public:
00120 explicit back_insert_iterator(pqxx::tablewriter &W) : m_Writer(W) {}
00121
00122 template<typename TUPLE>
00123 back_insert_iterator &operator=(const TUPLE &T)
00124 {
00125 m_Writer.insert(T);
00126 return *this;
00127 }
00128
00129 back_insert_iterator &operator++() { return *this; }
00130 back_insert_iterator &operator++(int) { return *this; }
00131 back_insert_iterator &operator*() { return *this; }
00132
00133 private:
00134 pqxx::tablewriter &m_Writer;
00135 };
00136
00137 }
00138
00139
00140 namespace pqxx
00141 {
00142
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
00162 inline void tablewriter::fieldconverter::Escape(PGSTD::string &S)
00163 {
00164 const char Special[] = "\n\t\\";
00165
00166 for (PGSTD::string::size_type j = S.find_first_of(Special);
00167 j != PGSTD::string::npos;
00168 j = S.find_first_of(Special, j+2))
00169 S.insert(j, 1, '\\');
00170 }
00171
00172
00173 template<typename IT>
00174 inline PGSTD::string tablewriter::generate(IT Begin, IT End) const
00175 {
00176 PGSTD::string Line = PGSTD::accumulate(Begin,
00177 End,
00178 PGSTD::string(),
00179 fieldconverter(NullStr()));
00180
00181
00182 if (!Line.empty()) Line.erase(Line.size()-1);
00183
00184 return Line;
00185 }
00186
00187
00188 template<typename TUPLE>
00189 inline PGSTD::string tablewriter::generate(const TUPLE &T) const
00190 {
00191 return generate(T.begin(), T.end());
00192 }
00193
00194
00195 template<typename IT> inline void tablewriter::insert(IT Begin, IT End)
00196 {
00197 WriteRawLine(generate(Begin, End));
00198 }
00199
00200
00201 template<typename TUPLE> inline void tablewriter::insert(const TUPLE &T)
00202 {
00203 insert(T.begin(), T.end());
00204 }
00205
00206 template<typename IT>
00207 inline void tablewriter::push_back(IT Begin, IT End)
00208 {
00209 insert(Begin, End);
00210 }
00211
00212 template<typename TUPLE>
00213 inline void tablewriter::push_back(const TUPLE &T)
00214 {
00215 insert(T.begin(), T.end());
00216 }
00217
00218 template<typename TUPLE>
00219 inline tablewriter &tablewriter::operator<<(const TUPLE &T)
00220 {
00221 insert(T);
00222 return *this;
00223 }
00224
00225 }
00226
00227