diff options
-rw-r--r-- | libodbcpp/odbc-bind.h | 13 | ||||
-rw-r--r-- | libodbcpp/odbc-column.cpp | 22 | ||||
-rw-r--r-- | libodbcpp/odbc-column.h | 349 | ||||
-rw-r--r-- | libodbcpp/odbc-command.cpp | 8 | ||||
-rw-r--r-- | libodbcpp/odbc-command.h | 58 | ||||
-rw-r--r-- | libodbcpp/odbc-connection.cpp | 37 | ||||
-rw-r--r-- | libodbcpp/odbc-connection.h | 59 | ||||
-rw-r--r-- | libodbcpp/odbc-dsn.cpp | 5 | ||||
-rw-r--r-- | libodbcpp/odbc-dsn.h | 13 | ||||
-rw-r--r-- | libodbcpp/odbc-error.cpp | 13 | ||||
-rw-r--r-- | libodbcpp/odbc-error.h | 14 | ||||
-rw-r--r-- | libodbcpp/odbc-mock.cpp | 47 | ||||
-rw-r--r-- | libodbcpp/odbc-mock.h | 12 | ||||
-rw-r--r-- | libodbcpp/odbc-modifycommand.cpp | 5 | ||||
-rw-r--r-- | libodbcpp/odbc-modifycommand.h | 11 | ||||
-rw-r--r-- | libodbcpp/odbc-param.cpp | 40 | ||||
-rw-r--r-- | libodbcpp/odbc-param.h | 390 | ||||
-rw-r--r-- | libodbcpp/odbc-param_fwd.h | 29 | ||||
-rw-r--r-- | libodbcpp/odbc-selectcommand.cpp | 60 | ||||
-rw-r--r-- | libodbcpp/odbc-selectcommand.h | 23 | ||||
-rw-r--r-- | libodbcpp/unittests/testodbc.cpp | 36 |
21 files changed, 782 insertions, 462 deletions
diff --git a/libodbcpp/odbc-bind.h b/libodbcpp/odbc-bind.h index 7a982e6..e1dd57f 100644 --- a/libodbcpp/odbc-bind.h +++ b/libodbcpp/odbc-bind.h @@ -6,15 +6,14 @@ namespace ODBC { class Bind { - public: - virtual ~Bind() = default; + public: + virtual ~Bind() = default; - virtual SQLSMALLINT ctype() const = 0; // The C type ID - virtual SQLULEN size() const = 0; // The size of the data - protected: - mutable SQLLEN bindLen; // How much data the driver wants to store + virtual SQLSMALLINT ctype() const = 0; // The C type ID + virtual SQLULEN size() const = 0; // The size of the data + protected: + mutable SQLLEN bindLen; // How much data the driver wants to store }; } #endif - diff --git a/libodbcpp/odbc-column.cpp b/libodbcpp/odbc-column.cpp index 2a25f9b..3d968c2 100644 --- a/libodbcpp/odbc-column.cpp +++ b/libodbcpp/odbc-column.cpp @@ -1,14 +1,12 @@ -#include <sqlext.h> -#include <cstdio> -#include <cstdlib> #include "odbc-column.h" #include "odbc-command.h" -#include "odbc-selectcommand.h" #include "odbc-error.h" +#include "odbc-selectcommand.h" +#include <cstdio> +#include <cstdlib> +#include <sqlext.h> -ODBC::Column::Column(SelectCommand * sc, const Glib::ustring & s, unsigned int i) : - DB::Column(s, i), - selectCmd(sc) +ODBC::Column::Column(SelectCommand * sc, const Glib::ustring & s, unsigned int i) : DB::Column(s, i), selectCmd(sc) { bindLen = 0; } @@ -51,14 +49,12 @@ ODBC::Column::bind() ODBC::TimeStampColumn::operator boost::posix_time::ptime() const { - return boost::posix_time::ptime( - boost::gregorian::date(data.year, data.month, data.day), - boost::posix_time::time_duration(data.hour, data.minute, data.second, data.fraction)); + return boost::posix_time::ptime(boost::gregorian::date(data.year, data.month, data.day), + boost::posix_time::time_duration(data.hour, data.minute, data.second, data.fraction)); } ODBC::IntervalColumn::operator boost::posix_time::time_duration() const { - auto dur = boost::posix_time::time_duration( - (24 * data.intval.day_second.day) + data.intval.day_second.hour, + auto dur = boost::posix_time::time_duration((24 * data.intval.day_second.day) + data.intval.day_second.hour, data.intval.day_second.minute, data.intval.day_second.second, data.intval.day_second.fraction); return (data.interval_sign ? -dur : dur); } @@ -84,7 +80,7 @@ ODBC::CharArrayColumn::apply(DB::HandleField & h) const if (isNull()) { return h.null(); } - h.string({ data.data(), (std::size_t)bindLen }); + h.string({data.data(), (std::size_t)bindLen}); } void ODBC::TimeStampColumn::apply(DB::HandleField & h) const diff --git a/libodbcpp/odbc-column.h b/libodbcpp/odbc-column.h index 5d7c7d4..4f3c697 100644 --- a/libodbcpp/odbc-column.h +++ b/libodbcpp/odbc-column.h @@ -1,130 +1,285 @@ #ifndef ODBC_COLUMN_H #define ODBC_COLUMN_H -#include <column.h> -#include <typeinfo> -#include <glibmm/ustring.h> -#include <algorithm> #include "odbc-bind.h" #include "odbc-param.h" +#include <algorithm> +#include <column.h> +#include <glibmm/ustring.h> +#include <typeinfo> namespace ODBC { class SelectCommand; class Column : public virtual Bind, public virtual DB::Column { - public: - Column(SelectCommand *, const Glib::ustring & s, unsigned int i); - virtual ~Column() = default; - void bind(); - virtual void * rwDataAddress() = 0; - virtual bool resize(); + public: + Column(SelectCommand *, const Glib::ustring & s, unsigned int i); + virtual ~Column() = default; + void bind(); + virtual void * rwDataAddress() = 0; + virtual bool resize(); + + virtual operator int() const + { + throw std::bad_cast(); + } + virtual operator long() const + { + throw std::bad_cast(); + } + virtual operator long long() const + { + throw std::bad_cast(); + } + virtual operator unsigned int() const + { + throw std::bad_cast(); + } + virtual operator unsigned long() const + { + throw std::bad_cast(); + } + virtual operator unsigned long long() const + { + throw std::bad_cast(); + } - virtual operator int () const { throw std::bad_cast(); } - virtual operator long () const { throw std::bad_cast(); } - virtual operator long long () const { throw std::bad_cast(); } - virtual operator unsigned int () const { throw std::bad_cast(); } - virtual operator unsigned long () const { throw std::bad_cast(); } - virtual operator unsigned long long () const { throw std::bad_cast(); } + virtual operator double() const + { + throw std::bad_cast(); + } + virtual operator float() const + { + throw std::bad_cast(); + } - virtual operator double () const { throw std::bad_cast(); } - virtual operator float () const { throw std::bad_cast(); } + virtual operator std::string() const + { + throw std::bad_cast(); + } + virtual operator Glib::ustring() const + { + throw std::bad_cast(); + } - virtual operator std::string () const { throw std::bad_cast(); } - virtual operator Glib::ustring () const { throw std::bad_cast(); } + virtual operator struct tm() const + { + throw std::bad_cast(); + } + virtual operator SQL_TIMESTAMP_STRUCT() const + { + throw std::bad_cast(); + } - virtual operator struct tm () const { throw std::bad_cast(); } - virtual operator SQL_TIMESTAMP_STRUCT () const { throw std::bad_cast(); } + [[nodiscard]] bool isNull() const override; + virtual void apply(DB::HandleField &) const override = 0; - [[nodiscard]] bool isNull() const override; - virtual void apply(DB::HandleField &) const override = 0; + const SelectCommand * selectCmd; - const SelectCommand * selectCmd; - protected: - virtual const Param * meAsAParam() const = 0; + protected: + virtual const Param * meAsAParam() const = 0; }; class CharArrayColumn : public Column, public Param { - public: - typedef std::vector<char> CharArray; - CharArrayColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i, SQLULEN sizeHint) : - DB::Column(n, i), - Column(sc, n, i) - { - data.resize(std::max<SQLULEN>(sizeHint, 64) + 1); - } - virtual SQLSMALLINT ctype() const override { return SQL_C_CHAR; } - virtual SQLSMALLINT stype() const override { return SQL_CHAR; } - virtual SQLULEN size() const override { return data.size(); } - virtual SQLINTEGER dp() const override { return 0; } - virtual const void * dataAddress() const override { return &data.front(); } - virtual void * rwDataAddress() override { return &data.front(); } - void operator=(const Glib::ustring & d); - bool resize() override; - virtual operator std::string () const override { return std::string(&data.front(), bindLen); } - virtual operator Glib::ustring () const override { return std::string(&data.front(), bindLen); } - virtual void apply(DB::HandleField &) const override; - protected: - virtual const Param * meAsAParam() const override { return this; } - CharArray data; + public: + typedef std::vector<char> CharArray; + CharArrayColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i, SQLULEN sizeHint) : + DB::Column(n, i), Column(sc, n, i) + { + data.resize(std::max<SQLULEN>(sizeHint, 64) + 1); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_CHAR; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_CHAR; + } + virtual SQLULEN + size() const override + { + return data.size(); + } + virtual SQLINTEGER + dp() const override + { + return 0; + } + virtual const void * + dataAddress() const override + { + return &data.front(); + } + virtual void * + rwDataAddress() override + { + return &data.front(); + } + void operator=(const Glib::ustring & d); + bool resize() override; + virtual operator std::string() const override + { + return std::string(&data.front(), bindLen); + } + virtual operator Glib::ustring() const override + { + return std::string(&data.front(), bindLen); + } + virtual void apply(DB::HandleField &) const override; + + protected: + virtual const Param * + meAsAParam() const override + { + return this; + } + CharArray data; }; class SignedIntegerColumn : public Column, public SignedIntegerParam { - public: - SignedIntegerColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : - DB::Column(n, i), - Column(sc, n, i) { } - virtual SQLSMALLINT ctype() const override { return SignedIntegerParam::ctype(); } - virtual SQLULEN size() const override { return SignedIntegerParam::size(); } - virtual void * rwDataAddress() override { return &data; } - virtual operator int () const override { return data; } - virtual operator long () const override { return data; } - virtual operator long long () const override { return data; } - virtual const Param * meAsAParam() const override { return this; } - virtual void apply(DB::HandleField &) const override; + public: + SignedIntegerColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : + DB::Column(n, i), Column(sc, n, i) + { + } + virtual SQLSMALLINT + ctype() const override + { + return SignedIntegerParam::ctype(); + } + virtual SQLULEN + size() const override + { + return SignedIntegerParam::size(); + } + virtual void * + rwDataAddress() override + { + return &data; + } + virtual operator int() const override + { + return data; + } + virtual operator long() const override + { + return data; + } + virtual operator long long() const override + { + return data; + } + virtual const Param * + meAsAParam() const override + { + return this; + } + virtual void apply(DB::HandleField &) const override; }; #ifdef COMPLETENESS class UnsignedIntegerColumn : public Column, public UnsignedIntegerParam { - public: - UnsignedIntegerColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : - Column(sc, n, i) { } - virtual const Param * meAsAParam() const override { return this; } + public: + UnsignedIntegerColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : Column(sc, n, i) { } + virtual const Param * + meAsAParam() const override + { + return this; + } }; #endif class FloatingPointColumn : public Column, public FloatingPointParam { - public: - FloatingPointColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : - DB::Column(n, i), - Column(sc, n, i) { } - virtual SQLSMALLINT ctype() const override { return FloatingPointParam::ctype(); } - virtual SQLULEN size() const override { return FloatingPointParam::size(); } - virtual void * rwDataAddress() override { return &data; } - virtual operator double () const override { return data; } - virtual operator float () const override { return data; } - virtual const Param * meAsAParam() const override { return this; } - virtual void apply(DB::HandleField &) const override; + public: + FloatingPointColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : + DB::Column(n, i), Column(sc, n, i) + { + } + virtual SQLSMALLINT + ctype() const override + { + return FloatingPointParam::ctype(); + } + virtual SQLULEN + size() const override + { + return FloatingPointParam::size(); + } + virtual void * + rwDataAddress() override + { + return &data; + } + virtual operator double() const override + { + return data; + } + virtual operator float() const override + { + return data; + } + virtual const Param * + meAsAParam() const override + { + return this; + } + virtual void apply(DB::HandleField &) const override; }; class IntervalColumn : public Column, public IntervalParam { - public: - IntervalColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : - DB::Column(n, i), - Column(sc, n, i) { } - virtual SQLSMALLINT ctype() const override { return IntervalParam::ctype(); } - virtual SQLULEN size() const override { return IntervalParam::size(); } - virtual void * rwDataAddress() override { return &data; } - virtual operator boost::posix_time::time_duration () const; - virtual const Param * meAsAParam() const override { return this; } - virtual void apply(DB::HandleField &) const override; + public: + IntervalColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : DB::Column(n, i), Column(sc, n, i) + { + } + virtual SQLSMALLINT + ctype() const override + { + return IntervalParam::ctype(); + } + virtual SQLULEN + size() const override + { + return IntervalParam::size(); + } + virtual void * + rwDataAddress() override + { + return &data; + } + virtual operator boost::posix_time::time_duration() const; + virtual const Param * + meAsAParam() const override + { + return this; + } + virtual void apply(DB::HandleField &) const override; }; class TimeStampColumn : public Column, public TimeStampParam { - public: - TimeStampColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : - DB::Column(n, i), - Column(sc, n, i) { } - virtual SQLSMALLINT ctype() const override { return TimeStampParam::ctype(); } - virtual SQLULEN size() const override { return TimeStampParam::size(); } - virtual void * rwDataAddress() override { return &data; } - virtual operator boost::posix_time::ptime () const; - virtual const Param * meAsAParam() const override { return this; } - virtual void apply(DB::HandleField &) const override; + public: + TimeStampColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : + DB::Column(n, i), Column(sc, n, i) + { + } + virtual SQLSMALLINT + ctype() const override + { + return TimeStampParam::ctype(); + } + virtual SQLULEN + size() const override + { + return TimeStampParam::size(); + } + virtual void * + rwDataAddress() override + { + return &data; + } + virtual operator boost::posix_time::ptime() const; + virtual const Param * + meAsAParam() const override + { + return this; + } + virtual void apply(DB::HandleField &) const override; }; } #endif - diff --git a/libodbcpp/odbc-command.cpp b/libodbcpp/odbc-command.cpp index 34febf3..c73b3f9 100644 --- a/libodbcpp/odbc-command.cpp +++ b/libodbcpp/odbc-command.cpp @@ -3,10 +3,7 @@ #include "odbc-param.h" #include <sqlext.h> -ODBC::Command::Command(const Connection & c, const std::string & s) : - DB::Command(s), - hStmt(nullptr), - connection(c) +ODBC::Command::Command(const Connection & c, const std::string & s) : DB::Command(s), hStmt(nullptr), connection(c) { RETCODE rc = SQLAllocHandle(SQL_HANDLE_STMT, c.conn, &hStmt); if (!SQL_SUCCEEDED(rc)) { @@ -16,7 +13,7 @@ ODBC::Command::Command(const Connection & c, const std::string & s) : if (!SQL_SUCCEEDED(rc)) { throw ConnectionError(rc, SQL_HANDLE_STMT, hStmt); } - rc = SQLPrepare(hStmt, (SQLCHAR*)sql.c_str(), sql.length()); + rc = SQLPrepare(hStmt, (SQLCHAR *)sql.c_str(), sql.length()); if (!SQL_SUCCEEDED(rc)) { SQLFreeHandle(SQL_HANDLE_STMT, hStmt); throw Error(rc, SQL_HANDLE_STMT, hStmt); @@ -29,4 +26,3 @@ ODBC::Command::Command(const Connection & c, const std::string & s) : } params.resize(pcount); } - diff --git a/libodbcpp/odbc-command.h b/libodbcpp/odbc-command.h index ceba2dc..b0aa3fa 100644 --- a/libodbcpp/odbc-command.h +++ b/libodbcpp/odbc-command.h @@ -1,54 +1,52 @@ #ifndef ODBC_COMMAND_H #define ODBC_COMMAND_H -#include <command.h> -#include <vector> #include "odbc-connection.h" #include "odbc-param_fwd.h" +#include <command.h> #include <glibmm/ustring.h> +#include <vector> namespace ODBC { using ParamPtr = std::unique_ptr<Param>; class Command : public virtual DB::Command { - using Params = std::vector<ParamPtr>; - public: - Command(const Connection &, const std::string & sql); + using Params = std::vector<ParamPtr>; + + public: + Command(const Connection &, const std::string & sql); - void bindParamI(unsigned int i, int val) override; - void bindParamI(unsigned int i, long val) override; - void bindParamI(unsigned int i, long long val) override; - void bindParamI(unsigned int i, unsigned int val) override; - void bindParamI(unsigned int i, unsigned long int val) override; - void bindParamI(unsigned int i, unsigned long long int val) override; + void bindParamI(unsigned int i, int val) override; + void bindParamI(unsigned int i, long val) override; + void bindParamI(unsigned int i, long long val) override; + void bindParamI(unsigned int i, unsigned int val) override; + void bindParamI(unsigned int i, unsigned long int val) override; + void bindParamI(unsigned int i, unsigned long long int val) override; - void bindParamB(unsigned int i, bool val) override; + void bindParamB(unsigned int i, bool val) override; - void bindParamF(unsigned int i, double val) override; - void bindParamF(unsigned int i, float val) override; + void bindParamF(unsigned int i, double val) override; + void bindParamF(unsigned int i, float val) override; - void bindParamS(unsigned int i, const Glib::ustring &) override; - void bindParamS(unsigned int i, const std::string_view &) override; + void bindParamS(unsigned int i, const Glib::ustring &) override; + void bindParamS(unsigned int i, const std::string_view &) override; - void bindParamT(unsigned int i, const boost::posix_time::time_duration &) override; - void bindParamT(unsigned int i, const boost::posix_time::ptime &) override; + void bindParamT(unsigned int i, const boost::posix_time::time_duration &) override; + void bindParamT(unsigned int i, const boost::posix_time::ptime &) override; - void bindNull(unsigned int i) override; + void bindNull(unsigned int i) override; - protected: - friend class Param; - friend class Column; - SQLHSTMT hStmt; - const Connection& connection; + protected: + friend class Param; + friend class Column; + SQLHSTMT hStmt; + const Connection & connection; - private: - Params params; + private: + Params params; - template <class ParamType> - ParamType * - makeParam(unsigned int idx); + template<class ParamType> ParamType * makeParam(unsigned int idx); }; } #endif - diff --git a/libodbcpp/odbc-connection.cpp b/libodbcpp/odbc-connection.cpp index 8ecaf2c..84e316d 100644 --- a/libodbcpp/odbc-connection.cpp +++ b/libodbcpp/odbc-connection.cpp @@ -1,23 +1,20 @@ -#include <sqlext.h> -#include <stdexcept> -#include <cstdio> -#include <cstring> #include "odbc-connection.h" -#include "odbc-selectcommand.h" -#include "odbc-modifycommand.h" #include "error.h" +#include "odbc-modifycommand.h" +#include "odbc-selectcommand.h" +#include <cstdio> +#include <cstring> +#include <sqlext.h> +#include <stdexcept> NAMEDFACTORY("odbc", ODBC::Connection, DB::ConnectionFactory); -ODBC::Connection::Connection(const DSN& d) : - env(nullptr), - conn(nullptr), - thinkDelStyle(DB::BulkDeleteUsingUsing), - thinkUpdStyle(DB::BulkUpdateUsingFromSrc) +ODBC::Connection::Connection(const DSN & d) : + env(nullptr), conn(nullptr), thinkDelStyle(DB::BulkDeleteUsingUsing), thinkUpdStyle(DB::BulkUpdateUsingFromSrc) { connectPre(); - RETCODE dberr = SQLConnect(conn, (SQLCHAR*)d.dsn.c_str(), SQL_NTS, - (SQLCHAR*)d.username.c_str(), SQL_NTS, (SQLCHAR*)d.password.c_str(), SQL_NTS); + RETCODE dberr = SQLConnect(conn, (SQLCHAR *)d.dsn.c_str(), SQL_NTS, (SQLCHAR *)d.username.c_str(), SQL_NTS, + (SQLCHAR *)d.password.c_str(), SQL_NTS); if (!SQL_SUCCEEDED(dberr)) { throw ConnectionError(dberr, SQL_HANDLE_DBC, conn); } @@ -32,7 +29,7 @@ ODBC::Connection::connectPre() throw ConnectionError(dberr, SQL_HANDLE_ENV, env); } - dberr = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); + dberr = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if (!SQL_SUCCEEDED(dberr)) { throw ConnectionError(dberr, SQL_HANDLE_ENV, env); } @@ -69,13 +66,11 @@ ODBC::Connection::connectPost() } ODBC::Connection::Connection(const std::string & s) : - env(nullptr), - conn(nullptr), - thinkDelStyle(DB::BulkDeleteUsingUsing), - thinkUpdStyle(DB::BulkUpdateUsingFromSrc) + env(nullptr), conn(nullptr), thinkDelStyle(DB::BulkDeleteUsingUsing), thinkUpdStyle(DB::BulkUpdateUsingFromSrc) { connectPre(); - RETCODE dberr = SQLDriverConnect(conn, nullptr, (SQLCHAR*)s.c_str(), s.length(), nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT); + RETCODE dberr = SQLDriverConnect( + conn, nullptr, (SQLCHAR *)s.c_str(), s.length(), nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT); if (!SQL_SUCCEEDED(dberr)) { throw ConnectionError(dberr, SQL_HANDLE_DBC, conn); } @@ -187,8 +182,6 @@ ODBC::Connection::ping() const } ODBC::ConnectionError::ConnectionError(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle) : - ODBC::Error(err, handletype, handle), - DB::ConnectionError() + ODBC::Error(err, handletype, handle), DB::ConnectionError() { } - diff --git a/libodbcpp/odbc-connection.h b/libodbcpp/odbc-connection.h index 3574c42..a7853e4 100644 --- a/libodbcpp/odbc-connection.h +++ b/libodbcpp/odbc-connection.h @@ -1,46 +1,45 @@ #ifndef ODBC_CONNECTION_H #define ODBC_CONNECTION_H -#include <connection.h> -#include <error.h> #include "odbc-dsn.h" #include "odbc-error.h" +#include <connection.h> +#include <error.h> #include <sql.h> namespace ODBC { class ConnectionError : public virtual Error, public virtual DB::ConnectionError { - public: - ConnectionError(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle); + public: + ConnectionError(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle); }; class Connection : public DB::Connection { - public: - Connection(const DSN& d); - Connection(const std::string & str); - ~Connection(); - SQLHENV env; - SQLHDBC conn; - - void beginTxInt() override; - void commitTxInt() override; - void rollbackTxInt() override; - void ping() const override; - std::string getAttrStr(SQLINTEGER) const; - SQLINTEGER getAttrInt(SQLINTEGER) const; - DB::BulkDeleteStyle bulkDeleteStyle() const override; - DB::BulkUpdateStyle bulkUpdateStyle() const override; - - DB::SelectCommandPtr select(const std::string & sql, const DB::CommandOptionsCPtr &) override; - DB::ModifyCommandPtr modify(const std::string & sql, const DB::CommandOptionsCPtr &) override; - - private: - DB::BulkDeleteStyle thinkDelStyle; - DB::BulkUpdateStyle thinkUpdStyle; - - void connectPre(); - void connectPost(); + public: + Connection(const DSN & d); + Connection(const std::string & str); + ~Connection(); + SQLHENV env; + SQLHDBC conn; + + void beginTxInt() override; + void commitTxInt() override; + void rollbackTxInt() override; + void ping() const override; + std::string getAttrStr(SQLINTEGER) const; + SQLINTEGER getAttrInt(SQLINTEGER) const; + DB::BulkDeleteStyle bulkDeleteStyle() const override; + DB::BulkUpdateStyle bulkUpdateStyle() const override; + + DB::SelectCommandPtr select(const std::string & sql, const DB::CommandOptionsCPtr &) override; + DB::ModifyCommandPtr modify(const std::string & sql, const DB::CommandOptionsCPtr &) override; + + private: + DB::BulkDeleteStyle thinkDelStyle; + DB::BulkUpdateStyle thinkUpdStyle; + + void connectPre(); + void connectPost(); }; } #endif - diff --git a/libodbcpp/odbc-dsn.cpp b/libodbcpp/odbc-dsn.cpp index d2802bd..9d300f4 100644 --- a/libodbcpp/odbc-dsn.cpp +++ b/libodbcpp/odbc-dsn.cpp @@ -1,9 +1,6 @@ #include "odbc-dsn.h" ODBC::DSN::DSN(std::string d, std::string u, std::string p) : - dsn(std::move(d)), - username(std::move(u)), - password(std::move(p)) + dsn(std::move(d)), username(std::move(u)), password(std::move(p)) { } - diff --git a/libodbcpp/odbc-dsn.h b/libodbcpp/odbc-dsn.h index 4568cb6..0d33507 100644 --- a/libodbcpp/odbc-dsn.h +++ b/libodbcpp/odbc-dsn.h @@ -5,14 +5,13 @@ namespace ODBC { class DSN { - public: - DSN(std::string, std::string, std::string); - virtual ~DSN() = default; - const std::string dsn; // DSN name for odbc.ini - const std::string username; // User name - const std::string password; // Password + public: + DSN(std::string, std::string, std::string); + virtual ~DSN() = default; + const std::string dsn; // DSN name for odbc.ini + const std::string username; // User name + const std::string password; // Password }; } #endif - diff --git a/libodbcpp/odbc-error.cpp b/libodbcpp/odbc-error.cpp index afa1d42..93f11c0 100644 --- a/libodbcpp/odbc-error.cpp +++ b/libodbcpp/odbc-error.cpp @@ -1,11 +1,12 @@ #include "odbc-error.h" -#include <compileTimeFormatter.h> #include <array> +#include <compileTimeFormatter.h> namespace AdHoc { StreamWriterT('5') { - template<std::size_t l, typename ... Pn> - static void write(stream & s, const std::array<SQLCHAR, l> & sqlstatus, const Pn & ... pn) + template<std::size_t l, typename... Pn> + static void + write(stream & s, const std::array<SQLCHAR, l> & sqlstatus, const Pn &... pn) { static_assert(l > 5); s.write((const char * const)sqlstatus.data(), 5); @@ -21,10 +22,11 @@ AdHocFormatter(ODBCError, "Failed to get diagnostics for return code %?"); ODBC::Error::Error(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle) { std::array<SQLCHAR, 6> sqlstatus {}; - SQLINTEGER sqlerr; + SQLINTEGER sqlerr; std::array<SQLCHAR, 12800> sqlerrmsg {}; - SQLRETURN rc = SQLGetDiagRec(handletype, handle, 1, sqlstatus.data(), &sqlerr, sqlerrmsg.data(), sqlerrmsg.size(), nullptr); + SQLRETURN rc = SQLGetDiagRec( + handletype, handle, 1, sqlstatus.data(), &sqlerr, sqlerrmsg.data(), sqlerrmsg.size(), nullptr); switch (rc) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: @@ -51,4 +53,3 @@ ODBC::Error::message() const noexcept { return msg; } - diff --git a/libodbcpp/odbc-error.h b/libodbcpp/odbc-error.h index addc528..b19f2c0 100644 --- a/libodbcpp/odbc-error.h +++ b/libodbcpp/odbc-error.h @@ -1,20 +1,20 @@ #ifndef ODBC_ERROR_H #define ODBC_ERROR_H +#include <error.h> +#include <exception.h> #include <sql.h> #include <stdlib.h> -#include <exception.h> -#include <error.h> namespace ODBC { class Error : public AdHoc::Exception<DB::Error> { - public: - Error(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle); + public: + Error(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle); - std::string message() const noexcept override; + std::string message() const noexcept override; - private: - std::string msg; + private: + std::string msg; }; } diff --git a/libodbcpp/odbc-mock.cpp b/libodbcpp/odbc-mock.cpp index 29a9278..21b332a 100644 --- a/libodbcpp/odbc-mock.cpp +++ b/libodbcpp/odbc-mock.cpp @@ -1,33 +1,34 @@ -#include "odbc-connection.h" #include "odbc-mock.h" +#include "odbc-connection.h" #include <compileTimeFormatter.h> namespace ODBC { -Mock::Mock(const std::string & b, const std::string & masterdb, const std::string & name, const std::vector<std::filesystem::path> & ss) : - MockServerDatabase(b + ";" + masterdb, name, "odbc"), - base(b) -{ - Mock::CreateNewDatabase(); - PlaySchemaScripts(ss); -} + Mock::Mock(const std::string & b, const std::string & masterdb, const std::string & name, + const std::vector<std::filesystem::path> & ss) : + MockServerDatabase(b + ";" + masterdb, name, "odbc"), + base(b) + { + Mock::CreateNewDatabase(); + PlaySchemaScripts(ss); + } -AdHocFormatter(MockConnStr, "%?;Database=%?"); -DB::ConnectionPtr -Mock::openConnection() const -{ - return std::make_shared<Connection>(MockConnStr::get(base, testDbName)); -} + AdHocFormatter(MockConnStr, "%?;Database=%?"); + DB::ConnectionPtr + Mock::openConnection() const + { + return std::make_shared<Connection>(MockConnStr::get(base, testDbName)); + } -Mock::~Mock() -{ - Mock::DropDatabase(); -} + Mock::~Mock() + { + Mock::DropDatabase(); + } -void Mock::DropDatabase() const -{ - MockServerDatabase::DropDatabase(); -} + void + Mock::DropDatabase() const + { + MockServerDatabase::DropDatabase(); + } } - diff --git a/libodbcpp/odbc-mock.h b/libodbcpp/odbc-mock.h index 8371cf6..5db50f5 100644 --- a/libodbcpp/odbc-mock.h +++ b/libodbcpp/odbc-mock.h @@ -1,16 +1,17 @@ #ifndef MOCKODBCDATASOURCE_H #define MOCKODBCDATASOURCE_H -#include <mockDatabase.h> +#include <c++11Helpers.h> #include <filesystem> +#include <mockDatabase.h> #include <visibility.h> -#include <c++11Helpers.h> namespace ODBC { -class DLL_PUBLIC Mock : public DB::MockServerDatabase { + class DLL_PUBLIC Mock : public DB::MockServerDatabase { public: - Mock(const std::string & base, const std::string & master, const std::string & name, const std::vector<std::filesystem::path> & ss); + Mock(const std::string & base, const std::string & master, const std::string & name, + const std::vector<std::filesystem::path> & ss); ~Mock() override; SPECIAL_MEMBERS_MOVE_RO(Mock); @@ -22,9 +23,8 @@ class DLL_PUBLIC Mock : public DB::MockServerDatabase { private: [[nodiscard]] DB::ConnectionPtr openConnection() const override; -}; + }; } #endif - diff --git a/libodbcpp/odbc-modifycommand.cpp b/libodbcpp/odbc-modifycommand.cpp index 3bea818..2fca416 100644 --- a/libodbcpp/odbc-modifycommand.cpp +++ b/libodbcpp/odbc-modifycommand.cpp @@ -2,9 +2,7 @@ #include "odbc-error.h" ODBC::ModifyCommand::ModifyCommand(const ODBC::Connection & c, const std::string & sql) : - DB::Command(sql), - ODBC::Command(c, sql), - DB::ModifyCommand(sql) + DB::Command(sql), ODBC::Command(c, sql), DB::ModifyCommand(sql) { } @@ -27,4 +25,3 @@ ODBC::ModifyCommand::execute(bool anc) } throw DB::NoRowsAffected(); } - diff --git a/libodbcpp/odbc-modifycommand.h b/libodbcpp/odbc-modifycommand.h index 3993d63..de3f7e0 100644 --- a/libodbcpp/odbc-modifycommand.h +++ b/libodbcpp/odbc-modifycommand.h @@ -1,17 +1,16 @@ #ifndef ODBC_MODIFYCOMMAND_H #define ODBC_MODIFYCOMMAND_H -#include <modifycommand.h> #include "odbc-command.h" +#include <modifycommand.h> namespace ODBC { class ModifyCommand : public Command, public DB::ModifyCommand { - public: - ModifyCommand(const Connection &, const std::string & sql); - // Execute the command and return effected row count - unsigned int execute(bool allowNoChange = true) override; + public: + ModifyCommand(const Connection &, const std::string & sql); + // Execute the command and return effected row count + unsigned int execute(bool allowNoChange = true) override; }; } #endif - diff --git a/libodbcpp/odbc-param.cpp b/libodbcpp/odbc-param.cpp index a185393..a14d244 100644 --- a/libodbcpp/odbc-param.cpp +++ b/libodbcpp/odbc-param.cpp @@ -1,26 +1,14 @@ -#include <sqlext.h> #include "odbc-param.h" #include "odbc-command.h" #include "odbc-error.h" #include <cstring> +#include <sqlext.h> -ODBC::Param::Param() : - paramCmd(nullptr), - paramIdx(0), - paramBound(false), - dataLength(0) -{ -} +ODBC::Param::Param() : paramCmd(nullptr), paramIdx(0), paramBound(false), dataLength(0) { } -ODBC::Param::Param(Command * c, unsigned int i) : - paramCmd(c), - paramIdx(i), - paramBound(false), - dataLength(0) -{ -} +ODBC::Param::Param(Command * c, unsigned int i) : paramCmd(c), paramIdx(i), paramBound(false), dataLength(0) { } -template <class ParamType> +template<class ParamType> ParamType * ODBC::Command::makeParam(unsigned int idx) { @@ -29,7 +17,7 @@ ODBC::Command::makeParam(unsigned int idx) } auto & p = params[idx]; if (p) { - if (auto np = dynamic_cast<ParamType*>(p.get())) { + if (auto np = dynamic_cast<ParamType *>(p.get())) { return np; } } @@ -41,8 +29,8 @@ void ODBC::Param::bind() const { if (!paramBound) { - RETCODE rc = SQLBindParameter(paramCmd->hStmt, paramIdx + 1, SQL_PARAM_INPUT, ctype(), stype(), - size(), dp(), const_cast<void *>(dataAddress()), size(), &bindLen); + RETCODE rc = SQLBindParameter(paramCmd->hStmt, paramIdx + 1, SQL_PARAM_INPUT, ctype(), stype(), size(), dp(), + const_cast<void *>(dataAddress()), size(), &bindLen); if (!SQL_SUCCEEDED(rc)) { throw Error(rc, SQL_HANDLE_STMT, paramCmd->hStmt); } @@ -51,13 +39,12 @@ ODBC::Param::bind() const } #define SIMPLEBINDER(ctype, otype, suf) \ -void \ -ODBC::Command::bindParam##suf(unsigned int i, ctype val) \ -{ \ - ODBC::otype * p = makeParam<ODBC::otype>(i); \ - *p = val; \ - p->bind(); \ -} + void ODBC::Command::bindParam##suf(unsigned int i, ctype val) \ + { \ + ODBC::otype * p = makeParam<ODBC::otype>(i); \ + *p = val; \ + p->bind(); \ + } SIMPLEBINDER(int, SignedIntegerParam, I); SIMPLEBINDER(long, SignedIntegerParam, I); SIMPLEBINDER(long long, SignedIntegerParam, I); @@ -135,4 +122,3 @@ ODBC::IntervalParam::operator=(const boost::posix_time::time_duration & d) data.intval.day_second.fraction = d.fractional_seconds(); return *this; } - diff --git a/libodbcpp/odbc-param.h b/libodbcpp/odbc-param.h index 6ef5ae1..03aaef5 100644 --- a/libodbcpp/odbc-param.h +++ b/libodbcpp/odbc-param.h @@ -1,116 +1,326 @@ #ifndef ODBC_PARAM_H #define ODBC_PARAM_H -#include <malloc.h> -#include <sqlext.h> -#include <glibmm/ustring.h> #include "odbc-param_fwd.h" #include <boost/date_time/posix_time/posix_time_types.hpp> +#include <glibmm/ustring.h> +#include <malloc.h> +#include <sqlext.h> namespace ODBC { class BooleanParam : public Param { - public: - BooleanParam() : Param() { } - BooleanParam(Command * c, unsigned int i) : Param(c, i) { bindLen = BooleanParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_BIT; } - virtual SQLSMALLINT stype() const override { return SQL_C_BIT; } - virtual SQLULEN size() const override { return sizeof(SQLINTEGER); } - virtual SQLINTEGER dp() const override { return 0; } - virtual const void * dataAddress() const override { return &data; } - BooleanParam & operator=(const SQLINTEGER & d) { data = d; return *this; } - protected: - SQLINTEGER data; + public: + BooleanParam() : Param() { } + BooleanParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = BooleanParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_BIT; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_C_BIT; + } + virtual SQLULEN + size() const override + { + return sizeof(SQLINTEGER); + } + virtual SQLINTEGER + dp() const override + { + return 0; + } + virtual const void * + dataAddress() const override + { + return &data; + } + BooleanParam & + operator=(const SQLINTEGER & d) + { + data = d; + return *this; + } + + protected: + SQLINTEGER data; }; class SignedIntegerParam : public Param { - public: - SignedIntegerParam() : Param() { } - SignedIntegerParam(Command * c, unsigned int i) : Param(c, i) { bindLen = SignedIntegerParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_LONG; } - virtual SQLSMALLINT stype() const override { return SQL_C_LONG; } - virtual SQLULEN size() const override { return sizeof(SQLINTEGER); } - virtual SQLINTEGER dp() const override { return 0; } - virtual const void * dataAddress() const override { return &data; } - SignedIntegerParam & operator=(const SQLINTEGER & d) { data = d; return *this; } - protected: - SQLINTEGER data; + public: + SignedIntegerParam() : Param() { } + SignedIntegerParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = SignedIntegerParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_LONG; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_C_LONG; + } + virtual SQLULEN + size() const override + { + return sizeof(SQLINTEGER); + } + virtual SQLINTEGER + dp() const override + { + return 0; + } + virtual const void * + dataAddress() const override + { + return &data; + } + SignedIntegerParam & + operator=(const SQLINTEGER & d) + { + data = d; + return *this; + } + + protected: + SQLINTEGER data; }; class UnsignedIntegerParam : public Param { - public: - UnsignedIntegerParam() : Param() { } - UnsignedIntegerParam(Command * c, unsigned int i) : Param(c, i) { bindLen = UnsignedIntegerParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_ULONG; } - virtual SQLSMALLINT stype() const override { return SQL_C_ULONG; } - virtual SQLULEN size() const override { return sizeof(SQLUINTEGER); } - virtual SQLINTEGER dp() const override { return 0; } - virtual const void * dataAddress() const override { return &data; } - UnsignedIntegerParam & operator=(const SQLUINTEGER & d) { data = d; return *this; } - protected: - SQLUINTEGER data; + public: + UnsignedIntegerParam() : Param() { } + UnsignedIntegerParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = UnsignedIntegerParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_ULONG; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_C_ULONG; + } + virtual SQLULEN + size() const override + { + return sizeof(SQLUINTEGER); + } + virtual SQLINTEGER + dp() const override + { + return 0; + } + virtual const void * + dataAddress() const override + { + return &data; + } + UnsignedIntegerParam & + operator=(const SQLUINTEGER & d) + { + data = d; + return *this; + } + + protected: + SQLUINTEGER data; }; class FloatingPointParam : public Param { - public: - FloatingPointParam() : Param() { } - FloatingPointParam(Command * c, unsigned int i) : Param(c, i) { bindLen = FloatingPointParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_DOUBLE; } - virtual SQLSMALLINT stype() const override { return SQL_C_DOUBLE; } - virtual SQLULEN size() const override { return sizeof(SQLDOUBLE); } - virtual SQLINTEGER dp() const override { return 10; } - virtual const void * dataAddress() const override { return &data; } - FloatingPointParam & operator=(const SQLDOUBLE & d) { data = d; return *this; } - protected: - SQLDOUBLE data; + public: + FloatingPointParam() : Param() { } + FloatingPointParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = FloatingPointParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_DOUBLE; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_C_DOUBLE; + } + virtual SQLULEN + size() const override + { + return sizeof(SQLDOUBLE); + } + virtual SQLINTEGER + dp() const override + { + return 10; + } + virtual const void * + dataAddress() const override + { + return &data; + } + FloatingPointParam & + operator=(const SQLDOUBLE & d) + { + data = d; + return *this; + } + + protected: + SQLDOUBLE data; }; class StdStringParam : public Param { - public: - StdStringParam() : Param() { } - StdStringParam(Command * c, unsigned int i) : Param(c, i) { bindLen = StdStringParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_CHAR; } - virtual SQLSMALLINT stype() const override { return SQL_CHAR; } - virtual SQLULEN size() const override { return data.length(); } - virtual SQLINTEGER dp() const override { return 0; } - virtual const void * dataAddress() const override { return data.data(); } - StdStringParam & operator=(const std::string_view & d); - StdStringParam & operator=(const Glib::ustring & d); - protected: - std::string data; + public: + StdStringParam() : Param() { } + StdStringParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = StdStringParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_CHAR; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_CHAR; + } + virtual SQLULEN + size() const override + { + return data.length(); + } + virtual SQLINTEGER + dp() const override + { + return 0; + } + virtual const void * + dataAddress() const override + { + return data.data(); + } + StdStringParam & operator=(const std::string_view & d); + StdStringParam & operator=(const Glib::ustring & d); + + protected: + std::string data; }; class IntervalParam : public Param { - public: - IntervalParam() : Param() { } - IntervalParam(Command * c, unsigned int i) : Param(c, i) { bindLen = IntervalParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_INTERVAL_DAY_TO_SECOND; } - virtual SQLSMALLINT stype() const override { return SQL_INTERVAL_DAY_TO_SECOND; } - virtual SQLULEN size() const override { return sizeof(SQL_INTERVAL_STRUCT); } - virtual SQLINTEGER dp() const override { return boost::posix_time::time_res_traits::num_fractional_digits(); } - virtual const void * dataAddress() const override { return &data; } - IntervalParam & operator=(const boost::posix_time::time_duration & d); - protected: - SQL_INTERVAL_STRUCT data; + public: + IntervalParam() : Param() { } + IntervalParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = IntervalParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_INTERVAL_DAY_TO_SECOND; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_INTERVAL_DAY_TO_SECOND; + } + virtual SQLULEN + size() const override + { + return sizeof(SQL_INTERVAL_STRUCT); + } + virtual SQLINTEGER + dp() const override + { + return boost::posix_time::time_res_traits::num_fractional_digits(); + } + virtual const void * + dataAddress() const override + { + return &data; + } + IntervalParam & operator=(const boost::posix_time::time_duration & d); + + protected: + SQL_INTERVAL_STRUCT data; }; class TimeStampParam : public Param { - public: - TimeStampParam() : Param() { } - TimeStampParam(Command * c, unsigned int i) : Param(c, i) { bindLen = TimeStampParam::size(); } - virtual SQLSMALLINT ctype() const override { return SQL_C_TYPE_TIMESTAMP; } - virtual SQLSMALLINT stype() const override { return SQL_TYPE_TIMESTAMP; } - virtual SQLULEN size() const override { return sizeof(SQL_TIMESTAMP_STRUCT); } - virtual SQLINTEGER dp() const override { return boost::posix_time::time_res_traits::num_fractional_digits(); } - virtual const void * dataAddress() const override { return &data; } - TimeStampParam & operator=(const boost::posix_time::ptime & d); - protected: - SQL_TIMESTAMP_STRUCT data; + public: + TimeStampParam() : Param() { } + TimeStampParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = TimeStampParam::size(); + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_TYPE_TIMESTAMP; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_TYPE_TIMESTAMP; + } + virtual SQLULEN + size() const override + { + return sizeof(SQL_TIMESTAMP_STRUCT); + } + virtual SQLINTEGER + dp() const override + { + return boost::posix_time::time_res_traits::num_fractional_digits(); + } + virtual const void * + dataAddress() const override + { + return &data; + } + TimeStampParam & operator=(const boost::posix_time::ptime & d); + + protected: + SQL_TIMESTAMP_STRUCT data; }; class NullParam : public Param { - public: - NullParam() : Param() { } - NullParam(Command * c, unsigned int i) : Param(c, i) { bindLen = SQL_NULL_DATA; } - virtual SQLSMALLINT ctype() const override { return SQL_C_LONG; } - virtual SQLSMALLINT stype() const override { return SQL_C_LONG; } - virtual SQLULEN size() const override { return 0; } - virtual SQLINTEGER dp() const override { return 0; } - virtual const void * dataAddress() const override { return NULL; } + public: + NullParam() : Param() { } + NullParam(Command * c, unsigned int i) : Param(c, i) + { + bindLen = SQL_NULL_DATA; + } + virtual SQLSMALLINT + ctype() const override + { + return SQL_C_LONG; + } + virtual SQLSMALLINT + stype() const override + { + return SQL_C_LONG; + } + virtual SQLULEN + size() const override + { + return 0; + } + virtual SQLINTEGER + dp() const override + { + return 0; + } + virtual const void * + dataAddress() const override + { + return NULL; + } }; } #endif - diff --git a/libodbcpp/odbc-param_fwd.h b/libodbcpp/odbc-param_fwd.h index 88c3dae..6c32d02 100644 --- a/libodbcpp/odbc-param_fwd.h +++ b/libodbcpp/odbc-param_fwd.h @@ -1,29 +1,28 @@ #ifndef ODBC_PARAM_FWD_H #define ODBC_PARAM_FWD_H -#include <sqlext.h> #include "odbc-bind.h" +#include <sqlext.h> namespace ODBC { class Command; class Param : public virtual Bind { - public: - Param(); - Param(Command *, unsigned int idx); - void bind() const; + public: + Param(); + Param(Command *, unsigned int idx); + void bind() const; - virtual SQLSMALLINT stype() const = 0; // The SQL type ID - virtual SQLINTEGER dp() const = 0; // The decimal place count - virtual const void * dataAddress() const = 0; // The address of the data + virtual SQLSMALLINT stype() const = 0; // The SQL type ID + virtual SQLINTEGER dp() const = 0; // The decimal place count + virtual const void * dataAddress() const = 0; // The address of the data - protected: - friend class Column; - mutable Command * paramCmd; - mutable unsigned int paramIdx; - mutable bool paramBound; // Has SqlBind(...) been called since last change of address? - SQLLEN dataLength; + protected: + friend class Column; + mutable Command * paramCmd; + mutable unsigned int paramIdx; + mutable bool paramBound; // Has SqlBind(...) been called since last change of address? + SQLLEN dataLength; }; } #endif - diff --git a/libodbcpp/odbc-selectcommand.cpp b/libodbcpp/odbc-selectcommand.cpp index 82947a7..d40ab2f 100644 --- a/libodbcpp/odbc-selectcommand.cpp +++ b/libodbcpp/odbc-selectcommand.cpp @@ -1,15 +1,13 @@ #include "odbc-selectcommand.h" -#include "odbc-error.h" #include "odbc-column.h" -#include <sqlext.h> -#include <cstring> -#include <boost/multi_index_container.hpp> +#include "odbc-error.h" #include <boost/multi_index/ordered_index.hpp> +#include <boost/multi_index_container.hpp> +#include <cstring> +#include <sqlext.h> ODBC::SelectCommand::SelectCommand(const Connection & c, const std::string & s) : - DB::Command(s), - ODBC::Command(c, s), - DB::SelectCommand(s) + DB::Command(s), ODBC::Command(c, s), DB::SelectCommand(s) { } @@ -26,7 +24,7 @@ ODBC::SelectCommand::fetch() return fetch(SQL_FETCH_NEXT, 0); } -constexpr std::array<SQLCHAR, 6> truncated = { '0', '1', '0', '0', '4', '\0' }; +constexpr std::array<SQLCHAR, 6> truncated = {'0', '1', '0', '0', '4', '\0'}; bool ODBC::SelectCommand::fetch(SQLSMALLINT orientation, SQLLEN offset) { @@ -36,31 +34,29 @@ ODBC::SelectCommand::fetch(SQLSMALLINT orientation, SQLLEN offset) RETCODE rc = SQLFetchScroll(hStmt, orientation, offset); switch (rc) { case SQL_SUCCESS_WITH_INFO: - default: - { - std::array<SQLCHAR, 6> sqlstatus {}; - RETCODE diagrc = SQLGetDiagRec(SQL_HANDLE_STMT, hStmt, 1, sqlstatus.data(), nullptr, nullptr, 0, nullptr); - if (SQL_SUCCEEDED(diagrc)) { - if (sqlstatus == truncated) { - for (const auto & c : largeColumns) { - c->resize(); - } - return fetch(SQL_FETCH_RELATIVE, 0); + default: { + std::array<SQLCHAR, 6> sqlstatus {}; + RETCODE diagrc = SQLGetDiagRec(SQL_HANDLE_STMT, hStmt, 1, sqlstatus.data(), nullptr, nullptr, 0, nullptr); + if (SQL_SUCCEEDED(diagrc)) { + if (sqlstatus == truncated) { + for (const auto & c : largeColumns) { + c->resize(); } - } - } - [[ fallthrough ]]; - case SQL_SUCCESS: - { - bool resized = false; - for (const auto & c : largeColumns) { - resized |= c->resize(); - } - if (resized) { return fetch(SQL_FETCH_RELATIVE, 0); } - return true; } + } + [[fallthrough]]; + case SQL_SUCCESS: { + bool resized = false; + for (const auto & c : largeColumns) { + resized |= c->resize(); + } + if (resized) { + return fetch(SQL_FETCH_RELATIVE, 0); + } + return true; + } case SQL_NO_DATA: return false; } @@ -84,7 +80,7 @@ ODBC::SelectCommand::execute() int sqlcol = col + 1; // NOLINTNEXTLINE(hicpp-no-array-decay) if (!SQL_SUCCEEDED(rc = SQLDescribeCol(hStmt, sqlcol, _colName.data(), _colName.size(), &nameLen, &bindType, - &bindSize, &dp, &nullable))) { + &bindSize, &dp, &nullable))) { throw Error(rc, SQL_HANDLE_STMT, hStmt); } Glib::ustring colName((const char *)_colName.data(), nameLen); @@ -129,7 +125,8 @@ ODBC::SelectCommand::execute() throw DB::ColumnTypeNotSupported(); default: SQLLEN octetSize = 0; - if (!SQL_SUCCEEDED(rc = SQLColAttribute(hStmt, sqlcol, SQL_DESC_OCTET_LENGTH, nullptr, 0, nullptr, &octetSize))) { + if (!SQL_SUCCEEDED(rc + = SQLColAttribute(hStmt, sqlcol, SQL_DESC_OCTET_LENGTH, nullptr, 0, nullptr, &octetSize))) { throw Error(rc, SQL_HANDLE_STMT, hStmt); } bindSize = octetSize; @@ -141,4 +138,3 @@ ODBC::SelectCommand::execute() dynamic_cast<Column *>(ncol)->bind(); } } - diff --git a/libodbcpp/odbc-selectcommand.h b/libodbcpp/odbc-selectcommand.h index efa584e..1dbf798 100644 --- a/libodbcpp/odbc-selectcommand.h +++ b/libodbcpp/odbc-selectcommand.h @@ -1,25 +1,24 @@ #ifndef ODBC_SELECTCOMMAND_H #define ODBC_SELECTCOMMAND_H -#include <selectcommand.h> #include "odbc-command.h" +#include <selectcommand.h> namespace ODBC { class Column; class SelectCommand : public Command, public DB::SelectCommand { - public: - SelectCommand (const Connection &, const std::string & sql); - ~SelectCommand(); - bool fetch() override; - void execute() override; + public: + SelectCommand(const Connection &, const std::string & sql); + ~SelectCommand(); + bool fetch() override; + void execute() override; - private: - bool fetch(SQLSMALLINT orientation = SQL_FETCH_NEXT, SQLLEN offset = 0); - typedef std::shared_ptr<Column> ColumnPtr; - typedef std::set<Column *> Columns; - Columns largeColumns; + private: + bool fetch(SQLSMALLINT orientation = SQL_FETCH_NEXT, SQLLEN offset = 0); + typedef std::shared_ptr<Column> ColumnPtr; + typedef std::set<Column *> Columns; + Columns largeColumns; }; } #endif - diff --git a/libodbcpp/unittests/testodbc.cpp b/libodbcpp/unittests/testodbc.cpp index 5263eb5..14fe0a3 100644 --- a/libodbcpp/unittests/testodbc.cpp +++ b/libodbcpp/unittests/testodbc.cpp @@ -1,30 +1,30 @@ #define BOOST_TEST_MODULE TestODBC #include <boost/test/unit_test.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> +#include <column.h> #include <definedDirs.h> +#include <error.h> #include <modifycommand.h> +#include <odbc-mock.h> #include <selectcommand.h> #include <selectcommandUtil.impl.h> -#include <column.h> -#include <error.h> -#include <odbc-mock.h> #include <testCore.h> -#include <definedDirs.h> -#include <boost/date_time/posix_time/posix_time.hpp> class StandardMockDatabase : public DB::PluginMock<ODBC::Mock> { - public: - StandardMockDatabase() : DB::PluginMock<ODBC::Mock>( "odbcmock", { rootDir / "odbcschema.sql" }, +public: + StandardMockDatabase() : + DB::PluginMock<ODBC::Mock>("odbcmock", {rootDir / "odbcschema.sql"}, "Driver=psqlodbcw.so;uid=postgres;servername=/run/postgresql", "Database=postgres") - { - } + { + } }; -BOOST_GLOBAL_FIXTURE( StandardMockDatabase ); +BOOST_GLOBAL_FIXTURE(StandardMockDatabase); -BOOST_FIXTURE_TEST_SUITE( Core, DB::TestCore ); +BOOST_FIXTURE_TEST_SUITE(Core, DB::TestCore); -BOOST_AUTO_TEST_CASE( transactions ) +BOOST_AUTO_TEST_CASE(transactions) { auto ro = DB::MockDatabase::openConnectionTo("odbcmock"); @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE( transactions ) BOOST_REQUIRE_EQUAL(false, ro->inTx()); } -BOOST_AUTO_TEST_CASE( bindAndSend ) +BOOST_AUTO_TEST_CASE(bindAndSend) { auto rw = DB::MockDatabase::openConnectionTo("odbcmock"); @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE( bindAndSend ) BOOST_CHECK_EQUAL(1, mod->execute()); } -BOOST_AUTO_TEST_CASE( bindAndSelect ) +BOOST_AUTO_TEST_CASE(bindAndSelect) { auto ro = DB::MockDatabase::openConnectionTo("odbcmock"); @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE( bindAndSelect ) BOOST_REQUIRE_EQUAL(1, rows); } -BOOST_AUTO_TEST_CASE( bindAndSelectOther ) +BOOST_AUTO_TEST_CASE(bindAndSelectOther) { auto ro = DB::MockDatabase::openConnectionTo("odbcmock"); @@ -85,13 +85,14 @@ BOOST_AUTO_TEST_CASE( bindAndSelectOther ) assertColumnValueHelper(*select, 1, 123.45); assertColumnValueHelper(*select, 2, std::string_view("some text")); // assertColumnValueHelper(*select, 3, true); - assertColumnValueHelper(*select, 4, boost::posix_time::ptime_from_tm({ 3, 6, 23, 27, 3, 115, 0, 0, 0, 0, nullptr})); + assertColumnValueHelper( + *select, 4, boost::posix_time::ptime_from_tm({3, 6, 23, 27, 3, 115, 0, 0, 0, 0, nullptr})); rows += 1; } BOOST_REQUIRE_EQUAL(1, rows); } -BOOST_AUTO_TEST_CASE( multibyte ) +BOOST_AUTO_TEST_CASE(multibyte) { auto ro = DB::MockDatabase::openConnectionTo("odbcmock"); @@ -106,4 +107,3 @@ BOOST_AUTO_TEST_CASE( multibyte ) } BOOST_AUTO_TEST_SUITE_END(); - |