bool db_mysql::sane_mysql_query(const char* sql) { if (conn_ == NULL) { logger_error("db(%s) not opened yet!", dbname_); return false; } if (__mysql_query(conn_, sql) == 0) return true; int errnum = __mysql_errno(conn_); if (errnum != CR_SERVER_LOST && errnum != CR_SERVER_GONE_ERROR) { logger_error("db(%s): sql(%s) error(%s)", dbname_, sql, __mysql_error(conn_)); return false; } /* 重新打开MYSQL连接进行重试 */ close(); if (open("GBK") == false) { logger_error("reopen db(%s) error", dbname_); return false; } if (__mysql_query(conn_, sql) == 0) return true; logger_error("db(%s), sql(%s) error(%s)", dbname_, sql, __mysql_error(conn_)); close(); return false; }
bool db_mysql::sql_select(const char* sql) { if (sane_mysql_query(sql) == false) return false; MYSQL_RES *my_res = __mysql_store_result(conn_); if (my_res == NULL) { if (__mysql_errno(conn_) != 0) { logger_error("db(%s), sql(%s) error(%s)", dbname_, sql, __mysql_error(conn_)); close(); } return false; } my_ulonglong nrow = __mysql_num_rows(my_res); if (nrow <= 0) { __mysql_free_result(my_res); result_ = NULL; return true; } result_ = NEW db_mysql_rows(my_res); return true; }
bool db_mysql::tbl_exists(const char* tbl_name) { if (conn_ == NULL) { logger_error("db(%s) not opened yet", dbname_); return false; } char sql[256]; safe_snprintf(sql, sizeof(sql), "show tables like '%s'", tbl_name); if (sane_mysql_query(sql) == false) return false; MYSQL_RES *my_res = __mysql_store_result(conn_); if (my_res == NULL) { if (__mysql_errno(conn_) != 0) { logger_error("db(%s), sql(%s) error(%s)", dbname_, sql, __mysql_error(conn_)); close(); } return false; } bool ret; if (__mysql_num_rows(my_res) > 0) ret = true; else ret = false; __mysql_free_result(my_res); return ret; }
const char* db_mysql::get_error() const { if (conn_) return __mysql_error(conn_); else return "mysql not opened yet!"; }
bool db_mysql::sql_select(const char* sql, db_rows* result /* = NULL */) { // 优先调用基类方法释放上次的查询结果 free_result(); if (sane_mysql_query(sql) == false) return false; MYSQL_RES *my_res = __mysql_store_result(conn_); if (my_res == NULL) { if (__mysql_errno(conn_) != 0) { logger_error("db(%s), sql(%s) error(%s)", dbname_, sql, __mysql_error(conn_)); close(); } return false; } my_ulonglong nrow = __mysql_num_rows(my_res); if (nrow <= 0) { __mysql_free_result(my_res); result_ = NULL; return true; } if (result != NULL) mysql_rows_save(my_res, *result); else { result_ = NEW db_rows(); mysql_rows_save(my_res, *result_); } return true; }
bool db_mysql::open(const char* local_charset /* = GBK */) { if (conn_) return true; char tmpbuf[256]; char *db_host, *db_unix; int db_port; char* ptr = strchr(dbaddr_, '/'); if (ptr == NULL) { ACL_SAFE_STRNCPY(tmpbuf, dbaddr_, sizeof(tmpbuf)); ptr = strchr(tmpbuf, ':'); if (ptr == NULL || *(ptr + 1) == 0) { logger_error("invalid db_addr=%s", dbaddr_); return false; } else *ptr++ = 0; db_host = tmpbuf; db_port = atoi(ptr); if (db_port <= 0) { logger_error("invalid port=%d", db_port); return false; } db_unix = NULL; } else { db_unix = dbaddr_; db_host = NULL; db_port = 0; } conn_ = __mysql_init(NULL); if (conn_ == NULL) { logger_error("mysql init error"); return false; } if (conn_timeout_ > 0) #if MYSQL_VERSION_ID >= 50500 __mysql_options(conn_, MYSQL_OPT_CONNECT_TIMEOUT, (const void*) &conn_timeout_); #else __mysql_options(conn_, MYSQL_OPT_CONNECT_TIMEOUT, (const char*) &conn_timeout_); #endif if (rw_timeout_ > 0) { #if MYSQL_VERSION_ID >= 50500 __mysql_options(conn_, MYSQL_OPT_READ_TIMEOUT, (const void*) &rw_timeout_); __mysql_options(conn_, MYSQL_OPT_WRITE_TIMEOUT, (const void*) &rw_timeout_); #else __mysql_options(conn_, MYSQL_OPT_READ_TIMEOUT, (const char*) &rw_timeout_); __mysql_options(conn_, MYSQL_OPT_WRITE_TIMEOUT, (const char*) &rw_timeout_); #endif } my_bool reconnect = 1; #if MYSQL_VERSION_ID >= 50500 __mysql_options(conn_, MYSQL_OPT_RECONNECT, (const void*) &reconnect); #else __mysql_options(conn_, MYSQL_OPT_RECONNECT, (const char*) &reconnect); #endif if (__mysql_open(conn_, db_host, dbuser_ ? dbuser_ : "", dbpass_ ? dbpass_ : "", dbname_, db_port, db_unix, dbflags_) == NULL) { logger_error("connect mysql error(%s), db_host=%s, db_port=%d," " db_unix=%s, db_name=%s, db_user=%s, db_pass=%s", __mysql_error(conn_), db_host ? db_host : "null", db_port, db_unix ? db_unix : "null", dbname_, dbuser_, dbpass_); __mysql_close(conn_); conn_ = NULL; return false; } if (local_charset) { if (!__mysql_set_character_set(conn_, local_charset)) logger("set mysql charset to %s, %s", local_charset, __mysql_character_set_name(conn_)); else logger_error("set mysql to %s error %s", local_charset, __mysql_error(conn_)); } #if MYSQL_VERSION_ID >= 50000 if (__mysql_autocommit(conn_, auto_commit_ ? 1 : 0) != 0) { logger_error("mysql_autocommit error"); __mysql_close(conn_); conn_ = NULL; return (false); } #else auto_commit_ = false; #endif return true; }
bool db_mysql::dbopen(const char* charset /* = NULL */) { if (conn_) return true; char tmpbuf[256]; char *db_host, *db_unix; int db_port; char* ptr = strchr(dbaddr_, '/'); if (ptr == NULL) { ACL_SAFE_STRNCPY(tmpbuf, dbaddr_, sizeof(tmpbuf)); ptr = strchr(tmpbuf, ':'); if (ptr == NULL || *(ptr + 1) == 0) { logger_error("invalid db_addr=%s", dbaddr_); return false; } else *ptr++ = 0; db_host = tmpbuf; db_port = atoi(ptr); if (db_port <= 0) { logger_error("invalid port=%d", db_port); return false; } db_unix = NULL; } else { db_unix = dbaddr_; db_host = NULL; db_port = 0; } int* dummy; if (acl_pthread_once(&__thread_once_control, thread_once) != 0) logger_error("call thread_once error: %s", acl_last_serror()); else if (!(dummy = (int*) acl_pthread_getspecific(__thread_key))) { dummy = (int*) acl_mymalloc(sizeof(int)); *dummy = 1; acl_assert(!acl_pthread_setspecific(__thread_key, dummy)); // 调用下面函数可能会造成内存越界 //if (__mysql_thread_init != NULL) // __mysql_thread_init(); if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) { __main_dummy = dummy; atexit(main_free_dummy); } } conn_ = __mysql_init(NULL); if (conn_ == NULL) { logger_error("mysql init error"); return false; } if (conn_timeout_ > 0) #if MYSQL_VERSION_ID >= 50500 __mysql_options(conn_, MYSQL_OPT_CONNECT_TIMEOUT, (const void*) &conn_timeout_); #else __mysql_options(conn_, MYSQL_OPT_CONNECT_TIMEOUT, (const char*) &conn_timeout_); #endif if (rw_timeout_ > 0) { #if MYSQL_VERSION_ID >= 50500 __mysql_options(conn_, MYSQL_OPT_READ_TIMEOUT, (const void*) &rw_timeout_); __mysql_options(conn_, MYSQL_OPT_WRITE_TIMEOUT, (const void*) &rw_timeout_); #else __mysql_options(conn_, MYSQL_OPT_READ_TIMEOUT, (const char*) &rw_timeout_); __mysql_options(conn_, MYSQL_OPT_WRITE_TIMEOUT, (const char*) &rw_timeout_); #endif } my_bool reconnect = 1; #if MYSQL_VERSION_ID >= 50500 __mysql_options(conn_, MYSQL_OPT_RECONNECT, (const void*) &reconnect); #else __mysql_options(conn_, MYSQL_OPT_RECONNECT, (const char*) &reconnect); #endif if (__mysql_open(conn_, db_host, dbuser_ ? dbuser_ : "", dbpass_ ? dbpass_ : "", dbname_, db_port, db_unix, dbflags_) == NULL) { logger_error("connect mysql error(%s), db_host=%s, db_port=%d," " db_unix=%s, db_name=%s, db_user=%s, db_pass=%s," " dbflags=%ld", __mysql_error(conn_), db_host ? db_host : "null", db_port, db_unix ? db_unix : "null", dbname_ ? dbname_ : "null", dbuser_ ? dbuser_ : "null", dbpass_ ? dbpass_ : "null", dbflags_); __mysql_close(conn_); conn_ = NULL; return false; } #if 0 logger("connect mysql ok(%s), db_host=%s, db_port=%d, " "db_unix=%s, db_name=%s, db_user=%s, db_pass=%s, dbflags=%ld", __mysql_error(conn_), db_host ? db_host : "null", db_port, db_unix ? db_unix : "null", dbname_ ? dbname_ : "null", dbuser_ ? dbuser_ : "null", dbpass_ ? dbpass_ : "null", dbflags_); #endif if (charset != NULL && *charset != 0) charset_ = charset; if (!charset_.empty()) { if (!__mysql_set_character_set(conn_, charset_.c_str())) logger("set mysql charset to %s, %s", charset_.c_str(), __mysql_character_set_name(conn_)); else logger_error("set mysql to %s error %s", charset_.c_str(), __mysql_error(conn_)); } #if MYSQL_VERSION_ID >= 50000 if (__mysql_autocommit(conn_, auto_commit_ ? 1 : 0) != 0) { logger_error("mysql_autocommit error"); __mysql_close(conn_); conn_ = NULL; return (false); } #else auto_commit_ = false; #endif return true; }