68 #include <mysqld_error.h>    72 #if MYSQL_VERSION_ID >= 80000 && !defined(MARIADB_BASE_VERSION)    84 static inline int mysql_er_temp(
const int rc)
    87     case ER_LOCK_WAIT_TIMEOUT:
    88     case ER_LOCK_DEADLOCK:
    89     case ER_GET_TEMPORARY_ERRMSG:
   101 static void *mysql_open_conn(
const DBConf *db_conf)
   111     mysql = gw_malloc(
sizeof(MYSQL));
   115     if (!mysql_init(mysql)) {
   116         error(0, 
"MYSQL: init failed!");
   117         error(0, 
"MYSQL: %s", mysql_error(mysql));
   125                             conf->
port, NULL, 0)) {
   126         error(0, 
"MYSQL: can not connect to database!");
   127         error(0, 
"MYSQL: %s", mysql_error(mysql));
   132     info(0, 
"MYSQL: server version %s, client version %s.",
   133            mysql_get_server_info(mysql), mysql_get_client_info());
   144 static void mysql_close_conn(
void *conn)
   149     mysql_close((MYSQL*) conn);
   154 static int mysql_check_conn(
void *conn)
   159     if (mysql_ping((MYSQL*) conn)) {
   160         error(0, 
"MYSQL: database check failed!");
   161         error(0, 
"MYSQL: %s", mysql_error(conn));
   169 static int mysql_select(
void *conn, 
const Octstr *sql, 
List *binds, 
List **res)
   173     MYSQL_BIND *bind = NULL;
   180     stmt = mysql_stmt_init((MYSQL*) conn);
   182         error(0, 
"MYSQL: mysql_stmt_init(), out of memory.");
   186         error(0, 
"MYSQL: Unable to prepare statement: %s", mysql_stmt_error(stmt));
   187         mysql_stmt_close(stmt);
   193         bind = gw_malloc(
sizeof(MYSQL_BIND) * binds_len);
   194         memset(bind, 0, 
sizeof(MYSQL_BIND) * binds_len);
   195         for (i = 0; i < binds_len; i++) {
   198             bind[i].buffer_type = MYSQL_TYPE_STRING;
   203         if (mysql_stmt_bind_param(stmt, bind)) {
   204           error(0, 
"MYSQL: mysql_stmt_bind_param() failed: `%s'", mysql_stmt_error(stmt));
   206           mysql_stmt_close(stmt);
   212     if (mysql_stmt_execute(stmt)) {
   213         error(0, 
"MYSQL: mysql_stmt_execute() failed: `%s'", mysql_stmt_error(stmt));
   215         mysql_stmt_close(stmt);
   220 #define DESTROY_BIND(bind, binds_len)           \   223         for (i = 0; i < binds_len; i++) {       \   224             gw_free(bind[i].buffer);            \   225             gw_free(bind[i].length);            \   226             gw_free(bind[i].is_null);           \   232     result = mysql_stmt_result_metadata(stmt);
   234         error(0, 
"MYSQL: mysql_stmt_result_metadata() failed: `%s'", mysql_stmt_error(stmt));
   235         mysql_stmt_close(stmt);
   239     binds_len = mysql_num_fields(result);
   240     bind = gw_malloc(
sizeof(MYSQL_BIND) * binds_len);
   241     memset(bind, 0, 
sizeof(MYSQL_BIND) * binds_len);
   243     for (i = 0; i < binds_len; i++) {
   244         MYSQL_FIELD *field = mysql_fetch_field(result); 
   246         debug(
"gwlib.dbpool_mysql", 0, 
"column=%s buffer_type=%d max_length=%ld length=%ld", field->name, field->type, field->max_length, field->length);
   248         switch(field->type) {
   249         case MYSQL_TYPE_TIME:
   250         case MYSQL_TYPE_DATE:
   251         case MYSQL_TYPE_DATETIME:
   252         case MYSQL_TYPE_TIMESTAMP:
   253             bind[i].buffer_type = field->type;
   254             bind[i].buffer = (
char*)gw_malloc(
sizeof(MYSQL_TIME));
   255             bind[i].is_null = gw_malloc(
sizeof(my_bool));
   256             bind[i].length = gw_malloc(
sizeof(
unsigned long));
   259             bind[i].buffer_type = MYSQL_TYPE_STRING;
   260             bind[i].buffer = gw_malloc(field->length);
   261             bind[i].buffer_length = field->length;
   262             bind[i].length = gw_malloc(
sizeof(
unsigned long));
   263             bind[i].is_null = gw_malloc(
sizeof(my_bool));
   267     mysql_free_result(result);
   269     if (mysql_stmt_bind_result(stmt, bind)) {
   270         error(0, 
"MYSQL: mysql_stmt_bind_result() failed: `%s'", mysql_stmt_error(stmt));
   271         DESTROY_BIND(bind, binds_len);
   272         mysql_stmt_close(stmt);
   277     while(!(ret = mysql_stmt_fetch(stmt))) {
   279         for (i = 0; i < binds_len; i++) {
   283             if (*bind[i].is_null) {
   288             switch(bind[i].buffer_type) {
   289             case MYSQL_TYPE_DATE:
   291                 str = 
octstr_format(
"%04d-%02d-%02d", ts->year, ts->month, ts->day);
   293             case MYSQL_TYPE_TIME:
   294             case MYSQL_TYPE_DATETIME:
   295             case MYSQL_TYPE_TIMESTAMP:
   297                 str = 
octstr_format(
"%04d-%02d-%02d %02d:%02d:%02d", ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second);
   300                 if (bind[i].length == 0)
   310     DESTROY_BIND(bind, binds_len);
   314     if (ret != MYSQL_NO_DATA) {
   316         error(0, 
"MYSQL: mysql_stmt_bind_result() failed: `%s'", mysql_stmt_error(stmt));
   317         mysql_stmt_close(stmt);
   325     mysql_stmt_close(stmt);
   331 static int mysql_update(
void *conn, 
const Octstr *sql, 
List *binds)
   334     MYSQL_BIND *bind = NULL;
   339     stmt = mysql_stmt_init((MYSQL*) conn);
   341         error(0, 
"MYSQL: mysql_stmt_init(), out of memory.");
   345         error(0, 
"MYSQL: Unable to prepare statement: `%s'", mysql_stmt_error(stmt));
   346         mysql_stmt_close(stmt);
   352         bind = gw_malloc(
sizeof(MYSQL_BIND) * binds_len);
   353         memset(bind, 0, 
sizeof(MYSQL_BIND) * binds_len);
   354         for (i = 0; i < binds_len; i++) {
   357             bind[i].buffer_type = MYSQL_TYPE_STRING;
   362         if (mysql_stmt_bind_param(stmt, bind)) {
   363           error(0, 
"MYSQL: mysql_stmt_bind_param() failed: `%s'", mysql_stmt_error(stmt));
   365           mysql_stmt_close(stmt);
   372     ret = mysql_stmt_execute(stmt);
   374         ret = mysql_stmt_errno(stmt);
   375         if (mysql_er_temp(ret)) {
   376             warning(0, 
"MYSQL: mysql_stmt_execute() failed: %d: `%s'. Retrying.", ret, mysql_stmt_error(stmt));
   380             error(0, 
"MYSQL: mysql_stmt_execute() failed: %d: `%s'", ret, mysql_stmt_error(stmt));
   382             mysql_stmt_close(stmt);
   388     ret = mysql_stmt_affected_rows(stmt);
   389     mysql_stmt_close(stmt);
   395 static void mysql_conf_destroy(
DBConf *db_conf)
   409 static struct db_ops mysql_ops = {
   410     .
open = mysql_open_conn,
   411     .close = mysql_close_conn,
   412     .check = mysql_check_conn,
   413     .select = mysql_select,
   414     .update = mysql_update,
   415     .conf_destroy = mysql_conf_destroy
 void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_produce(List *list, void *item)
long gwlist_len(List *list)
void * gwlist_get(List *list, long pos)
#define octstr_get_cstr(ostr)
void * gwlist_extract_first(List *list)
void warning(int err, const char *fmt,...)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
long octstr_len(const Octstr *ostr)
void debug(const char *place, int err, const char *fmt,...)
#define octstr_create_from_data(data, len)
void *(* open)(const DBConf *conf)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)