#pragma once

#ifndef _RECORD_FETCHER_H_INCLUDED_
#define _RECORD_FETCHER_H_INCLUDED_

#include <Poco/Data/Statement.h>
#include <Poco/Data/RecordSet.h>
#include <Poco/DynamicAny.h>

#include "session.h"

namespace NWebmaster {

// Simple db record fertcher. Simplifies use of Poco::RecordSet
//
// Example:
//     Statement select(fSession);
//     select << "SELECT id, name FROM ...", limit(100);
//     RecordFetcher rf(select);
//     while (rf.hasValue()) {
//         Poco::Int64 id = rf[0].convert<Poco::Int64>();
//         std::string name = rf[1].convert<std::string>();
//         ...
//         rf.moveNext();
//     }

class RecordFetcher {
public:

    RecordFetcher(Poco::Data::Statement &_stmt) : stmt(_stmt), rs(nullptr), more(false) {
    }

    ~RecordFetcher() {
        delete rs;
    }

    bool hasValue() {
        if(!rs) {
            stmt.execute();
            rs = new Poco::Data::RecordSet(stmt);
            more = rs->moveFirst();
        }
        return more;
    }

    void moveNext() {
        if(!hasValue()) {
            return;
        }
        more = rs->moveNext();
        if (!more && !stmt.done()) {
            stmt.execute();
            more = rs->moveFirst();
        }
    }

    Poco::DynamicAny operator [] (const std::string &name) {
        return (*rs)[name];
    }

    Poco::DynamicAny operator [] (std::size_t index) {
        return (*rs)[index];
    }

private:
    Poco::Data::Statement &stmt;
    Poco::Data::RecordSet *rs;
    bool more;
};


} // namespace NWebmaster

#endif
