mysql.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #pragma once
  2. #include <vector>
  3. #include <string>
  4. #include <queue>
  5. #include <memory>
  6. #include <sstream>
  7. #include <unordered_map>
  8. #ifndef _WIN32
  9. #include <stddef.h>
  10. #endif
  11. #include "base/define.h"
  12. #include "base/error.h"
  13. #include "base/buffer.h"
  14. #include "util/json.h"
  15. #include "util/pool.hpp"
  16. namespace ylib::mysql
  17. {
  18. class pool;
  19. class result;
  20. class conn;
  21. class prepare_statement;
  22. // 与 MySQL Connector/C++ sql::DataType 数值对齐
  23. enum class field_type : int {
  24. UNKNOWN = 0,
  25. BIT,
  26. TINYINT,
  27. SMALLINT,
  28. MEDIUMINT,
  29. INTEGER,
  30. BIGINT,
  31. REAL,
  32. DOUBLE,
  33. DECIMAL,
  34. NUMERIC,
  35. CHAR,
  36. BINARY,
  37. VARCHAR,
  38. VARBINARY,
  39. LONGVARCHAR,
  40. LONGVARBINARY,
  41. TIMESTAMP,
  42. DATE,
  43. TIME,
  44. YEAR,
  45. GEOMETRY,
  46. ENUM,
  47. SET,
  48. SQLNULL,
  49. JSON
  50. };
  51. struct field {
  52. uint32 index = 0; // 列下标,从 1 开始
  53. std::string name;
  54. field_type type = field_type::UNKNOWN;
  55. bool is_unsigned = false;
  56. };
  57. // 单列取值:从 ResultSet 读出后独立保存
  58. class data {
  59. public:
  60. data() = default;
  61. bool is_null() const { return m_hold == hold::null; }
  62. field_type type() const { return m_type; }
  63. int32 to_int32() const;
  64. uint32 to_uint32() const;
  65. int64 to_int64() const;
  66. uint64 to_uint64() const;
  67. bool to_boolean() const;
  68. double to_double() const;
  69. std::string to_string() const;
  70. ylib::buffer to_blob() const;
  71. friend class result;
  72. friend class row;
  73. private:
  74. enum class hold {
  75. null,
  76. i64,
  77. u64,
  78. f64,
  79. boolean,
  80. str,
  81. blob
  82. };
  83. hold m_hold = hold::null;
  84. field_type m_type = field_type::UNKNOWN;
  85. int64 m_i64 = 0;
  86. uint64 m_u64 = 0;
  87. double m_f64 = 0;
  88. bool m_bool = false;
  89. std::string m_str;
  90. ylib::buffer m_blob;
  91. };
  92. // 整行数据:支持按索引 / 字段名取值,并可转为 json 对象
  93. class row {
  94. public:
  95. row() = default;
  96. size_t size() const { return m_values.size(); }
  97. bool empty() const { return m_values.empty(); }
  98. bool has(const std::string& name) const;
  99. // 列下标从 1 开始
  100. const data& get(uint32 index) const;
  101. const data& get(const std::string& name) const;
  102. const data& operator[](uint32 index) const { return get(index); }
  103. const data& operator[](const std::string& name) const { return get(name); }
  104. const field& field_info(uint32 index) const;
  105. const std::vector<field>& fields() const { return m_fields; }
  106. ylib::json to_json() const;
  107. friend class result;
  108. private:
  109. std::vector<field> m_fields;
  110. std::vector<data> m_values;
  111. std::unordered_map<std::string, uint32> m_name_index; // value: 0-based
  112. };
  113. struct mysql_conn_info
  114. {
  115. mysql_conn_info() {
  116. port = 0;
  117. }
  118. std::string ipaddress;
  119. std::string username;
  120. std::string password;
  121. std::string database;
  122. std::string charset;
  123. uint32 port;
  124. };
  125. class result :public ylib::error_base
  126. {
  127. public:
  128. result(void* handle);
  129. ~result();
  130. // 列名
  131. std::string field_name(uint32 index);
  132. // 列数量
  133. uint32 field_count();
  134. // 行数量
  135. size_t row_count();
  136. // 下一行
  137. bool next();
  138. // 按列下标(从1开始) / 列名取值
  139. ylib::mysql::data get(uint32 index);
  140. ylib::mysql::data get(const std::string& name);
  141. // 获取当前整行
  142. ylib::mysql::row get_row();
  143. // 当前行转 json 对象
  144. ylib::json row_to_json();
  145. private:
  146. uint32 field_index(const std::string& name) const;
  147. ylib::mysql::data read_data(uint32 index) const;
  148. void* m_handle = nullptr;
  149. std::vector<ylib::mysql::field> m_fields;
  150. std::unordered_map<std::string, uint32> m_field_index;
  151. };
  152. class prepare_statement :public ylib::error_base {
  153. public:
  154. prepare_statement();
  155. ~prepare_statement();
  156. void set_bigint(uint32 index, const std::string& value);
  157. void set_boolean(uint32 index, bool value);
  158. void set_datetime(uint32 index, const std::string& value);
  159. void set_double(uint32 index, double value);
  160. void set_int32(uint32 index, int32 value);
  161. void set_uint32(uint32 index, uint32 value);
  162. void set_int64(uint32 index, int64 value);
  163. void set_uint64(uint32 index, uint64 value);
  164. void set_null(uint32 index);
  165. void set_string(uint32 index, const std::string& value);
  166. void set_string(uint32 index,const char* data,int size);
  167. void set_blob(uint32 index, const char* data, int size);
  168. void clear();
  169. uint64 update();
  170. ylib::mysql::result* query();
  171. friend class ylib::mysql::conn;
  172. private:
  173. ylib::mysql::result* m_result = nullptr;
  174. void* m_handle = nullptr;
  175. // 持有 blob 流,保证 execute 前有效(仅一次拷贝进 stringstream)
  176. std::queue<std::shared_ptr<std::stringstream>> m_blobs;
  177. };
  178. class conn :public ylib::example<ylib::mysql::mysql_conn_info>, public ylib::error_base
  179. {
  180. public:
  181. conn();
  182. ~conn();
  183. virtual EXAMPLE_START_RESULT start(const ylib::mysql::mysql_conn_info& info) override;
  184. virtual void close() override;
  185. virtual void recover() override;
  186. virtual void task_out() override;
  187. void clear();
  188. ylib::mysql::prepare_statement* setsql(const std::string& sql);
  189. uint64 insert_id();
  190. void begin(bool autocommit = false);
  191. void commit();
  192. void rollback();
  193. void setDatabase(const std::string& name);
  194. friend class ylib::mysql::pool;
  195. private:
  196. void* m_handle = nullptr;
  197. ylib::mysql::mysql_conn_info m_info;
  198. class prepare_statement* m_ppst = nullptr;
  199. // 事务状态 0=未开启 1=已开启
  200. int m_sw = 0;
  201. };
  202. // 连接池:增量配置,未填字段用默认值
  203. // ylib::pool_options opt;
  204. // opt.max_size = 50; // 只改需要的项
  205. // pool.start(info, opt);
  206. class pool : public ylib::pool<ylib::mysql::conn, ylib::mysql::mysql_conn_info>
  207. {
  208. public:
  209. pool() = default;
  210. ~pool() = default;
  211. };
  212. }