diff --git a/connector_api/bind_result.h b/connector_api/bind_result.h new file mode 100644 index 00000000..8999c357 --- /dev/null +++ b/connector_api/bind_result.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef SQLPP_DATABASE_BIND_RESULT_H +#define SQLPP_DATABASE_BIND_RESULT_H + +#include + +namespace sqlpp +{ + namespace database + { + /* + * bind_result_t binds values of a sqlpp11 result row + * to the results of a statement + */ + class bind_result_t + { + public: + bind_result_t(); // default constructor for a result that will not yield a valid row + bind_result_t(...); + bind_result_t(const bind_result_t&) = delete; + bind_result_t(bind_result_t&& rhs); + bind_result_t& operator=(const bind_result_t&) = delete; + bind_result_t& operator=(bind_result_t&&); + ~bind_result_t(); + + bool operator==(const bind_result_t& rhs) const; + + template + void next(ResultRow& result_row); + + // something similar to this: + /* + { + if (!_handle) + { + result_row.invalidate(); + return; + } + + if (next_impl()) + { + if (not result_row) + { + result_row.validate(); + } + result_row._bind(*this); // bind result row values to results + } + else + { + if (result_row) + result_row.invalidate(); + } + }; + */ + + // These are called by the result row to bind individual result values + void _bind_boolean_result(size_t index, signed char* value, bool* is_null); + void _bind_integral_result(size_t index, int64_t* value, bool* is_null); + void _bind_text_result(size_t index, const char** text, size_t* len); + ... + }; + + } +} +#endif diff --git a/connector_api/char_result.h b/connector_api/char_result.h new file mode 100644 index 00000000..355ba959 --- /dev/null +++ b/connector_api/char_result.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef SQLPP_DATABASE_CHAR_RESULT_H +#define SQLPP_DATABASE_CHAR_RESULT_H + +#include + +namespace sqlpp +{ + namespace database + { + /* + * char_result_t yields results as + * sqlpp11::vendor::char_result_row_t + */ + class char_result_t + { + ::sqlpp11::vendor::char_result_row_t char_result_row; + public: + char_result_t(); // default constructor for a result that will not yield a valid row + char_result_t(...); + char_result_t(const char_result_t&) = delete; + char_result_t(char_result_t&& rhs); + char_result_t& operator=(const char_result_t&) = delete; + char_result_t& operator=(char_result_t&&); + ~char_result_t(); + + bool operator==(const char_result_t& rhs) const; + + template + void next(ResultRow& result_row); + + // Something like + /* + { + next_impl(); + if (_char_result_row.data) + result_row = _char_result_row; + else + result_row.invalidate(); + }; + */ + } +} +#endif diff --git a/connector_api/connection.h b/connector_api/connection.h new file mode 100644 index 00000000..297ae55e --- /dev/null +++ b/connector_api/connection.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef SQLPP_DATABASE_CONNECTION_H +#define SQLPP_DATABASE_CONNECTION_H + +#include +#include +#include // You may use char result or bind result or both +#include // to represent results of select and prepared select + +namespace sqlpp +{ + namespace database + { + // The context is not a requirement, but if the database requires + // any deviations from the SQL standard, you should use your own + // context in order to specialize the behaviour, see also interpreter.h + struct context_t + { + template + std::ostream& operator<<(T t); + + std::string escape(std::string arg); + }; + + class connection: public sqlpp::connection // this inheritance helps with ADL for dynamic_select, for instance + { + public: + using _prepared_statement_t = << handle to a prepared statement of the database >>; + using _context_t = << This context is used to interpret the dynamic parts of dynamic statemtents>>; + + connection(...); + ~connection(); + connection(const connection&) = delete; + connection(connection&&) = delete; + connection& operator=(const connection&) = delete; + connection& operator=(connection&&) = delete; + + //! "direct" select + template + <> select(const Select& s); + + //! prepared select + template + _prepared_statement_t prepare_select(Select& s); + + template + <> run_prepared_select(const PreparedSelect& s); + + //! "direct insert + template + size_t insert(const Insert& i); + + //! prepared insert + template + _prepared_statement_t prepare_insert(Insert& i); + + template + size_t run_prepared_insert(const PreparedInsert& i); + + //! "direct" update + template + size_t update(const Update& u); + + //! "prepared" update + template + _prepared_statement_t prepare_update(Update& u); + + template + size_t run_prepared_update(const PreparedUpdate& u); + + //! "direct" remove + template + size_t remove(const Remove& r) + + //! prepared remove + template + _prepared_statement_t prepare_remove(Remove& r); + + template + size_t run_prepared_remove(const PreparedRemove& r); + + //! call run on the argument + template + auto run(const T& t) -> decltype(t._run(*this)) + { + return t._run(*this); + } + + //! call prepare on the argument + template + auto prepare(const T& t) -> decltype(t._prepare(*this)) + { + return t._prepare(*this); + } + + //! start transaction + void start_transaction(); + + //! commit transaction (or throw transaction if the transaction has been finished already) + void commit_transaction(); + + //! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished already) + void rollback_transaction(bool report); + + //! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor) + void report_rollback_failure(const std::string message) noexcept; + }; + + } +} + +#include + +#endif diff --git a/connector_api/interpreter.h b/connector_api/interpreter.h new file mode 100644 index 00000000..9a83c008 --- /dev/null +++ b/connector_api/interpreter.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_DATABASE_INTERPRETER_H +#define SQLPP_DATABASE_INTERPRETER_H + +#include +#include + +/* + * sqlpp11 offers an interpreter that can be used to serialize the expression tree + * into a standard SQL string. + * + * The connector library can specialize the interpreter template to partially or + * completely change the way the expression tree is interpreted. + * + * For example, this specialization will produce indexed parameters instead of just '?' + */ +namespace sqlpp +{ + namespace vendor + { + template + struct interpreter_t> + { + using T = parameter_t; + + static database::context_t& _(const T& t, database::context_t& context) + { + context << "?" << context.count(); + context.pop_count(); + return context; + } + }; + + } +} + +#endif diff --git a/connector_api/prepared_statement.h b/connector_api/prepared_statement.h new file mode 100644 index 00000000..4a99ee03 --- /dev/null +++ b/connector_api/prepared_statement.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef SQLPP_DATABASE_PREPARED_STATEMENT_H +#define SQLPP_DATABASE_PREPARED_STATEMENT_H + +#include +#include + +namespace sqlpp +{ + namespace database + { + class prepared_statement_t + { + public: + prepared_statement_t() = delete; + prepared_statement_t(...); + prepared_statement_t(const prepared_statement_t&) = delete; + prepared_statement_t(prepared_statement_t&& rhs); + prepared_statement_t& operator=(const prepared_statement_t&) = delete; + prepared_statement_t& operator=(prepared_statement_t&&); + ~prepared_statement_t(); + + bool operator==(const prepared_statement_t& rhs) const; + + // These are called by the sqlpp11::prepared_*_t to bind the individual parameters + void _bind_boolean_parameter(size_t index, const signed char* value, bool is_null); + void _bind_integral_parameter(size_t index, const int64_t* value, bool is_null); + void _bind_text_parameter(size_t index, const std::string* value, bool is_null); + }; + } +} +#endif diff --git a/database_api/api.h b/database_api/api.h deleted file mode 100644 index e3519075..00000000 --- a/database_api/api.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2013, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_DATABASE_API_H -#define SQLPP_DATABASE_API_H - -#include -#include -#include - -namespace sqlpp -{ - namespace connector_name - { - class result - { - public: - result() = default; - result(const result&) = delete; - result(result&& rhs) = default; - result& operator=(const result&) = delete; - result& operator=(result&&) = default; - ~result() = default; - - bool operator==(const result& rhs) const; - - //! return the next row from the result or a "false" row, if there is no next row - sqlpp::raw_result_row_t next(); - size_t num_cols() const; - }; - - class connection: public sqlpp::connection - { - public: - // A bunch of flags telling sqlpp11 which feature is support and which isn't - - // join types - static constexpr bool _supports_inner_join = true; - static constexpr bool _supports_outer_join = true; - static constexpr bool _supports_left_outer_join = true; - static constexpr bool _supports_right_outer_join = true; - - // functions - static constexpr bool _supports_avg = true; - static constexpr bool _supports_count = true; - static constexpr bool _supports_exists = true; - static constexpr bool _supports_like = true; - static constexpr bool _supports_in = true; - static constexpr bool _supports_is_null = true; - static constexpr bool _supports_is_not_null = true; - static constexpr bool _supports_max = true; - static constexpr bool _supports_min = true; - static constexpr bool _supports_not_in = true; - static constexpr bool _supports_sum = true; - - // select - static constexpr bool _supports_group_by = true; - static constexpr bool _supports_having = true; - static constexpr bool _supports_limit = true; - static constexpr bool _supports_order_by = true; - static constexpr bool _supports_select_as_table = true; - - static constexpr bool _supports_some = true; - static constexpr bool _supports_any = true; - static constexpr bool _use_concat_operator = false; - static constexpr bool _use_concat_function = true; - - connection(/*whatever arguments you need*/); - connection(const connection&) = delete; - connection(connection&&) = delete; - connection& operator=(const connection&) = delete; - connection& operator=(connection&&) = delete; - ~connection(); - - //! select returns a result (which can be iterated row by row) - result select(const std::string& query); - - //! insert returns the last auto_incremented id (or zero, if there is none) - size_t insert(const std::string& query); - - //! update returns the number of affected rows - size_t update(const std::string& query); - - //! remove returns the number of removed rows - size_t remove(const std::string& query); - - //! execute arbitrary command (e.g. create a table) - void execute(const std::string& command); - - //! escape given string - std::string escape(const std::string& s) const; - - //! call run on the argument - template - auto run(const T& t) -> decltype(t.run(*this)) - { - return t.run(*this); - } - - //! start transaction - void start_transaction(); - - //! commit transaction (or throw transaction if the transaction has been finished already) - void commit_transaction(); - - //! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished already) - void rollback_transaction(bool report); - - //! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor) - void report_rollback_failure(const std::string message) noexcept; - }; - } -} -#endif