Mercurial > code
view C++/Driver.h @ 189:cc1e5fe1ee2c
Update drivers to style and using instead of typedefs
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 26 Nov 2013 20:36:59 +0100 |
parents | 4c746050969a |
children | d263f85f43a4 |
line wrap: on
line source
/* * Driver.h -- generic SQL driver access * * Copyright (c) 2013, David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _DRIVER_H_ #define _DRIVER_H_ #include <iostream> #include <memory> #include <string> #include <unordered_map> #include "Date.h" /** * @enum ColumnType * @brief The column type request * * Used for the drivers. */ enum class ColumnType { Invalid, //! not found Boolean, //! bool or 0 / 1 Date, //! date see Common/Date.h Double, //! double Integer, //! 32 or 64 bit int String, //! varchar to std::string }; /** * @class Query * @brief Class for querying the database * * That class is returned when a SQL query succeed. It can retrieve the * number of rows, columns and retrieve the results independantly from the * driver. * * @see Driver::query */ class Query { public: using Ptr = std::shared_ptr<Query>; /** * @class Error * @brief Query exception on query error */ class Error : public std::exception { private: std::string m_error; public: Error(const std::string &error); virtual const char *what() const throw(); }; private: /** * Check if the request is valid and throws an exception * on error. * * @param row the row number * @param column the column name * @param type * @throw Error on error */ void assertRequest(int row, const std::string &column, ColumnType type); protected: /** * Get a bool. * * @param row the row number * @param column the column * @return the value */ virtual bool getBoolean(int row, const std::string &column) = 0; /** * Get a Date. * * @param row the row number * @param column the column * @return the value */ virtual Date getDate(int row, const std::string &column) = 0; /** * Get a double. * * @param row the row number * @param column the column * @return the value */ virtual double getDouble(int row, const std::string &column) = 0; /** * Get a integer. * * @param row the row number * @param column the column * @return the value */ virtual int getInt(int row, const std::string &column) = 0; /** * Get a string. * * @param row the row number * @param column the column * @return the value */ virtual std::string getString(int row, const std::string &column) = 0; public: /** * Default destructor. */ virtual ~Query(); /** * Get a variable from a row and column. * * Specialization available: * - bool * - Date * - double * - int * - std::string * * @param row the row number (starts from 0) * @param column the the column name * @return the value */ template <class T> T get(int row, const std::string &column); /** * Returns the type of a named column. * * @param column the column name * @return the type */ virtual ColumnType type(const std::string &column) const = 0; /** * Tells how many rows has been fetched. * * @return the number of rows */ virtual int countRows() = 0; /** * Tells how many number of columns are present for each * row. * * @return the number of columns */ virtual int countColumns() = 0; /** * Tells if the column is null or not. * * @param row the row number * @param column the column * @return an true if null */ virtual bool isNull(int row, const std::string &column) = 0; /** * Dump all rows and columns. */ virtual void dump() = 0; }; /** * @class Request * @brief A secure helper for creating requests * * This helps creating class with SQL injection security and such. */ class Request { public: friend class Driver; using Ptr = std::shared_ptr<Request>; private: size_t m_pos; int m_params; std::string m_command; void assertCorrect(); void setValue(const std::string &value); protected: /** * Bind a boolean. * * @param value the boolean * @return the string to use */ virtual std::string bindBoolean(bool value) = 0; /** * Bind a date. * * @param value the date * @return the string to use */ virtual std::string bindDate(Date value) = 0; /** * Bind a double. * * @param value the double * @return the string to use */ virtual std::string bindDouble(double value) = 0; /** * Bind an integer. * * @param value the integer * @return the string to use */ virtual std::string bindInt(int value) = 0; /** * Bind a string. * * @param value the string * @return the string to use */ virtual std::string bindString(std::string value) = 0; /** * Default constructor with SQL command. * * @param command the SQL command */ Request(const std::string &command); public: /** * Default destructor. */ virtual ~Request(); /** * Bind a value. * * @param value the value */ template <typename T> void bind(T value); /** * Convert the request to string. * * @return the request as a string */ operator std::string(); }; /** * @class Driver * @brief A generic SQL driver * * This class is used to connect to a database and execute SQL queries. It * does not include any DBMS code and just call virtual functions for * a simpler integration of new DBMS drivers. */ class Driver : public std::enable_shared_from_this<Driver> { protected: std::string m_error; /** * Default constructor. Should not be used. * * @see Driver::create */ Driver(); public: using Params = std::unordered_map<std::string, std::string>; using Ptr = std::shared_ptr<Driver>; /** * Create a new Driver object, some queries need to do additional * internal requests so it's easier to use shared_ptr. * * @return a shared_ptr */ template <class T> static Ptr create() { T *t = new T(); return std::shared_ptr<T>(t); } /** * Virtual destructor. */ virtual ~Driver(); /** * Get the error. * * @return the error */ const std::string &getError() const; /** * Wrapper for std::string variant. * * @param request the request to use * @return a result * @throw Query::Exception on failure */ Query::Ptr query(Request::Ptr request); /** * Create a synchronous connection, it waits and block until * the connection is made up to a specified timeout max. * * @param params a list of parameters. */ virtual bool connect(const Params ¶ms) = 0; /** * Prepare a request with the specified SQL command. * * @param command the SQL command to parse and bind * @return a request to use with query * @see query */ virtual Request::Ptr prepare(const std::string &command) = 0; /** * Execute a query. * * @param query the SQL command * @return a result * @throw Query::Exception on failure */ virtual Query::Ptr query(const std::string &command) = 0; /** * Get the driver connection description. * * @return the description */ virtual std::string description() const = 0; /** * Get the driver version as a string. * * @return the version */ virtual std::string version() const = 0; }; #endif // !_DRIVER_H_