select.cc

This examples expects a SQL select statement as well as the number of columns returned from that statement as argument and will fetch and print the result of the select statement to stdout. Since we need to fetch more then one row we must implement a SQLFetcher derivation. The PrintFetcher class from the example does so. It basically implements a process() which prints out the record's columns delimted by '|'.

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 
in the examples directory of the distribution (after building the library).

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 }

Generated on Mon Nov 9 16:21:24 2009 for ResourcePool by  doxygen 1.5.3