c-mysql (commonly used)

MySQL C API use (basic functions)
liaoxuefeng SQL
understands the above basic knowledge, to wrap some functions for c use

accept_mysql is used to connect to the database

MYSQL   accept_mysql()
{
    
    
    MYSQL   mysql;
    if(NULL==mysql_init(&mysql)){
    
    
        err_sys("mysql_init err",__LINE__);
    }
    if(mysql_library_init(0,NULL,NULL)!=0){
    
    
        err_sys("mysql_init err",__LINE__);
    }
    if(NULL==mysql_real_connect(&mysql,"127.0.0.1","root","sss","chatroom",0,NULL,0))
        err_sys("mysql_real_connect",__LINE__);
    if(mysql_set_character_set(&mysql,"utf8")<0)
        err_sys("mysql_set_character_set",__LINE__);
    printf("连接数据库成功\n");
    return  mysql;
}

close_mysql (close the database)


int close_mysql(MYSQL   mysql)
{
    
    
    mysql_close(&mysql);
    mysql_library_end();
    return  0;
}

use_mysql
return 1 represents no data.
return -1 represents an error in the mysql statement
(used to query the database or modify the data in the database, but the disadvantage of this function is that select can only print and cannot send a single data)

int use_mysql(const char*string,MYSQL mysql)
{
    
    
    int i;
    int ret;
    unsigned    int num_fields,num_rows;
    MYSQL mysql_temp=mysql;
    MYSQL_RES  *result=NULL;
    MYSQL_ROW       row;
    MYSQL_FIELD *field;
    ret=mysql_query(&mysql_temp,string);
    if(!ret){
    
    
        result  =   mysql_store_result(&mysql_temp);
        if(result){
    
    
            num_rows=mysql_num_rows(result);
            if(num_rows==0){
    
    
                mysql_free_result(result);
                return  1;
            }        
            num_fields  =mysql_num_fields(result);
            while (field=mysql_fetch_field(result)){
    
    
                printf("%-20s",field->name);
            }
            printf("\n");

            while(row=mysql_fetch_row(result)){
    
    
                for ( i = 0; i < num_fields; i++){
    
    
                    if(row[i]){
    
    
                        printf("%-20s",row[i]);
                    }else{
    
    
                        printf("NULL");
                    }
                }
                printf("\n");
            }
        }else{
    
    
            mysql_free_result(result);
            return  1;
        }
    mysql_free_result(result);
    }
    else{
    
    
    	fprintf(stderr,"query err\n");
        return -1;
    }
    return  0;
}

And if I want to get every data of select, the method I take is to open up dynamic memory, but the disadvantage is that after calling this function, you have to manually free it, which will be very cumbersome, and the location of memory development must be in the function, because it is impossible to determine how much Row results, and only the function returns 0 or -2 to be free. You need if judgment when calling a function.
Call method

mysqlMsg*mmsglist=NULL;
int mNum=0;
int ret=mysqlGetMsgByUid(mysql,x,&mmsglist,mMum);
if(ret==-2){
    
    
	...
	if(mmsglist!=NULL){
    
    
                free(mmsglist);
                mmsglist=NULL;
      }
}else if(ret==0){
    
    
	...
	if(mmsglist!=NULL){
    
    
                free(mmsglist);
                mmsglist=NULL;
      }
}else{
    
    
	...
}

(If you have any better way, you can teach me)

int mysqlGetMsgByUid(MYSQL mysql,int uid,mysqlMsg**mMsgList,int *mNum)
{
    
    
    int i=0;
    int ret;
    unsigned    int num_fields,num_rows;
    MYSQL mysql_temp=mysql;
    MYSQL_RES  *result=NULL;
    MYSQL_ROW       row;
    MYSQL_FIELD *field;
    char table[MYSQL_TABLE_LEN]="message";
    char mysql_order[MYSQL_ORDER_MAXLEN];
    *mNum=0;
    
    snprintf(mysql_order,MYSQL_ORDER_MAXLEN," select id,uid,type,sid,msg,status,flag from %s \
        where uid ='%d' \
        ",table,uid);
    ret=mysql_query(&mysql_temp,mysql_order);
    if(!ret){
    
    
        result  =   mysql_store_result(&mysql_temp);
        if(result){
    
    
            // num_fields  =mysql_num_fields(result);        
            num_rows= mysql_num_rows(result);
            if(num_rows==0){
    
    
                    mysql_free_result(result);
                    return  1;
                }        
            *mNum=num_rows;
            *(mMsgList)=malloc(num_rows*sizeof(mysqlMsg));
            memset(*mMsgList,0,sizeof (num_rows*sizeof(mysqlMsg)));
            while(row=mysql_fetch_row(result)){
    
       
                if((!row[0])||(!row[6])||(!row[1])||(!row[2])||(!row[3])||(!row[4])||(!row[5])){
    
    
                    mysql_free_result(result);
                    fprintf(stderr,"出现 NULL");                    
                    return  -2;
                }
                (*(mMsgList)+i)->id=atoi(row[0]);
                (*(mMsgList)+i)->recv_id=atoi(row[1]);
                (*(mMsgList)+i)->type=atoi(row[2]);
                (*(mMsgList)+i)->send_id=atoi(row[3]);
                strncpy((*(mMsgList)+i)->message,row[4],MYSQL_MSG_SIZE);
                (*(mMsgList)+i)->status=atoi(row[5]);
                (*(mMsgList)+i)->flag=atoi(row[6]);
                // (*(mMsgList)+i)->recv_id=uid;
                i++;
            }
        }else{
    
    
             mysql_free_result(result);
            return  1;
        }
        mysql_free_result(result);
    }else{
    
    
        fprintf(stderr,"???query   fail\n");
        return -1;
    }
    return  0;
}



