Code Monkey home page Code Monkey logo

sql_wrapper's Introduction

sql_wrapper

// windows 下编译记得修改报错的文件编码

封装mysql官方的cppconn c++接口的更高级封装(需要自行下载mysql cppconn),使增删改查变得更加modern c++。

测试代码:

#include "sql_wrapper.h"

int main()
{
	sql_wrapper sql_("tcp://127.0.0.1:3306", "root", "123456", "game");
	bool ret_ = false;

	// 创建
	ret_ = sql_.create("create table test (id_ double, name_ varchar(64), password_ varchar(64)); ");

	// 添加
	ret_ = sql_.insert("insert into test (id_, name_, password_) values (0.1, '0.2', '0.3');"),
	// 添加 —> 带参数
	ret_ = sql_.insert("insert into test (id_, name_, password_) values (?, ?, ?);",
		std::tuple<double, std::string, std::string>(0.11118, "0.2", "0.2"));
	// 添加 —> 带参数
	ret_ = sql_.insert("insert into test (id_, name_, password_) values (?, ?, ?);",
		std::tuple<double, std::string, std::string>(0.8, "0.2", "0.2"));

	// 删除
	ret_ = sql_.remove("delete from test where id_ = '0.3';");
	// 删除 —> 带参数
	ret_ = sql_.remove("delete from test where id_ = ?;", std::tuple<std::string>("0.11118"));

	// 更新
	ret_ = sql_.update("update test set id_ = 0.1, name_ = 'test' where password_ = 0.1;"),
	// 更新 —> 带参数
	ret_ = sql_.update("update test set id_ = ?, name_ = ? where password_ = ?;",
		std::tuple<double, std::string, std::string>(0.2, "humorly", "0.2"));

	std::vector<std::tuple<double, std::string, std::string>> user_content_;
	// 查询
	ret_ = sql_.select("select * from test;",
		std::tuple <>(),
		std::tuple<std::string, std::string, std::string>("id_", "name_", "password_"),
		user_content_);

	std::cout << "content:" << std::endl;
	for (auto& val : user_content_)
	{
		std::cout << "id_ = " << std::get<0>(val) << ", ";
		std::cout << "name_ = " << std::get<1>(val) << ", ";
		std::cout << "password_ = " << std::get<2>(val) << std::endl;
	}

	// 查询 —> 带参数
	user_content_.clear();
	ret_ = sql_.select("select id_, name_, password_ from test where password_ = ?;",
		std::tuple <std::string>("0.2"),
		std::tuple<std::string, std::string, std::string>("id_", "name_", "password_"),
		user_content_);

	std::cout << "content:" << std::endl;
	for (auto& val : user_content_)
	{
		std::cout << "id_ = " << std::get<0>(val) << ", ";
		std::cout << "name_ = " << std::get<1>(val) << ", ";
		std::cout << "password_ = " << std::get<2>(val) << std::endl;
	}

	return 0;
}
  

sql_wrapper's People

Contributors

humorly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sql_wrapper's Issues

移除 MySQL Connector/C++中的boost依赖

修改对应MySQL Connector库目录下的 ...\include\jdbc\mysql_connection.h 文件

  1. 移除包含boost 智能指针头文件,替换以c++标准智能指针 头文件;
  2. 替换boost::shared_ptr为 std::shared_ptr,修改boost::scoped_ptr为std::unique_ptr;

修改该文件后的源码如下:
mysql_connection.h

/*
 * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2.0, as
 * published by the Free Software Foundation.
 *
 * This program is also distributed with certain software (including
 * but not limited to OpenSSL) that is licensed under separate terms,
 * as designated in a particular file or component or in included license
 * documentation.  The authors of MySQL hereby grant you an
 * additional permission to link the program and your derivative works
 * with the separately licensed software that they have included with
 * MySQL.
 *
 * Without limiting anything contained in the foregoing, this file,
 * which is part of MySQL Connector/C++, is also subject to the
 * Universal FOSS Exception, version 1.0, a copy of which can be found at
 * http://oss.oracle.com/licenses/universal-foss-exception.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License, version 2.0, for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 */



#ifndef _MYSQL_CONNECTION_H_
#define _MYSQL_CONNECTION_H_

#include "cppconn/connection.h"
#include <memory>

namespace sql
{
	namespace mysql
	{

		class MySQL_Savepoint : public sql::Savepoint
		{
			sql::SQLString name;

		public:
			MySQL_Savepoint(const sql::SQLString& savepoint);
			virtual ~MySQL_Savepoint() {}

			int getSavepointId();

			sql::SQLString getSavepointName();

		private:
			/* Prevent use of these */
			MySQL_Savepoint(const MySQL_Savepoint&);
			void operator=(MySQL_Savepoint&);
		};


