/home/martin/workspace/OpenStreetNav/src/psql/Cursor.h
Go to the documentation of this file.
00001 /*
00002  * Cursor.h
00003  *
00004  *  Created on: Jan 12, 2012
00005  *      Author: martin
00006  */
00007 
00008 #ifndef PSQLCURSOR_H_
00009 #define PSQLCURSOR_H_
00010 
00011 namespace psql
00012 {
00013 
00014 class ICursor
00015 {
00016 };
00017 
00024 template<typename BTypes, typename RTypes>
00025 class Cursor : ICursor
00026 {
00027 public:
00034     Cursor(Database& db, std::string const& name, Statement<BTypes, RTypes> const& s):
00035         db(&db),
00036         name(name),
00037         decl_curs("DECLARE " + name + " CURSOR FOR " + s.get_sql(), db),
00038         close_curs("CLOSE " + name, db),
00039         opened(false)
00040     {
00041     }
00047     template<typename... Args>
00048     void open(Args... a)
00049     {
00050         if (db == NULL)
00051             throw PgSqlException("You can't call open on empty cursor");
00052         decl_curs.execute(a...);
00053         db->add_cursor(this);
00054         opened = true;
00055     }
00056 
00061     std::vector<typename RTypes::RowType> const& get_buffer()
00062     {
00063         return buffer;
00064     }
00065 
00070     void fetch(int count)
00071     {
00072         if (!opened)
00073             throw PgSqlException("You need to open cursor prior to fetching");
00074         Statement<BindTypes<>, RTypes > st(util::concatenate(" ", "FETCH", count, "FROM", name), *db);
00075         buffer = exec_statement(st);
00076     }
00077     virtual ~Cursor()
00078     {
00079         close();
00080     }
00081     Cursor(Cursor const&) = delete;
00082     Cursor& operator=(Cursor const&) = delete;
00086     Cursor():
00087         db(NULL),
00088         opened(false)
00089     {
00090     }
00095     Cursor(Cursor && other):
00096         db(NULL),
00097         opened(false)
00098     {
00099         *this = std::move(other);
00100     }
00106     Cursor& operator=(Cursor && other)
00107     {
00108         if (this == &other)
00109             return *this;
00110         close();
00111         decl_curs = std::move(other.decl_curs);
00112         close_curs = std::move(other.close_curs);
00113         name = std::move(other.name);
00114         db = other.db;
00115         other.db = NULL;
00116         opened = other.opened;
00117         buffer = std::move(other.buffer);
00118         return *this;
00119     }
00120 
00124     void close()
00125     {
00126         if (db != NULL && opened && db->in_transaction() && db->is_cursor(this))
00127         {
00128             close_curs.execute();
00129             db->remove_cursor(this);
00130         }
00131         opened = false;
00132     }
00133 private:
00134     Database* db;
00135     std::string name;
00136     Statement<BTypes, RetTypes<> > decl_curs;
00137     Statement<BindTypes<>, RetTypes<> > close_curs;
00138     std::vector<typename RTypes::RowType> buffer;
00139     bool opened;
00140 };
00141 
00150 template<typename BTypes, typename RTypes>
00151 Cursor<BTypes, RTypes> make_cursor(Database& db, std::string const& name, Statement<BTypes, RTypes> const& st)
00152 {
00153     return Cursor<BTypes, RTypes>(db, name, st);
00154 }
00155 
00156 } /* namespace psql */
00157 #endif /* PSQLCURSOR_H_ */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines