#include "cpps_mysql.h"#include "cpps_mysql_record.h"#include "cpps_mysql_result.h"namespace cpps{cpps_mysql::cpps_mysql(){connect_state = false;isreconnect = true;port = 3306;mysql = NULL;mysql_stmt = NULL;affectedrows = 0;}cpps_mysql::~cpps_mysql(){close();}void cpps_mysql::setcstate(cpps::C* cstate){c = cstate;}bool cpps_mysql::connect(C *cstate,cpps::object option){setcstate(cstate);if (cpps::type(option["db"]) == CPPS_TSTRING) db = cpps::object_cast<std::string>(option["db"]);if (cpps::type(option["host"]) == CPPS_TSTRING) host = cpps::object_cast<std::string>(option["host"]);if (cpps::type(option["user"]) == CPPS_TSTRING) user = cpps::object_cast<std::string>(option["user"]);if (cpps::type(option["passwd"]) == CPPS_TSTRING) passwd = cpps::object_cast<std::string>(option["passwd"]);if (cpps::type(option["port"]) == CPPS_TINTEGER || cpps::type(option["port"]) == CPPS_TUINTEGER) port = cpps::object_cast<cpps::usint16>(option["port"]);if (cpps::type(option["isreconnect"]) == CPPS_TBOOLEAN) isreconnect = cpps::object_cast<bool>(option["isreconnect"]);return real_connect();}void cpps_mysql::close(){if (mysql_stmt){mysql_stmt_close(mysql_stmt);mysql_stmt = NULL;}if (mysql){mysql_close(mysql);mysql = NULL;}connect_state = false;affectedrows = 0;}cpps::cpps_value cpps_mysql::call(std::string spname, cpps::cpps_value params) {std::string proc = "call ";proc += spname;proc += "(";cpps_vector* vec = cpps_to_cpps_vector(params);static cpps_vector tmp_empty_vector; //emptyif (!vec)vec = &tmp_empty_vector;if (vec->size() > 0) {for (size_t i = 0; i < vec->realvector().size(); i++){if (i != 0)proc += ",";proc += "?";}}proc += ");";return execute(proc, params);}cpps::cpps_value cpps_mysql::execute(std::string proc, cpps::cpps_value params){cpps::cpps_value nil;cpps_vector* vec = cpps_to_cpps_vector(params);static cpps_vector tmp_empty_vector; //emptyif (!vec)vec = &tmp_empty_vector;std::vector< MYSQL_BIND > paramlist;std::vector< MYSQL_BINDDATA > paramDatalist;if (vec->size() > 0) {paramlist.resize(size_t(vec->size()));paramDatalist.resize(size_t(vec->size()));memset(paramlist.data(), 0, sizeof(MYSQL_BIND) * size_t(vec->size()));//填充参数数据for (size_t i = 0; i < vec->realvector().size(); i++){paramlist[i].buffer = paramDatalist[i].buff;paramlist[i].length = ¶mDatalist[i].length;#ifdef MARIADB_BASE_VERSIONparamlist[i].is_null = (my_bool*)¶mDatalist[i].is_null;#elseparamlist[i].is_null = ¶mDatalist[i].is_null;#endifcpps_value& v = vec->realvector()[i];paramDatalist[i].is_null = false;if (v.tt == CPPS_TBOOLEAN){bool n = v.value.b;memcpy(paramDatalist[i].buff, (const void*)&n, sizeof(bool));paramDatalist[i].length = sizeof(bool);paramlist[i].buffer_type = MYSQL_TYPE_TINY;paramlist[i].buffer_length = sizeof(bool);}else if (v.tt == CPPS_TINTEGER){cpps_integer n = v.value.integer;memcpy(paramDatalist[i].buff, (const void*)&n, sizeof(cpps_integer));paramDatalist[i].length = sizeof(cpps_integer);paramlist[i].buffer_type = MYSQL_TYPE_LONGLONG;paramlist[i].buffer_length = sizeof(cpps_integer);}else if (v.tt == CPPS_TUINTEGER){cpps_uinteger n = v.value.uinteger;memcpy(paramDatalist[i].buff, (const void*)&n, sizeof(cpps_uinteger));paramDatalist[i].length = sizeof(cpps_uinteger);paramlist[i].buffer_type = MYSQL_TYPE_LONGLONG;paramlist[i].buffer_length = sizeof(cpps_uinteger);}else if (v.tt == CPPS_TNUMBER){cpps_number n = v.value.number;memcpy(paramDatalist[i].buff, (const void*)&n, sizeof(cpps_number));paramDatalist[i].length = sizeof(cpps_number);paramlist[i].buffer_type = MYSQL_TYPE_DOUBLE;paramlist[i].buffer_length = sizeof(cpps_number);}else if (v.tt == CPPS_TSTRING){std::string* s = cpps_get_string(v);memcpy(paramDatalist[i].buff, (const void*)s->c_str(), s->size());paramDatalist[i].length = (unsigned long)s->size();paramlist[i].buffer_type = MYSQL_TYPE_VAR_STRING;paramlist[i].buffer_length = (unsigned long)s->size();}else{paramDatalist[i].is_null = true;}}}if (!checkconnect() && !real_connect()){return nil;}if (mysql_stmt_prepare(mysql_stmt, proc.c_str(), (unsigned long)proc.size())){//如果断开连接了,那么尝试重连if (!checkconnect() && !real_connect()){return nil;}//尝试再次转换if (mysql_stmt_prepare(mysql_stmt, proc.c_str(), (unsigned long)proc.size())){seterror(mysql_stmt_error(mysql_stmt));return nil;}}if (paramlist.size() > 0) {//传入参数if (mysql_stmt_bind_param(mysql_stmt, paramlist.data())){seterror(mysql_stmt_error(mysql_stmt));return nil;}}//执行语句if (mysql_stmt_execute(mysql_stmt)){seterror(mysql_stmt_error(mysql_stmt));return nil;}affectedrows = mysql_stmt_affected_rows(mysql_stmt);cpps_create_class_var(cpps_vector, c, cpps_vector_var, cpps_vector_ptr);result_build_records(cpps_vector_ptr,false);return cpps_vector_var;}bool cpps_mysql::checkconnect(){//已经断开过连接了。if (mysql_stmt == NULL) return false;//检测当前连接状态if ((mysql_stmt_errno(mysql_stmt) == CR_SERVER_GONE_ERROR) ||(mysql_stmt_errno(mysql_stmt) == CR_SERVER_LOST) ||(mysql_stmt_errno(mysql_stmt) == CR_CONN_HOST_ERROR)){seterror(mysql_stmt_error(mysql_stmt));return false;}return true;}cpps::cpps_value cpps_mysql::make_cpps_value(enum_field_types type, void* buffer, unsigned long size ){cpps::cpps_value ret;if (type == MYSQL_TYPE_DOUBLE ){cpps_number n = (cpps_number)(*(cpps_number*)(buffer));ret = n;}else if(type == MYSQL_TYPE_FLOAT){cpps_number n = (cpps_number)(*(float*)(buffer));ret = n;}else if (IS_NUM(type)){cpps_integer n = 0;n = (cpps_integer)(*(cpps::int64*)(buffer));ret = n;}else if (IS_LONGDATA(type)){std::string string_ptr;string_ptr.append((const char *)buffer, size);ret = cpps_value(c, string_ptr);}else{//what??}return ret;}void cpps_mysql::result_build_records(cpps_vector* vec,bool is_mysql_stmt_store_result){do{MYSQL_RES* m_mysql_result = mysql_stmt_result_metadata(mysql_stmt);if (m_mysql_result){cpps_create_class_var(cpps_mysql_result, c, cpps_mysql_result_var, cpps_mysql_result_ptr);vec->push_back(cpps_mysql_result_var);uint64_t m_num_rows;MYSQL_FIELD* m_fields = mysql_fetch_fields(m_mysql_result);int m_num_fields = mysql_num_fields(m_mysql_result);if (m_fields && m_num_fields != 0){std::vector< MYSQL_BIND > resultlist;std::vector< MYSQL_BINDDATA > resultDatalist;resultlist.resize(m_num_fields);resultDatalist.resize(m_num_fields);memset(resultlist.data(), 0, sizeof(MYSQL_BIND) * m_num_fields);//填充数据BINDfor (int i = 0; i < m_num_fields; i++){resultlist[i].buffer_type = m_fields[i].type;resultlist[i].buffer = resultDatalist[i].buff;resultlist[i].length = &resultDatalist[i].length;resultlist[i].buffer_length = BINDDATA_SIZE;#ifdef MARIADB_BASE_VERSIONresultlist[i].is_null = (my_bool*)&resultDatalist[i].is_null;#elseresultlist[i].is_null = &resultDatalist[i].is_null;#endif}if (mysql_stmt_bind_result(mysql_stmt, resultlist.data())){seterror(mysql_stmt_error(mysql_stmt));clear(m_mysql_result);return;}int err = mysql_stmt_store_result(mysql_stmt);if (is_mysql_stmt_store_result && err != 0){seterror(mysql_stmt_error(mysql_stmt));clear(m_mysql_result);return;}m_num_rows = mysql_stmt_num_rows(mysql_stmt);for (uint64_t i = 0; i < m_num_rows; i++){memset(resultDatalist.data(), 0, sizeof(MYSQL_BINDDATA) * m_num_fields);mysql_stmt_fetch(mysql_stmt);cpps_create_class_var(cpps_mysql_record, c, cpps_mysql_record_var, cpps_mysql_record_ptr);for (int j = 0; j < m_num_fields; j++){cpps::cpps_value v = make_cpps_value(m_fields[j].type, resultlist[j].buffer, resultDatalist[j].length);cpps_mysql_record_ptr->add(cpps_value(c,m_fields[j].name), v);}cpps_mysql_result_ptr->vct_records.push_back(cpps_mysql_record_var);}}mysql_free_result(m_mysql_result);m_mysql_result = NULL;mysql_stmt_free_result(mysql_stmt);}} while (mysql_stmt_next_result(mysql_stmt) == 0);}bool cpps_mysql::real_connect(){close();mysql = mysql_init(NULL);if (!mysql){connect_state = false;seterror(mysql_error(mysql));return false;}if (mysql != mysql_real_connect(mysql, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, NULL, (CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS ))){connect_state = false;seterror(mysql_error(mysql));return false;}mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);//初始化stmtmysql_stmt = mysql_stmt_init(mysql);if (!mysql_stmt){connect_state = false;seterror(mysql_stmt_error(mysql_stmt));return false;}unsigned long true_value = CURSOR_TYPE_READ_ONLY;mysql_stmt_attr_set(mysql_stmt, STMT_ATTR_CURSOR_TYPE, (void*)&true_value);bool flag = false;mysql_stmt_attr_set(mysql_stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &flag);execute("set names utf8;");execute("set global max_prepared_stmt_count=65536;");connect_state = true;return true;}bool cpps_mysql::isconnect(){return connect_state && checkconnect();}std::string cpps_mysql::error(){return errorstr;}void cpps_mysql::seterror(std::string str){errorstr = str;}cpps_integer cpps_mysql::affected_rows(){return affectedrows;}void cpps_mysql::clear(MYSQL_RES* m_mysql_result){do{if (!m_mysql_result)m_mysql_result = mysql_store_result(mysql);mysql_free_result(m_mysql_result);m_mysql_result = NULL;mysql_stmt_free_result(mysql_stmt);} while (!mysql_next_result(mysql));}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型