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(Transaction &Trans, PGSTD::string Name);
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(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
00090
00091 template<> class back_insert_iterator<pqxx::TableWriter> :
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
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
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