From c5875724324c4a98ea9ce47522ce002380469b1a Mon Sep 17 00:00:00 2001 From: jie Date: Mon, 14 Oct 2024 18:08:50 +0800 Subject: [PATCH] init --- build.sh | 1 + main.cc | 6 ++++ sqlConnection.h | 87 ++++++++++++++++++++++++++++++++++++++++++++ util.h | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100755 build.sh create mode 100644 main.cc create mode 100644 sqlConnection.h create mode 100644 util.h diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..88b2619 --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +g++ -o demo main.cc -I/usr/include/mysql -lmysqlclient -std=c++23 -g diff --git a/main.cc b/main.cc new file mode 100644 index 0000000..3f7b1b2 --- /dev/null +++ b/main.cc @@ -0,0 +1,6 @@ +#include "sqlConnection.h" + +int main(int argc, char** const argv){ + SqlConnection conn{}; + return 0; +} \ No newline at end of file diff --git a/sqlConnection.h b/sqlConnection.h new file mode 100644 index 0000000..9f28fee --- /dev/null +++ b/sqlConnection.h @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include + +#include "mysql.h" + +#include "util.h" + +using util::_support_string; + +class SqlConnection{ +private: + MYSQL mysql_client; + auto get_error_msg(){ + return mysql_error(&mysql_client); + } + +public: + char* ip; + char* port; + char* username; + char* password; + char* database_name; + + SqlConnection(){ + Init(); + } + ~SqlConnection() noexcept{ + Close(); + } + + SqlConnection(const SqlConnection& other) = delete; + SqlConnection& operator=(const SqlConnection& other) = delete; + + SqlConnection(SqlConnection&& other){ + other.Close(); + this->Connect(other.ip, other.port, other.username, other.password, other.database_name); + } + + SqlConnection& operator=(SqlConnection&& other){ + if(this != &other){ + auto temp = SqlConnection{}; + temp.Connect(other.ip, other.port, other.username, other.password, other.database_name); + other.Close(); + } + return *this; + } + + void Init() noexcept { + mysql_init(&mysql_client); + } + + std::expected Connect(std::string_view _ip, std::string_view _port = "3306", std::string_view _username = "root", std::string_view _password = "", std::string_view _database_name = "mysql"){ + this->ip = util::to_char(_ip); + this->port = util::to_char(_port); + this->username = util::to_char(_username); + this->password = util::to_char(_password); + this->database_name = util::to_char(_database_name); + if(mysql_real_connect(&mysql_client, ip, username, password, database_name, std::stoi(port), nullptr, 0) == nullptr){ + auto error_msg = get_error_msg(); + return std::unexpected(error_msg); + } + return true; + } + + void Close() noexcept { + mysql_close(&mysql_client); + } + + std::optional> Query(std::string_view command){ + //Not Implemented; + return std::nullopt; + } + + bool Execute(std::string_view command){ + //Not Implemented; + return false; + } + + std::vector GetTables(){ + //Not Implemented; + return std::vector{}; + }; + +}; diff --git a/util.h b/util.h new file mode 100644 index 0000000..563b5ef --- /dev/null +++ b/util.h @@ -0,0 +1,96 @@ +#ifndef UTIL_H +#define UTIL_H + +#include +#include +#include +#include +#include + +namespace util{ + namespace ranges = std::ranges; + namespace views = std::ranges::views; + + //util template + + // find the most strong type, + template + struct _strong_type{}; + + template + struct _strong_type{ + using type = T; + }; + + template + struct _strong_type{ + using type = decltype(true ? std::declval() : std::declval()); + }; + + template + struct _strong_type{ + using type = + typename _strong_type::type>::type; + }; + + template + using _strong_type_t = typename _strong_type::type; + + //can type T convert to Args... + template + struct _is_castable{}; + + template + struct _is_castable{ + static constexpr bool value = true; + using type = T; + }; + + template + struct _is_castable{ + using __true = char; + using __false = struct {char _[2];}; + static consteval __true __test(U); + static consteval __false __test(...); + static constexpr bool value = sizeof(__test(std::declval())) == sizeof(__true); + using type = std::conditional; + }; + + template + struct _is_castable{ + static constexpr bool value = _is_castable::type>::value; + using type = std::conditional; + }; + + template + using _is_castable_v = _is_castable::value; + + //type can convert to const char*, char* std::string, std::string_view; + template + concept _support_string = requires{ + _is_castable::value; + }; + + //util function + template<_support_string T> + std::vector split_str(T str, T d){ + auto view = views::split(str, d) | views::transform([](auto word){return std::string_view{word.begin(), word.end()};}); + return std::vector{view.begin(), view.end()}; + }; + + template<_support_string T> + char* to_char(T str){ + if constexpr (std::is_same_v || std::is_same_v){ + return const_cast(str); + } + if constexpr (std::is_same_v){ + return const_cast(str.c_str()); + } + if constexpr (std::is_same_v){ + return const_cast(str.data()); + } + } + +}; + +#endif \ No newline at end of file