		class MySQL_DebugLogger;
		struct MySQL_ConnectionData; /* PIMPL */
		class MySQL_Statement;

		namespace NativeAPI
		{
			class NativeConnectionWrapper;
		}

		class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection
		{
			MySQL_Statement* createServiceStmt();

		public:
			MySQL_Connection(Driver* _driver,
				::sql::mysql::NativeAPI::NativeConnectionWrapper& _proxy,
				const sql::SQLString& hostName,
				const sql::SQLString& userName,
				const sql::SQLString& password);

			MySQL_Connection(Driver* _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper& _proxy,
				std::map< sql::SQLString, sql::ConnectPropertyVal >& options);

			virtual ~MySQL_Connection();

			void clearWarnings();

			void close();

			void commit();

			sql::Statement* createStatement();

			sql::SQLString escapeString(const sql::SQLString&);

			bool getAutoCommit();

			sql::SQLString getCatalog();

			Driver* getDriver();

			sql::SQLString getSchema();

			sql::SQLString getClientInfo();

			void getClientOption(const sql::SQLString& optionName, void* optionValue);

			sql::SQLString getClientOption(const sql::SQLString& optionName);

			sql::DatabaseMetaData* getMetaData();

			enum_transaction_isolation getTransactionIsolation();

			const SQLWarning* getWarnings();

			bool isClosed();

			bool isReadOnly();

			bool isValid();

			bool reconnect();

			sql::SQLString nativeSQL(const sql::SQLString& sql);

			sql::PreparedStatement* prepareStatement(const sql::SQLString& sql);

			sql::PreparedStatement* prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys);

			sql::PreparedStatement* prepareStatement(const sql::SQLString& sql, int columnIndexes[]);

			sql::PreparedStatement* prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency);

			sql::PreparedStatement* prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability);

			sql::PreparedStatement* prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]);

			void releaseSavepoint(Savepoint* savepoint);

			void rollback();

			void rollback(Savepoint* savepoint);

			void setAutoCommit(bool autoCommit);

			void setCatalog(const sql::SQLString& catalog);

			void setSchema(const sql::SQLString& catalog);

			sql::Connection* setClientOption(const sql::SQLString& optionName, const void* optionValue);

			sql::Connection* setClientOption(const sql::SQLString& optionName, const sql::SQLString& optionValue);

			void setHoldability(int holdability);

			void setReadOnly(bool readOnly);

			sql::Savepoint* setSavepoint();

			sql::Savepoint* setSavepoint(const sql::SQLString& name);

			void setTransactionIsolation(enum_transaction_isolation level);

			virtual sql::SQLString getSessionVariable(const sql::SQLString& varname);

			virtual void setSessionVariable(const sql::SQLString& varname, const sql::SQLString& value);

			virtual void setSessionVariable(const sql::SQLString& varname, unsigned int value);

			virtual sql::SQLString getLastStatementInfo();

		private:
			/* We do not really think this class has to be subclassed*/
			void checkClosed();
			void init(std::map< sql::SQLString, sql::ConnectPropertyVal >& properties);

			Driver* driver;

#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
			std::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy;
#ifdef _WIN32
#pragma warning(pop)
#endif

			/* statement handle to execute queries initiated by driver. Perhaps it is
			   a good idea to move it to a separate helper class */
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
			std::unique_ptr< ::sql::mysql::MySQL_Statement > service;

			std::unique_ptr< ::sql::mysql::MySQL_ConnectionData > intern; /* pimpl */
#ifdef _WIN32
#pragma warning(pop)
#endif

  /* Prevent use of these */
			MySQL_Connection(const MySQL_Connection&);
			void operator=(MySQL_Connection&);
		};

	} /* namespace mysql */
} /* namespace sql */

#endif // _MYSQL_CONNECTION_H_

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */

使用std::tuple实现mysql查询时静态反射

测试代码:

	sql_warpper sql_("tcp://127.0.0.1:3306", "root", "123456", "gamed");
	bool ret_ = false;
	ret_ = sql_.create("create table test (id_ double, name_ varchar(64), password_ varchar(64)); ");
	ret_ = sql_.insert("insert into test values(5.12056683, \"humorly\", \"chen123\");");
	ret_ = sql_.insert("insert into test values(5.12056684, \"humorly\", \"chen123\");");
	ret_ = sql_.insert("insert into test values(5.12056685, \"humorly\", \"chen123\");");
	ret_ = sql_.remove("delete from test  where id_ = 5.12056684;");
	ret_ = sql_.update("update game.test set id_ = 5.55555555 where id_ = 5.12056683;");

	// 待搜索的字段信息
	std::tuple<std::string, std::string, std::string> params_("id_", "name_", "password_");
	std::vector<std::tuple<double, std::string, std::string>> user_content_;
	ret_ = sql_.select("SELECT * FROM test", user_content_, params_);

	std::cout << "content:" << std::endl;
	for (auto & val : user_content_)
	{
		std::cout << "id_ = " << std::get<0>(val) << ", ";
		std::cout << "name_ = " << std::get<1>(val) << ", ";
		std::cout << "password_ = " << std::get<2>(val) << std::endl;
	}

	return 0;

