| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- #pragma once
- #include <vector>
- #include <string>
- #include <queue>
- #include <memory>
- #include <sstream>
- #include <unordered_map>
- #ifndef _WIN32
- #include <stddef.h>
- #endif
- #include "base/define.h"
- #include "base/error.h"
- #include "base/buffer.h"
- #include "util/json.h"
- #include "util/pool.hpp"
- namespace ylib::mysql
- {
- class pool;
- class result;
- class conn;
- class prepare_statement;
- // 与 MySQL Connector/C++ sql::DataType 数值对齐
- enum class field_type : int {
- UNKNOWN = 0,
- BIT,
- TINYINT,
- SMALLINT,
- MEDIUMINT,
- INTEGER,
- BIGINT,
- REAL,
- DOUBLE,
- DECIMAL,
- NUMERIC,
- CHAR,
- BINARY,
- VARCHAR,
- VARBINARY,
- LONGVARCHAR,
- LONGVARBINARY,
- TIMESTAMP,
- DATE,
- TIME,
- YEAR,
- GEOMETRY,
- ENUM,
- SET,
- SQLNULL,
- JSON
- };
- struct field {
- uint32 index = 0; // 列下标,从 1 开始
- std::string name;
- field_type type = field_type::UNKNOWN;
- bool is_unsigned = false;
- };
- // 单列取值:从 ResultSet 读出后独立保存
- class data {
- public:
- data() = default;
- bool is_null() const { return m_hold == hold::null; }
- field_type type() const { return m_type; }
- int32 to_int32() const;
- uint32 to_uint32() const;
- int64 to_int64() const;
- uint64 to_uint64() const;
- bool to_boolean() const;
- double to_double() const;
- std::string to_string() const;
- ylib::buffer to_blob() const;
- friend class result;
- friend class row;
- private:
- enum class hold {
- null,
- i64,
- u64,
- f64,
- boolean,
- str,
- blob
- };
- hold m_hold = hold::null;
- field_type m_type = field_type::UNKNOWN;
- int64 m_i64 = 0;
- uint64 m_u64 = 0;
- double m_f64 = 0;
- bool m_bool = false;
- std::string m_str;
- ylib::buffer m_blob;
- };
- // 整行数据:支持按索引 / 字段名取值,并可转为 json 对象
- class row {
- public:
- row() = default;
- size_t size() const { return m_values.size(); }
- bool empty() const { return m_values.empty(); }
- bool has(const std::string& name) const;
- // 列下标从 1 开始
- const data& get(uint32 index) const;
- const data& get(const std::string& name) const;
- const data& operator[](uint32 index) const { return get(index); }
- const data& operator[](const std::string& name) const { return get(name); }
- const field& field_info(uint32 index) const;
- const std::vector<field>& fields() const { return m_fields; }
- ylib::json to_json() const;
- friend class result;
- private:
- std::vector<field> m_fields;
- std::vector<data> m_values;
- std::unordered_map<std::string, uint32> m_name_index; // value: 0-based
- };
- struct mysql_conn_info
- {
- mysql_conn_info() {
- port = 0;
- }
- std::string ipaddress;
- std::string username;
- std::string password;
- std::string database;
- std::string charset;
- uint32 port;
- };
- class result :public ylib::error_base
- {
- public:
- result(void* handle);
- ~result();
- // 列名
- std::string field_name(uint32 index);
- // 列数量
- uint32 field_count();
- // 行数量
- size_t row_count();
- // 下一行
- bool next();
- // 按列下标(从1开始) / 列名取值
- ylib::mysql::data get(uint32 index);
- ylib::mysql::data get(const std::string& name);
- // 获取当前整行
- ylib::mysql::row get_row();
- // 当前行转 json 对象
- ylib::json row_to_json();
- ylib::json table();
- private:
- uint32 field_index(const std::string& name) const;
- ylib::mysql::data read_data(uint32 index) const;
- void* m_handle = nullptr;
- std::vector<ylib::mysql::field> m_fields;
- std::unordered_map<std::string, uint32> m_field_index;
- };
- class prepare_statement :public ylib::error_base {
- public:
- prepare_statement();
- ~prepare_statement();
- void set_bigint(uint32 index, const std::string& value);
- void set_boolean(uint32 index, bool value);
- void set_datetime(uint32 index, const std::string& value);
- void set_double(uint32 index, double value);
- void set_int32(uint32 index, int32 value);
- void set_uint32(uint32 index, uint32 value);
- void set_int64(uint32 index, int64 value);
- void set_uint64(uint32 index, uint64 value);
- void set_null(uint32 index);
- void set_string(uint32 index, const std::string& value);
- void set_string(uint32 index,const char* data,int size);
- void set_blob(uint32 index, const char* data, int size);
- void clear();
- uint64 update();
- ylib::mysql::result* query();
- friend class ylib::mysql::conn;
- private:
- ylib::mysql::result* m_result = nullptr;
- void* m_handle = nullptr;
- // 持有 blob 流,保证 execute 前有效(仅一次拷贝进 stringstream)
- std::queue<std::shared_ptr<std::stringstream>> m_blobs;
- };
- class conn :public ylib::example<ylib::mysql::mysql_conn_info>, public ylib::error_base
- {
- public:
- conn();
- ~conn();
- virtual EXAMPLE_START_RESULT start(const ylib::mysql::mysql_conn_info& info) override;
- virtual void close() override;
- virtual void recover() override;
- virtual void task_out() override;
- void clear();
- ylib::mysql::prepare_statement* setsql(const std::string& sql);
- uint64 insert_id();
- void begin(bool autocommit = false);
- void commit();
- void rollback();
- void setDatabase(const std::string& name);
- friend class ylib::mysql::pool;
- private:
- void* m_handle = nullptr;
- ylib::mysql::mysql_conn_info m_info;
- class prepare_statement* m_ppst = nullptr;
- // 事务状态 0=未开启 1=已开启
- int m_sw = 0;
- };
- // 连接池:增量配置,未填字段用默认值
- // ylib::pool_options opt;
- // opt.max_size = 50; // 只改需要的项
- // pool.start(info, opt);
- class pool : public ylib::pool<ylib::mysql::conn, ylib::mysql::mysql_conn_info>
- {
- public:
- pool() = default;
- ~pool() = default;
- };
- }
|