C language MYSQL library, C++ lightweight package (functional programming)

Solve the problem:

  1. Support BLOB type CURD (addition, deletion, modification and query)

  1. Support for special string types

  1. Secure Database Command Execution

Export function:

DB2_ExecuteQuery Executes a database query

DB2_ExecuteNonQuery Execute database commands, return value: -1, SQL problem/link failure, 0, no data change, >= 1 command affects the number of database rows

DB2_FetchAllRows Get all row data

DB2_FetchRowValue Gets the row’s column data

DB2_ParameterStatement parameter declaration (support: string, BLOB, various C/C++ basic syntax value types)

 if (!DB2_ExecuteQuery(m_Mysql, statement, statement_size,
            [ & amp;](int, MYSQL_RES* results)
            {
                DB2_FetchAllRows(results,
                    [results, reply](int, MYSQL_ROW rows)
                    {
                        return DB2_FetchRowValue(results, rows, 1, DB2_FetchRowValue<int>(results, rows, 0),
                            [reply](char* blob_data, int blob_size)
                            {
                                reply->add_orders(blob_data, blob_size);
                                return false;
                            });
                    });
            }))
        {
            reply->set_error(PROTO_GS_ERROR_SALTYFISH_FINDORDER_FROM_DATABASESERVER_EXECUTE_QUERY_TSQL_ERROR);
            break;
        }

        if (!DB2_ExecuteQuery(m_Mysql, statement, statement_size,
            [ & amp; dataPtr](int, MYSQL_RES* results)
            {
                MYSQL_ROW rows;
                while (rows = mysql_fetch_row(results))
                {
                    std::string cdkey = DB2_FetchRowValue<std::string>(results, rows, 0);
                    if (cdkey. empty())
                    {
                        continue;
                    }


                    dataPtr->add_account(cdkey);
                }
            }))
        {
            LogErr("DBThread::UserLogin mysql_query error");
            return NULL;
        }

    std::string statement = "insert into t_saltyfish(`guid`, `zone_id`, `seller`, `buyer`, `order_data`, `order_size`) value(";
    statement + = DB2_ParameterStatement(m_Mysql, CDBThread4Read_SaltyFish_Guid(msg->guid())) + ", ";
    statement + = DB2_ParameterStatement(m_Mysql, g_Config.GetZoneID()) + ", ";
    statement + = DB2_ParameterStatement(m_Mysql, msg->seller()) + ", ";
    statement + = DB2_ParameterStatement(m_Mysql, msg->buyer()) + ", ";
    statement + = DB2_ParameterStatement(m_Mysql, msg->order()) + ", ";
    statement + = DB2_ParameterStatement(m_Mysql, msg->order().size()) + ");";
    DB2_ExecuteNonQuery(m_Mysql, statement);

C/C ++ DB2.h lightweight database operation function package

#pragma once

#include <string>
#include <memory>

#include "MySqlCpp.h"
#include "DBBase.h"
#include "DBHead.h"

template <typename ExecuteHandler>
inline int DB2_ExecuteStatement(MySql & amp; mysql, const char* statement, int max_statement_size, ExecuteHandler & amp; & amp; handler) noexcept
{
    MYSQL* h = mysql. GetConnection();
    if (NULL == h)
    {
        return -1;
    }

    if (NULL == statement || max_statement_size < 1)
    {
        return -1;
    }

    if (mysql_real_query(h, statement, max_statement_size))
    {
        int err = mysql_errno(h);
        if (err == CR_SERVER_GONE_ERROR || err == CR_UNKNOWN_ERROR || err == CR_SERVER_LOST)
        {
            mysql. CloseConnection();
        }

        return -1;
    }

    return handler(h);
}

template <typename ExecuteHandler>
inline bool DB2_ExecuteQuery(MYSQL* mysql, ExecuteHandler & amp; & amp; handler) noexcept
{
    if (NULL == mysql)
    {
        return false;
    }

    int dataTable = -1;
    do
    {
        // FETCH MORE RESULTS
        MYSQL_RES* results = mysql_store_result(mysql);
        if (NULL == results)
        {
            break;
        }
        
        // FORWARD
        handler( + + dataTable, results);

        // NOP
        MYSQL_ROW rows;
        while (rows = mysql_fetch_row(results));

        // FREE
        mysql_free_result(results);
    } while (mysql_more_results(mysql));
    return dataTable > -1;
}

template <typename ExecuteHandler>
inline bool DB2_ExecuteQuery(MySql & amp; mysql, const char* statement, int max_statement_size, ExecuteHandler & amp; & amp; handler) noexcept
{
    int err = DB2_ExecuteStatement(mysql, statement, max_statement_size,
        [ & amp;handler](MYSQL* h) noexcept
        {
            return DB2_ExecuteQuery(h, handler) ? 0 : 1;
        });
    return err > -1;
}

template <typename ExecuteHandler>
inline bool DB2_ExecuteQuery(MySql & amp; mysql, const std::string & amp; statement, ExecuteHandler & amp; & amp; handler) noexcept
{
    return DB2_ExecuteQuery(mysql, statement.data(), statement.size(), handler);
}

inline int DB2_ExecuteNonQuery(MySql & amp; mysql, const char* statement, int max_statement_size) noexcept
{
    return DB2_ExecuteStatement(mysql, statement, max_statement_size,
        [](MYSQL* h) noexcept
        {
            return mysql_affected_rows(h);
        });
}

inline int DB2_ExecuteNonQuery(MySql & amp; mysql, const std::string & amp; statement) noexcept
{
    return DB2_ExecuteNonQuery(mysql, statement. data(), statement. size());
}