封装过程:
使用mysql等数据库在查询时无法避免一个问题,在作select操作时,经常要调用mysql对象中的getInt、getString、getByte、getDouble...,并且要将mysql中的sql::ResultSet对象公开(或以接口提供),其中mysql提供的cppconn也没有很好的解决方案。这里做了一番思考,为何不把对象的查询字段做一个tuple封装,传递给查询接口对应的”字段名称“。再做一个tuple传递结果字段的对应类型,并将查询到的“字段值”存储到其中。该过程中对tuple进行展开让编译器去调用getInt、getString、getByte、getDouble...等,代码设计如下:

1:设计一个获取字段值的tuple,必须与select操作需要的字段值对应,用来将其中的“字段名称”传递给getInt等方法作为参数,例如设计搜索表user_content中的"id_", "name_", "password_"(其中id_值类型为int,其他为varchar(string)); 则有展开字段模板:

std::tuple<std::string, std::string, std::string> params_("id_", "name_", "password_");

2:设计一个接收结果的tuple,用来接收表中搜索到的字段类型结果:

std::tuple<int, std::string, std::string> user_content_;

3:将select语句、content_、parm_传递到展开接口separation中:

bool select(const std::string & command, std::vector<__dest_type> & dest, __set parm)
{
	try {
		pstmt_ = con_->prepareStatement(command.c_str());
		res_ = pstmt_->executeQuery();
		res_->afterLast();
		while (res_->previous())
		{
			// 这里进行参数展开
			// 将res传入其中,待稍后参数展开时get对应的字段值
			separation<__dest_type, sql::ResultSet, __set, __type, params...>(dest, res_, parm);
		}
		delete res_;
		delete pstmt_;
	}
	catch (sql::SQLException &e) {
		std::string str_logger_("sql error by create select -> code is " + 
			std::to_string(e.getErrorCode()) + " & describe is " + std::string(e.what()));
		wstd::log_writer::log_store(str_logger_, __FILE_LINE__);
		return false;
	}
	return true;
}

4:展开过程解释:

std::vector<__dest_type> & separation(std::vector<__dest_type> & dest, __value_type * src, __set parm)
	{
		__dest_type tu_;
		// 获取字段列表parm待展开的参数数目
		constexpr int size_ = sizeof...(params);
		// 对参数进行递归展开
		get_class<0, size_>::template get<__dest_type, __value_type, __set, T, params...>(tu_, src, parm);

		dest.push_back(tu_);
		return dest;
	}

5:逐字段赋值过程

template<integer_type N, integer_type M>
	struct get_class
	{
		template <typename __dest, typename __src, typename __set, typename T, typename ... params>
		inline static void get(__dest & dest, __src * src, __set parm)
		{
			constexpr integer_type index_ = N + 1;
			// 对tuple中的第N个元素赋值
			// 右侧通过偏特化dest中的模板参数调用对应的get value方法
			std::get<N>(dest) = get_value_type<T, __src, const char *>::template get_value(src, std::get<N>(parm).c_str());
			// 递归下一字段
			get_class<index_, M>::template get<__dest, __src, __set, params...>(dest, src, parm);
		}
	};

// 递归到末元素时只赋值无需继续递归
// 末元素即为N = M,即偏特化M,M
template<integer_type M>
	struct get_class<M, M>
	{
		template <typename __dest, typename __src, typename __set, typename T>
		inline static void get(__dest & dest, __src * src, __set parm)
		{
			// 末元素赋值
			std::get<M>(dest) = get_value_type<T, __src, const char *>::template get_value(src, std::get<M>(parm).c_str());
		}
	};

6:偏特化get value过程:

	template<typename __value_type, typename __dest_type, typename __parm>
	struct get_value_type
	{
		inline static auto get_value(__dest_type * val, __parm parm) {}
	};

	// bigint
	template<typename __dest_type, typename __parm>
	struct get_value_type<integer_type, __dest_type, __parm>
	{
		inline static auto get_value(__dest_type * val, __parm parm) -> decltype(val->getInt64(parm))
		{
			return val->getInt64(parm);
		}
	};

	// varchar
	template<typename __dest_type, typename __parm>
	struct get_value_type<std::string, __dest_type, __parm>
	{
		inline static std::string get_value(__dest_type * val, __parm parm)
		{
			return val->getString(parm).c_str();
		}
	};
	
	// 其他类型在这里照例补充偏特化

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.