본문 바로가기

Computer Science/C 언어

[C언어] mysql 라이브러리 (libmysql)

C API libmysql

libmysql은 C언어에서 MySQL을 사용할 수 있도록 제공하는 C API 입니다. libmysql을 사용하기 위해서는 가장 우선적으로 mysql_init(), mysql_real_connect()통해 데이터베이스에 연결해줍니다. 이후, MySQL API들을 사용한 후, mysql_close()를 통해 종료시켜줍니다. 

 

Connection API

MYSQL * mysql_init(MYSQL *mysql)
MYSQL * mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, 
				unsigned int port, const char *unix_socket, unsigned long client_flag)
void mysql_close(MYSQL *mysql)

1. Prepared statement 방식을 사용하기 위해서는 mysql_stmt_init()로 초기화를 해줍니다. 

2. 서버에 statement를 prepare하기 위해, mysql_stmt_prepare()를 호출하고 SQL statement를 포함해서 string을 전달해줍니다.

3. mysql_stmt_bind_param()을 사용하여 파라미터에 값을 셋팅해줍니다. 

4. 위 과정을 모두 마친 후, statement를 실행하기 위해 mysql_stmt_execute()를 호출합니다. 

 

mysql_stmt_execute() 함수가 호출될 때, MySQL client/server protocol은 아래 내용을 수행합니다. 

  • 클라이언트는 statement handler를 사용하고 서버에 parameter data를 보냅니다. 
  • 이후, 서버는 클라이언트에 의해 제공되는 ID를 사용하여 statement를 식별하고 새롭게 제공된 데이터로 parameter markers를 대체하고, statement를 실행합니다. 만일 statement가 result set을 생성하면, 서버는 클라이언트에게 전달합니다. 만일 그렇지 않으면, 상태(status)를 전달하고 수정, 삭제, 삽입된 rows 수를 반환합니다. 

Statement API

MYSQL_STMT * mysql_stmt_init(MYSQL *mysql)
int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *stmt_str, unsigned long length)
bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)
int mysql_stmt_execute(MYSQL_STMT *stmt)

Compile

gcc -I/usr/local/include/mysql -lmysqlclient c_api_mysql.c -o c_api_mysql

Code (INSERT Query)

#include <stdio.h>
#include <mysql.h> 
#include <string.h> 

#define INSERT_CORPUS "INSERT INTO \
                        corpus (num_of_corpus) \
                        VALUES (?)" 
void test_stmt_error(MYSQL_STMT * stmt, int status)  {
    if ( status ) { 
        fprintf(stderr, "Error: %s\n", mysql_stmt_error(stmt)) ; 
        exit(1) ; 
    }  
}

int main(void) { 
    MYSQL * mysql ; 

    if ( (mysql = mysql_init(NULL)) == NULL) { 
        fprintf(stderr, "there was insufficient memory to allocate a new object.") ; 
        exit(1);
    } 
    
    if (!mysql_real_connect(mysql, "host", "userid", "passwd", "dbname", 0, NULL, 0)) {
        fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(mysql)); 
    } 

    MYSQL_BIND param_buf ; /* input parameter buffers */
    MYSQL_STMT * stmt ;    
    int corpus_count ;     /* input/output values */
    int status ; 

    stmt = mysql_stmt_init(mysql) ; 
    if ( !stmt )  {
        fprintf(stderr, "mysql_stmt_init(), out of memory\n") ; 
        exit(0); 
    }

    status = mysql_stmt_prepare(stmt, INSERT_CORPUS, strlen(INSERT_CORPUS)) ; 
    test_stmt_error(stmt, status); 

    param_buf.buffer_type = MYSQL_TYPE_LONG ; // INT
    param_buf.buffer = (char *) &corpus_count ; 
    param_buf.length = 0 ; 
    param_buf.is_null = 0 ; 

    status = mysql_stmt_bind_param(stmt, &param_buf) ; 
    test_stmt_error(stmt, status) ; 

    corpus_count = 200; // 값 셋팅

    status = mysql_stmt_execute(stmt) ; 
    test_stmt_error(stmt, status) ; 

    mysql_close(mysql) ; 
    return 0 ;
}

 

참고 문헌 

[1] https://downloads.mysql.com/docs/c-api-8.0-en.a4.pdf