Add, delete, modify, and check mysql statements frequently used in chat rooms
insert into xxx(name,xxxx,xx)values(xx,xxx,xxxx);
delete from xxx where x=y;
update xxx set x1=y1,x2=y2
select xxx from xx where x= y;

create table
AUTO_INCREMENT auto-increment
ENGINE=InnoDB engine
PRIMARY KEY ( id) primary key

The meaning of NOT NULL ("mysql must know and know")

Columns that do not allow NULL values ​​will not accept rows that have no value in the column.
In other words, when inserting or updating rows, the column must have a value.

use_mysql("create table account(\
    id BIGINT NOT NULL AUTO_INCREMENT,\
    姓名 varchar(20) NOT NULL ,\
    帐号 varchar(20) NOT NULL UNIQUE,\
    PRIMARY KEY (`id`)\
    )ENGINE=InnoDB 
          AUTO_INCREMENT=1
           DEFAULT CHARSET=utf8",mysql);


It is indeed much more convenient to encapsulate mysql into classes in C++. At the same time, it is divided into mysql_noResult_query
, mysql_select_query, and mysql_select_SingleLine_query (this is not necessary). Because of the dynamic expansion characteristics of vector and map containers, there is no need for the above-mentioned C version troublesome. Dynamic memory.

class mysql_db
{
    
    
public:
    mysql_db();
    ~mysql_db();
public:
    /*
        mysql_open()
        return : 1 OK
                -1 失败
     */
    int mysql_open(const char * host, const char * user, const char * password, const char * database, unsigned int port );
    /*
        mysql_noResult_query();
        非select语句查询
        return >0 成功, 为受影响的行数
               -1 失败
     */
    int mysql_noResult_query(const char * sql );
    /*
        mysql_select_query();
        有结果集的查询
        return >0 ok 返回结果集条数
               -1 失败
        map_results first = 行 second = values
        */
    int mysql_select_query(const char * sql, map<int,vector<string>> & map_results);
    /*
        mysql_select_SingleLine_query();
        只有一条数据 , 或者只有一个字段 N 条的查询. 直接调用vector即可
     */
    int mysql_select_SingleLine_query(const char * sql, vector<string> & v_results);
    /*
        mysql_lasterror();
        返回最近一次错误信息
     */
    string mysql_lasterror();
private:
    MYSQL sqlCon;
    MYSQL_RES *m_pResult;
    MYSQL_ROW  m_Row;
};



mysql_db::mysql_db() {
    
    
    mysql_init(&sqlCon);// mysql 初始化
}

mysql_db::~mysql_db() {
    
    
    mysql_close(&sqlCon);// 关闭连接
}

int mysql_db::mysql_open(const char *host, const char *user, const char *password, const char *database,
                         unsigned int port) {
    
    
    char nvalue = 1;
    mysql_options(&sqlCon, MYSQL_OPT_RECONNECT, (char *) &nvalue);// 断线自动重连
    mysql_options(&sqlCon, MYSQL_SET_CHARSET_NAME, "utf8");
    if (!mysql_real_connect(&sqlCon, host, user, password, database, port, NULL, 0)) {
    
    
        return -1;
    }
    return 1;
}

int mysql_db::mysql_noResult_query(const char *sql) {
    
    
    if (mysql_query(&sqlCon, sql) != 0) {
    
    
        return -1;
    }
    return (int) mysql_affected_rows(&sqlCon);
}

int mysql_db::mysql_select_query(const char *sql, map<int, vector<string>> &map_results) {
    
    
    if (mysql_query(&sqlCon, sql) != 0) {
    
    
        return -1;
    }
    if(!(m_pResult = mysql_use_result(&sqlCon))){
    
    
        return -1;
    }
    int i=0;
    int count = mysql_num_fields(m_pResult);
    while(m_Row=mysql_fetch_row(m_pResult)){
    
    
        vector<string>vVal;
        for (int j = 0; j < count; ++j) {
    
    
            if(m_Row[j])
                vVal.push_back(m_Row[j]);
            else
                vVal.push_back("null");
        }
        map_results[i++]=vVal;
    }
    mysql_free_result(m_pResult);
    return i;
}

int mysql_db::mysql_select_SingleLine_query(const char *sql, vector<string> &v_results) {
    
    
    if (mysql_query(&sqlCon, sql) != 0) {
    
    
        return -1;
    }
    if(!(m_pResult = mysql_use_result(&sqlCon))){
    
    
        return -1;
    }
    int count = mysql_num_fields(m_pResult);
    while(m_Row=mysql_fetch_row(m_pResult)){
    
    
        for (int j = 0; j < count; ++j) {
    
    
            v_results.push_back(m_Row[j]);
        }
    }
    mysql_free_result(m_pResult);
    return 0;
}

string mysql_db::mysql_lasterror() {
    
    
    return mysql_error(&sqlCon);
}

Regarding the design of the table, I think I did a bad design in the chat room. There are 9 tables. Since my name is placed in the account table, I did not design how to change the name. Because the secret security is placed in the account table, the group account must be rebuilt instead of the person account. The file table and the group file table are also scored, which makes the procedure more cumbersome.
I don’t know if the fri_mask table is used to block friends’ messages. . .

Although the design is not good the first time, at least the program can run, and with experience, it will not be so difficult next time.

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/adlatereturn/article/details/107281562