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).

Unfortunately this example shows also a few limitations.

#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#include "ResourcePool/SQL/ResourcePool.hh"
                                          /* define the resource type to use */
typedef fatalmind::ResourcePool<fatalmind::ResourceType::SQL> RP;

int parseString(char*);

class PrintFetcher: public fatalmind::SQL::SQLFetcher {
    struct columnDescriptor {
        std::string value;
        bool        isnull;
        int         width;
    };

    public:
        PrintFetcher(int c) 
        : columns(c)
        , row(columns)
        {
            /* calls the string's default c-tor n-times */
            row.resize(columns);
        };

        void bindout(RP::Command::SQLSelect& cmd) {
            for (int i = 0; i < columns; ++i) {
                columnDescriptor& c = row[i];
                cmd.bindout(i, c.value, c.isnull);
            }
        }

        bool process(int rownum) {
            std::cout << "|  ";
            row_t::const_iterator e = row.end();    
            for (row_t::iterator i = row.begin(); i != e; ++i) {
                columnDescriptor c = *i;
                if (! c.isnull) {
                    int len = c.value.length();
                    c.width = std::max(len, c.width);
                    std::cout << std::setw(c.width) << c.value << "  |  ";
                } else {
                    std::cout << "|  ";
                }
            }
            std::cout << std::endl;
            return true;
        }

        void done(bool more, int fetched) {
            std::cout << std::endl << (more ? "": "all ") << fetched << " row" << (fetched != 1 ? "s":"") << " fetched." <<std::endl << std::endl;
        }
    private:
        int columns;
        typedef std::vector<columnDescriptor> row_t;
        row_t row;
};

int main(int argc, char* argv[]) {
    try {
        if (argc < 4) {                   /* just some minimalistic checking */
            throw fatalmind::Exception("arguments missing: driver:logon no-columns SQL");
        }
        RP::Factory f(argv[1]);           /* pass the arguments to the factory */
        RP p(f);                          /* create a resource pool */
                          /* Initialize a PrintFetcher for the specified number of columns */
        PrintFetcher fetch(parseString(argv[2]));
                          /* pass the SQL and the Fetcher to the SQLSelect class */ 
        RP::Command::SQLSelect select(p, argv[3], fetch);
        fetch.bindout(select);            /* let the PrintFetcher bind the output parameters */
    
        p.execute(select);                /* execute the SQL */
    } catch (fatalmind::Exception e) {    /* if you provide missing/wrong data */
        std::cout << "An error happend: " << e.message() << std::endl;
    }
}

int parseString(char* param) {
    std::istringstream is(param);
    int rv;
    is >> rv;
    if (is.fail() || rv < 1) {
        throw fatalmind::Exception("Illegal argument (need numeric number of columns)");
    }
    return rv;
}

Generated on Mon Jun 9 11:27:00 2008 for ResourcePool by  doxygen 1.5.5