The main method itself looks very similar to the one shown in the selectrow.cc example. The only difference is the additional command line parameter and the PrintFetcher class.
You can compile this example with the following command:
c++ -I../ -L../.libs -lResourcePool -lrt -o select select.cc
To gain a better understanding what is happening in the background, you may choose to enable all logging:
export FATALMIND_DEFAULT_LOGEVENTS=ALL
Unfortunately this example shows also a limitation:
00001 #include <iostream> 00002 #include <iomanip> 00003 #include <sstream> 00004 #include <iterator> 00005 #include "ResourcePool/ResourcePoolStreamLogger.hh" 00006 #include "ResourcePool/SQL/ResourcePool.hh" 00007 /* define the resource type to use */ 00008 typedef fatalmind::ResourcePool<fatalmind::ResourceType::SQL> RP; 00009 00010 using fatalmind::ResourcePoolOptions; 00011 using fatalmind::ResourcePoolStreamLogger; 00012 00013 int parseString(char*); 00014 00015 class PrintFetcher: public fatalmind::SQL::SQLFetcher { 00016 struct columnDescriptor { 00017 std::string value; 00018 bool isnull; 00019 int width; 00020 columnDescriptor() 00021 : value() 00022 , isnull(false) 00023 , width(0) 00024 { 00025 } 00026 }; 00027 00028 public: 00029 PrintFetcher(int c) 00030 : columns(c) 00031 , row(columns) 00032 { 00033 /* calls the string's default c-tor n-times */ 00034 row.resize(columns); 00035 }; 00036 00037 void bindout(fatalmind::SQL::BindOutInterface& cmd) { 00038 for (int i = 0; i < columns; ++i) { 00039 columnDescriptor& c = row[i]; 00040 cmd.bindout(i, c.value, c.isnull); 00041 } 00042 } 00043 00044 bool process(int rownum) { 00045 std::cout << "| "; 00046 row_t::const_iterator e = row.end(); 00047 for (row_t::iterator i = row.begin(); i != e; ++i) { 00048 columnDescriptor& c = *i; 00049 if (! c.isnull) { 00050 int len = c.value.length(); 00051 c.width = std::max(len, c.width); 00052 std::cout << std::setw(c.width) << c.value << " | "; 00053 } else { 00054 std::cout << "| "; 00055 } 00056 } 00057 std::cout << std::endl; 00058 return true; 00059 } 00060 00061 void done(bool more, int fetched) { 00062 std::cout << std::endl << (more ? "": "all ") << fetched << " row" << (fetched != 1 ? "s":"") << " fetched." <<std::endl << std::endl; 00063 } 00064 private: 00065 int columns; 00066 typedef std::vector<columnDescriptor> row_t; 00067 row_t row; 00068 }; 00069 00070 int main(int argc, char* argv[]) { 00071 try { 00072 if (argc < 4) { /* just some minimalistic checking */ 00073 throw fatalmind::Exception("arguments missing: driver:logon no-columns SQL"); 00074 } 00075 ResourcePoolStreamLogger logger(std::cerr); /* log events to std::cerr */ 00076 RP::Factory f(argv[1], logger); /* pass the arguments to the factory */ 00077 RP p(f, ResourcePoolOptions::defaultOptions); /* create a resource pool */ 00078 /* Use the default options, but a custom logger */ 00079 /* Initialize a PrintFetcher for the specified number of columns */ 00080 PrintFetcher fetch(parseString(argv[2])); 00081 /* pass the SQL and the Fetcher to the SQLSelect class */ 00082 RP::Commands::SQLSelect select(p, argv[3], fetch); 00083 fetch.bindout(select); /* let the PrintFetcher bind the output parameters */ 00084 00085 p.execute(select); /* execute the SQL */ 00086 } catch (fatalmind::Exception e) { /* if you provide missing/wrong data */ 00087 std::cout << "An error happend: " << e.message() << std::endl; 00088 } 00089 } 00090 00091 int parseString(char* param) { 00092 std::istringstream is(param); 00093 int rv; 00094 is >> rv; 00095 if (is.fail() || rv < 1) { 00096 throw fatalmind::Exception("Illegal argument (need numeric number of columns)"); 00097 } 00098 return rv; 00099 }