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