00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string>
00020
00021 #include "pqxx/result"
00022 #include "pqxx/tablestream"
00023
00024
00025
00026
00027
00028 namespace pqxx
00029 {
00030
00032
00044 class PQXX_LIBEXPORT tablereader : public tablestream
00045 {
00046 public:
00047 tablereader(transaction_base &, const PGSTD::string &RName);
00048 ~tablereader();
00049
00050 template<typename TUPLE> tablereader &operator>>(TUPLE &);
00051
00052 operator bool() const throw () { return !m_Done; }
00053 bool operator!() const throw () { return m_Done; }
00054
00056
00059 bool get_raw_line(PGSTD::string &Line);
00060
00061 template<typename TUPLE>
00062 void tokenize(PGSTD::string, TUPLE &) const;
00063
00064
00065 #ifdef PQXX_DEPRECATED_HEADERS
00066
00067 bool GetRawLine(PGSTD::string &L) { return get_raw_line(L); }
00069 template<typename TUPLE> void Tokenize(PGSTD::string L, TUPLE &T) const
00070 { tokenize(L, T); }
00071 #endif
00072
00073 private:
00074 bool m_Done;
00075 };
00076
00077
00078 }
00079
00080
00081
00082
00083 template<typename TUPLE>
00084 inline void pqxx::tablereader::tokenize(PGSTD::string Line,
00085 TUPLE &T) const
00086 {
00087 PGSTD::back_insert_iterator<TUPLE> ins = PGSTD::back_inserter(T);
00088
00089
00090 PGSTD::string::size_type token = 0;
00091 for (PGSTD::string::size_type i=0; i < Line.size(); ++i)
00092 {
00093 switch (Line[i])
00094 {
00095 case '\t':
00096 *ins++ = PGSTD::string(Line, token, i-token);
00097 token = i+1;
00098 break;
00099
00100 case '\\':
00101
00102 if ((i+1) >= Line.size())
00103 throw PGSTD::runtime_error("Row ends in backslash");
00104
00105 switch (Line[i+1])
00106 {
00107 case 'N':
00108
00109 Line.replace(i, 2, NullStr());
00110 i += NullStr().size() - 1;
00111 break;
00112
00113 case 't':
00114 Line.replace(i++, 2, "\t");
00115 break;
00116
00117 case 'n':
00118 Line.replace(i++, 2, "\n");
00119 break;
00120
00121 case 'r':
00122 Line.replace(i++, 2, "\r");
00123 break;
00124
00125
00126
00127 default:
00128 Line.erase(i, 1);
00129 }
00130 break;
00131 }
00132 }
00133
00134 *ins++ = PGSTD::string(Line, token);
00135 }
00136
00137
00138 template<typename TUPLE>
00139 inline pqxx::tablereader &pqxx::tablereader::operator>>(TUPLE &T)
00140 {
00141 PGSTD::string Line;
00142 if (get_raw_line(Line)) tokenize(Line, T);
00143 return *this;
00144 }
00145
00146