// // EyeDB.h // ionuCommon // // Created by Frank Vernon on 1/16/14. // Copyright (c) 2013-2014 IONU Security. All rights reserved. // #ifndef __com_ionu_eyedb__ #define __com_ionu_eyedb__ #ifndef LIBEYE_DLL #ifdef WIN32 # ifdef DLLEXPORT # define LIBEYE_DLL __declspec(dllexport) # else # define LIBEYE_DLL __declspec(dllimport) # endif #else #define LIBEYE_DLL #endif #endif #include #include #include #include #include #include "sqlite/sqlite3.h" namespace sequencelogic { typedef std::map STRING_STRING_MAP; typedef std::vector MAP_VECTOR; /** Functor class to sort MAP_VECTORs based on an arbitrary field common to all maps */ class MapVectorSortFunctor { public: MapVectorSortFunctor(const std::string & key, bool sortAscending) :_key(key), _ascending(sortAscending) {} bool operator() (const STRING_STRING_MAP& lhs, const STRING_STRING_MAP& rhs) { STRING_STRING_MAP::const_iterator left = lhs.find(_key); STRING_STRING_MAP::const_iterator right = rhs.find(_key); if(left != lhs.end() && right != rhs.end()) { if (_ascending) { return left->second < right->second; } else { return left->second > right->second; } } return false; } private: const std::string _key; bool _ascending; }; /** Functor class to find object in MAP_VECTORs based on an arbitrary field common to all maps */ struct MapVectorFindFunctor: std::unary_function { explicit MapVectorFindFunctor(const std::string& key, const std::string& val) : _key(key), _value(val) {} bool operator() (const STRING_STRING_MAP& obj) { STRING_STRING_MAP::const_iterator it = obj.find(_key); if (it != obj.end()) { return it->second == _value; } return false; } private: const std::string _key; const std::string _value; }; class statement; //forward reference /** EyeDB - pure virutal base class for database operations. Manages open/close on db (RAII), implements common query functionality, has pure virtual method to create required table(s) for base classes */ class LIBEYE_DLL EyeDB { public: EyeDB(); virtual ~EyeDB(); /** Open a database on this object @param file - platform appropriate path to db file @returns bool - success/fail */ virtual bool open(const char * file); /** Close database file - called on destructor if necessary */ virtual void close(); /** Execute a query @param query - query to execute, no bindings @returns bool - success/fail */ virtual bool executeQuery(const std::string & query); /** Execute query and return results @param statement - statement to excute @returns MAP_VECTOR - vector of maps:column->value (std::string->std::string) vector retains order of result set */ MAP_VECTOR fetchResults(const statement & statement); operator sqlite3*() const { return _db; } /** Get name of the file backing the database @returns absolute path to the database file */ std::string filePath(); bool isOpen() { return _db_open; } /** Set the length of time to wait for busy conflicts. This value can be set before the database is opened. @param timeoutSeconds - time in seconds */ void busyTimeout(double timeoutSeconds); /** Get the length of time to wait for busy conflicts. @returns time in seconds */ double busyTimeout() { return _busy_timeout_seconds; } protected: sqlite3* _db; bool _db_open; double _busy_timeout_seconds; }; /** transaction - RAII class for transaction support on sqlite */ class LIBEYE_DLL transaction { public: transaction(EyeDB & db); ~transaction(); void commit(); protected: bool _commit; EyeDB & _db; }; /** savepoint - RAII class for savepoint support on sqlite */ class LIBEYE_DLL savepoint { public: savepoint(EyeDB & db, const char * savepoint); ~savepoint(); void commit(); #if defined(WIN32) || defined(_WIN32) #pragma warning(push) #pragma warning(disable:4251 4275) // Disable the dumbass XXXX needs to have dll-interface. #endif protected: bool _commit; EyeDB & _db; std::string _savepoint; #if defined(WIN32) || defined(_WIN32) #pragma warning(pop) #endif }; /** statement - RAII class for statement support on sqlite. Class supports prepare, bind, and step directly. finalize is called on destructor. */ class LIBEYE_DLL statement { public: sqlite3_stmt * stmt; statement(); statement(EyeDB & db, const std::string & query); ~statement(); /** prepare query for execution or further binding @param db - database to prepare query on @param query - query to prepare @returns bool - success/fail */ bool prepare(EyeDB & db, const std::string & query); /** bind variables on the statement @param position - variable position in query @param value - value to bind to variable on query @returns bool - success/fail */ bool bind(int position, int integer); bool bind(int position, sqlite3_int64 integer64); bool bind(int position, double dbl); bool bind(int position, const std::string & text); bool bind(int position, const void * blob, int blobLength); bool bind(int position, const sqlite3_value * value); bool bind_null(int position); bool bind_zeroblob(int position, int n); /** Clear bindings to ready for resuse @returns bool - success/fail */ bool clear_bindings() const; /** step (execute) next iteration of query @returns int - sqlite return value appropriate to query */ int step() const; /** reset statement. reset for re-execution */ bool reset() const; /** column type @param column - column position @returns int column type */ int columnType(int column); /** column sizes @param column - column position @returns value appropriate to column type */ double columnBytesDouble(int column); int columnBytesInt(int column); int columnBytesInt16(int column); /** column values @param column - column position @returns value appropriate to column type */ const void * columnBlob(int column); int columnInt(int column); sqlite_int64 columnInt64(int column); const unsigned char * columnText(int column); sqlite3_value * columnValue(int column); const void * columnText16(int column); /** finalize (release) statement. called on destructor if prepared */ void finalize(); operator sqlite3_stmt *() const { return stmt; } /** get state of statement @param n/a @returns bool - true if statement is prepared for binding/execution */ bool isPrepared(); protected: bool prepared; }; /** PragmaAccess - get/set SQLite pragma values at runtime */ class LIBEYE_DLL PragmaAccess { public: PragmaAccess(EyeDB & db); /** get the runtime value of a SQLite pragma @param pragma - the name of the pragma @returns result as string */ std::string get(const std::string & pragma); /** set the runtime value of a SQLite pragma @param pragma - the name of the pragma @param value - the new value of the pragma @returns bool - success/fail */ bool set(const std::string & pragma, const std::string & value); protected: EyeDB & _db; }; } #endif /* defined(__ionuCommon__EyeDB__) */