inline std::string DB2_ParameterStatement(MySql & amp; mysql, const void* data, int data_size) noexcept
{
    MYSQL* h = mysql. GetConnection();
    if (NULL == h)
    {
        return "''";
    }

    if (NULL == data || data_size < 1)
    {
        return "''";
    }

    int buf_size = data_size << 1 + 3;
    if (buf_size < 1)
    {
        return "''";
    }

    char* buf = (char*)SafeMalloc(buf_size);
    if (NULL == buf)
    {
        return "''";
    }
    else
    {
        buf[0] = '\'';
    }

    int len = mysql_real_escape_string(h, buf + 1, (char*)data, data_size);
    if (len < 1)
    {
        SafeFree(buf);
        return "''";
    }
    else
    {
        buf[ + + len] = '\'';
        buf[ + + len] = '\x0';

        std::string r = std::string(buf, len);
        SafeFree(buf);

        return std::move(r);
    }
}

template <typename PredicateHandler>
inline MYSQL_ROW DB2_FetchAllRows(MYSQL_RES* results, PredicateHandler & amp; & amp; predicate) noexcept
{
    if (NULL == results)
    {
        return NULL;
    }

    int rowsindex = 0;
    MYSQL_ROW rows = NULL;

    while (rows = mysql_fetch_row(results))
    {
        if (predicate(rowsindex + + , rows))
        {
            return rows;
        }
    }

    return NULL;
}

template <typename FetchValueHandler>
inline bool DB2_FetchRowValue(MYSQL_RES* results, MYSQL_ROW rows, int fields_index, int fields_size, FetchValueHandler & amp; & amp; handler) noexcept
{
    if (NULL == results || NULL == rows || fields_index < 0)
    {
        return false;
    }

    unsigned int num_fields = mysql_num_fields(results);
    if (fields_index >= num_fields)
    {
        return false;
    }

    if (fields_size < 1)
    {
        ulong* fetch_lengths = mysql_fetch_lengths(results);
        if (NULL == fetch_lengths)
        {
            return false;
        }

        fields_size = fetch_lengths[fields_index];
    }

    char* fields_data = (char*)rows[fields_index];
    if (NULL == fields_data)
    {
        if (fields_size > 0)
        {
            return false;
        }
        else
        {
            fields_data = "";
            fields_size = 0;
        }
    }

    return handler(fields_data, fields_size);
}

inline std::string DB2_FetchRowValue(MYSQL_RES* results, MYSQL_ROW rows, int fields_index, int fields_size) noexcept
{
    std::string v;
    if (!DB2_FetchRowValue(results, rows, fields_index, fields_size,
        [ & amp;v](char* fields_data, int fields_size) noexcept
        {
            v.append(fields_data, fields_size);
            return true;
        }))
    {
        return "";
    }
    return std::move(v);
}

template <typename TValue>
inline TValue DB2_FetchRowValue(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept;

template <>
inline long long DB2_FetchRowValue<long long>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return atoll(v. data());
}

template <>
inline long DB2_FetchRowValue<long>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return atol(v. data());
}

template <>
inline int DB2_FetchRowValue<int>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return atoi(v. data());
}

template <>
inline short DB2_FetchRowValue<short>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<int>(results, rows, fields_index);
}

template <>
inline char DB2_FetchRowValue<char>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<int>(results, rows, fields_index);
}

template <>
inline unsigned long long DB2_FetchRowValue<unsigned long long>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return strtoull(v. data(), NULL, 10);
}

template <>
inline unsigned long DB2_FetchRowValue<unsigned long>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return strtoul(v. data(), NULL, 10);
}

template <>
inline unsigned int DB2_FetchRowValue<unsigned int>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<unsigned long>(results, rows, fields_index);
}

template <>
inline unsigned short DB2_FetchRowValue<unsigned short>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<unsigned long>(results, rows, fields_index);
}

template <>
inline unsigned char DB2_FetchRowValue<unsigned char>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<unsigned long>(results, rows, fields_index);
}

template <>
inline long double DB2_FetchRowValue<long double>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return strtold(v. data(), NULL);
}

template <>
inline double DB2_FetchRowValue<double>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    std::string v = DB2_FetchRowValue(results, rows, fields_index, -1);
    return strtod(v. data(), NULL);
}

template <>
inline wchar_t DB2_FetchRowValue<wchar_t>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<unsigned long>(results, rows, fields_index);
}

template <>
inline bool DB2_FetchRowValue<bool>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue<unsigned long>(results, rows, fields_index) != 0;
}

template <>
inline std::string DB2_FetchRowValue<std::string>(MYSQL_RES* results, MYSQL_ROW rows, int fields_index) noexcept
{
    return DB2_FetchRowValue(results, rows, fields_index, -1);
}

template <typename T>
inline std::string DB2_ParameterStatement(MySql & amp; mysql, const T & amp; value) noexcept { return std::to_string(value); }

template <>
inline std::string DB2_ParameterStatement<std::string>(MySql & amp; mysql, const std::string & amp; value) noexcept { return DB2_ParameterStatement(mysql, value.data(), value.size()); }

inline std::string DB2_ParameterStatement(MySql & amp; mysql, const char* value) noexcept { return DB2_ParameterStatement<std::string>(mysql, NULL != value ? value : ""); }

inline std::string DB2_ParameterStatement(MySql & amp; mysql, char* value) noexcept { return DB2_ParameterStatement(mysql, const_cast<const char*>(value)); }

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge