void output_mysql_init() { #if HAVE_LIBMYSQLCLIENT int rc; char create_query[sizeof(mysql_create_template) +64]; char insert_query[sizeof(mysql_insert_template) +64]; if (!cfg.mysql_flag) return; snprintf(create_query, sizeof(create_query), mysql_create_template, cfg.mysql_table); snprintf(insert_query, sizeof(insert_query), mysql_insert_template, cfg.mysql_table); rc = mysql_library_init(0, NULL, NULL); if (rc) log_msg(LOG_ERR, "Error initializing MySQL library (%d)", rc); cfg.mysql_conn = mysql_init(cfg.mysql_conn); if (!cfg.mysql_conn) log_msg(LOG_ERR, "Error allocating MySQL object"); mysql_options(cfg.mysql_conn, MYSQL_READ_DEFAULT_GROUP, PACKAGE); if (!mysql_real_connect(cfg.mysql_conn, NULL, NULL, NULL, cfg.mysql_db, 0, NULL, 0)) log_msg(LOG_ERR, "Failed to connect to database: Error: %s", mysql_error(cfg.mysql_conn)); log_msg(LOG_DEBUG, "Using MySQL create query: %s", create_query); if(mysql_query(cfg.mysql_conn, create_query)) log_msg(LOG_ERR, "Error creating table `addrwatch` in MySQL database: %s", mysql_error(cfg.mysql_conn)); cfg.mysql_stmt = mysql_stmt_init(cfg.mysql_conn); if (!cfg.mysql_stmt) log_msg(LOG_ERR, "Error allocating MySQL statement object"); log_msg(LOG_DEBUG, "Using MySQL insert query: %s [%d]", insert_query, sizeof(insert_query)); rc = mysql_stmt_prepare(cfg.mysql_stmt, insert_query, strnlen(insert_query, sizeof(insert_query))); if (rc) log_msg(LOG_ERR, "Error preparing MySQL statement object: %s", mysql_stmt_error(cfg.mysql_stmt)); bzero(cfg.mysql_bind, sizeof(cfg.mysql_bind)); cfg.mysql_bind[0].buffer_type = MYSQL_TYPE_LONGLONG; cfg.mysql_bind[0].buffer = &cfg.mysql_vars.timestamp; cfg.mysql_bind[0].is_null = 0; cfg.mysql_bind[0].length = 0; cfg.mysql_bind[1].buffer_type = MYSQL_TYPE_VAR_STRING; cfg.mysql_bind[1].buffer = cfg.mysql_vars.hostname; cfg.mysql_bind[1].is_null = 0; cfg.mysql_bind[1].length = &cfg.mysql_vars.hostname_len; cfg.mysql_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING; cfg.mysql_bind[2].buffer = cfg.mysql_vars.iface; cfg.mysql_bind[2].is_null = 0; cfg.mysql_bind[2].length = &cfg.mysql_vars.iface_len; cfg.mysql_bind[3].buffer_type = MYSQL_TYPE_LONG; cfg.mysql_bind[3].buffer = &cfg.mysql_vars.vlan; cfg.mysql_bind[3].is_null = 0; cfg.mysql_bind[3].length = 0; //cfg.mysql_vars.mac_len = ETHER_ADDR_LEN; //cfg.mysql_bind[3].buffer_type = MYSQL_TYPE_STRING; cfg.mysql_bind[4].buffer_type = MYSQL_TYPE_VAR_STRING; cfg.mysql_bind[4].buffer = cfg.mysql_vars.mac; cfg.mysql_bind[4].is_null = 0; cfg.mysql_bind[4].length = &cfg.mysql_vars.mac_len; cfg.mysql_bind[5].buffer_type = MYSQL_TYPE_VAR_STRING; cfg.mysql_bind[5].buffer = cfg.mysql_vars.ip; cfg.mysql_bind[5].is_null = 0; cfg.mysql_bind[5].length = &cfg.mysql_vars.ip_len; cfg.mysql_bind[6].buffer_type = MYSQL_TYPE_VAR_STRING; cfg.mysql_bind[6].buffer = cfg.mysql_vars.origin; cfg.mysql_bind[6].is_null = 0; cfg.mysql_bind[6].length = &cfg.mysql_vars.origin_len; if (mysql_stmt_bind_param(cfg.mysql_stmt, cfg.mysql_bind)) log_msg(LOG_ERR, "Error binding MySQL statement object: %s", mysql_stmt_error(cfg.mysql_stmt)); #endif }
nsresult jxMySQL50Statement::BindOutput() { PRInt32 ndx; PRInt32 col_type; // Allocate the BIND array and supporting structures. nsresult rv = mOut.Allocate(); if (NS_FAILED(rv)) { SET_ERROR_RETURN(rv); } // Set up the BIND structure based on the column types specified by the database metadata. for (ndx=0; ndx < mOut.mCount ; ndx++) { col_type = (mSTMT->fields) ? mSTMT->fields[ndx].type : MYSQL_TYPE_STRING; switch (col_type) { case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_TINY: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_YEAR: mOut.mBindArrayType[ndx] = MYSQL_TYPE_DOUBLE; /* allocate buffer for double */ mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_DOUBLE; mOut.mBIND[ndx].buffer = &(mOut.mBindArrayBufferTYPE_DOUBLE[ndx]); mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]); break; case MYSQL_TYPE_NULL: mOut.mBindArrayType[ndx] = MYSQL_TYPE_NULL; /* don't initialize to 0 : 1. stmt->result.buf[ofs].buflen 2. bind[ofs].buffer 3. bind[ofs].buffer_length because memory was allocated with ecalloc */ mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_NULL; mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]); break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_BIT: { unsigned long tmp = 0; if (mSTMT->fields[ndx].max_length == 0 && !mysql_stmt_attr_get(mSTMT, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp) { mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = (mSTMT->fields) ? (mSTMT->fields[ndx].length) ? mSTMT->fields[ndx].length + 1: 256: 256; } else { /* the user has called store_result(). if he does not there is no way to determine the libmysql does not allow us to allocate 0 bytes for a buffer so we try 1 */ if (!(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = mSTMT->fields[ndx].max_length)) ++mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx]; } mOut.mBindArrayType[ndx] = MYSQL_TYPE_STRING; mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_STRING; mOut.mBindArrayBufferTYPE_STRING[ndx] = static_cast<char*>(nsMemory::Alloc(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx])) ; if (!mOut.mBindArrayBufferTYPE_STRING[ndx]) { SET_ERROR_RETURN (JX_MYSQL50_ERROR_OUT_OF_MEMORY); } mOut.mBIND[ndx].buffer = mOut.mBindArrayBufferTYPE_STRING[ndx]; mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]); mOut.mBIND[ndx].buffer_length = mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx]; mOut.mBIND[ndx].length = &(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]); } break; case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: { #if 0 PRUint32 tmp = 0; if (mSTMT->fields[ndx].max_length == 0 && !mysql_stmt_attr_get(mSTMT, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp) { if (mSTMT->fields && mSTMT->fields[ndx].length) tmp = mSTMT->fields[ndx].length + 1; // tmp will be zero if a length isn't available or if it was the maximum possible of 4GB-1. In // this case, supply a suitable length. // NB. tmp may not always be 4GB-1, so if we do not want support larger than 16MB, we should try // to prevent it. if (tmp == 0 || tmp > 16*1024*1024) { switch (col_type) { case MYSQL_TYPE_BLOB: tmp = 64*1024; break; case MYSQL_TYPE_TINY_BLOB: tmp = 256; break; case MYSQL_TYPE_MEDIUM_BLOB: tmp = 16*1024*1024; break; case MYSQL_TYPE_LONG_BLOB: tmp = 16*1024*1024; break; } } mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = tmp; } else { /* the user has called store_result(). if he does not there is no way to determine the libmysql does not allow us to allocate 0 bytes for a buffer so we try 1 */ if (!(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx] = mSTMT->fields[ndx].max_length)) ++mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx]; } mOut.mBindArrayType[ndx] = MYSQL_TYPE_BLOB; mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_BLOB; mOut.mBindArrayBufferTYPE_STRING[ndx] = static_cast<char*>(nsMemory::Alloc(mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx])) ; if (!mOut.mBindArrayBufferTYPE_STRING[ndx]) { SET_ERROR_RETURN (JX_MYSQL50_ERROR_OUT_OF_MEMORY); } mOut.mBIND[ndx].buffer = mOut.mBindArrayBufferTYPE_STRING[ndx]; mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]); mOut.mBIND[ndx].buffer_length = mOut.mBindArrayBufferTYPE_STRING_LEN_IN[ndx]; mOut.mBIND[ndx].length = (unsigned long*)&(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]); #endif mOut.mBindArrayType[ndx] = MYSQL_TYPE_BLOB; mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_BLOB; mOut.mBindArrayBufferTYPE_STRING[ndx] = 0; mOut.mBIND[ndx].buffer = mOut.mBindArrayBufferTYPE_STRING[ndx]; mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]); mOut.mBIND[ndx].buffer_length = 0; mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx] = 0; mOut.mBIND[ndx].length = &(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]); } break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIMESTAMP: if (col_type == MYSQL_TYPE_TIMESTAMP ) mOut.mBindArrayType[ndx] = MYSQL_TYPE_DATETIME; else mOut.mBindArrayType[ndx] = col_type; mOut.mBindArrayBufferTYPE_DATE[ndx] = static_cast<MYSQL_TIME*>(nsMemory::Alloc(sizeof(MYSQL_TIME))); if (!mOut.mBindArrayBufferTYPE_DATE[ndx]) { SET_ERROR_RETURN (JX_MYSQL50_ERROR_OUT_OF_MEMORY); } /* allocate buffer for DATE */ mOut.mBIND[ndx].buffer_type = MYSQL_TYPE_DATETIME; mOut.mBIND[ndx].buffer = (void*)mOut.mBindArrayBufferTYPE_DATE[ndx]; mOut.mBIND[ndx].buffer_length = sizeof(MYSQL_TIME); mOut.mBIND[ndx].length = (unsigned long*)&(mOut.mBindArrayBufferTYPE_STRING_LEN_OUT[ndx]); mOut.mBIND[ndx].is_null = (my_bool*)&(mOut.mBindArrayIsNull[ndx]); break; default: SET_ERROR_RETURN (JX_MYSQL50_ERROR_INVALID_TYPE); break; } } PRUint32 rc = mysql_stmt_bind_result(mSTMT, mOut.mBIND); if (rc) { SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR); } else { if (mRES) { mysql_free_result(mRES); mRES = nsnull; } mRES = mysql_stmt_result_metadata(mSTMT); if (mRES) { if (mysql_stmt_store_result(mSTMT)) { #if 0 int i=0; unsigned int en = mysql_stmt_errno(mSTMT); const char* es = mysql_stmt_error(mSTMT); // Not sure why this would fail. Will need to be investigated // Per DOC, this needs to be called earlier. // SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR); #endif } } return NS_OK; } }
fsal_posixdb_status_t fsal_posixdb_initPreparedQueries(fsal_posixdb_conn * p_conn) { int rc; unsigned int retry = 1; static const char *buildonepath_query = "SELECT CONCAT('/',name), handleidparent, handletsparent FROM Parent WHERE handleid=? AND handlets=?"; /* @TODO retry = lmgr_config.connect_retry_min; */ /* create prepared statements */ do { /* First create the prepared statement */ p_conn->stmt_tab[BUILDONEPATH] = mysql_stmt_init(&p_conn->db_conn); /* retry if connection to server failed */ if((p_conn->stmt_tab[BUILDONEPATH] == NULL) && db_is_retryable(mysql_errno(&p_conn->db_conn))) { LogCrit(COMPONENT_FSAL, "Connection to database lost in %s()... Retrying in %u sec.", __FUNCTION__, retry); sleep(retry); retry *= 2; /*if ( retry > lmgr_config.connect_retry_max ) retry = lmgr_config.connect_retry_max; */ } else break; } while(1); if(!p_conn->stmt_tab[BUILDONEPATH]) ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, mysql_errno(&p_conn->db_conn)); /* another retry loop */ /* @TODO retry = lmgr_config.connect_retry_min; */ retry = 1; do { /* prepare the request */ rc = mysql_stmt_prepare(p_conn->stmt_tab[BUILDONEPATH], buildonepath_query, strlen(buildonepath_query)); if(rc && db_is_retryable(mysql_stmt_errno(p_conn->stmt_tab[BUILDONEPATH]))) { LogCrit(COMPONENT_FSAL, "Connection to database lost in %s()... Retrying in %u sec.", __FUNCTION__, retry); sleep(retry); retry *= 2; /*if ( retry > lmgr_config.connect_retry_max ) retry = lmgr_config.connect_retry_max; */ } else break; } while(1); if(rc) { LogCrit(COMPONENT_FSAL, "Failed to create prepared statement: Error: %s (query='%s')", mysql_stmt_error(p_conn->stmt_tab[BUILDONEPATH]), buildonepath_query); mysql_stmt_close(p_conn->stmt_tab[BUILDONEPATH]); ReturnCodeDB(ERR_FSAL_POSIXDB_CMDFAILED, rc); } ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); }
/* FIXME: Add support for DB_NONE, in this case the function should determine * the type of the column in the database and set the field type appropriately. * This function must be called after check_result. */ static int bind_result(MYSQL_STMT* st, db_fld_t* fld) { int i, n, err = 0; struct my_fld* f; MYSQL_BIND* result; /* Calculate the number of fields in the result */ for(n = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[n]); n++); /* Return immediately if there are no fields in the result set */ if (n == 0) return 0; result = (MYSQL_BIND*)pkg_malloc(sizeof(MYSQL_BIND) * n); if (result == NULL) { ERR("mysql: No memory left\n"); return 1; } memset(result, '\0', sizeof(MYSQL_BIND) * n); for(i = 0; i < n; i++) { f = DB_GET_PAYLOAD(fld + i); result[i].is_null = &f->is_null; /* We can do it for all the types here, mysql will ignore it * for fixed-size types such as MYSQL_TYPE_LONG */ result[i].length = &f->length; switch(fld[i].type) { case DB_INT: case DB_BITMAP: result[i].buffer_type = MYSQL_TYPE_LONG; result[i].buffer = &fld[i].v.int4; break; case DB_FLOAT: result[i].buffer_type = MYSQL_TYPE_FLOAT; result[i].buffer = &fld[i].v.flt; break; case DB_DOUBLE: result[i].buffer_type = MYSQL_TYPE_DOUBLE; result[i].buffer = &fld[i].v.dbl; break; case DB_DATETIME: result[i].buffer_type = MYSQL_TYPE_DATETIME; result[i].buffer = &f->time; break; case DB_STR: result[i].buffer_type = MYSQL_TYPE_VAR_STRING; if (!f->buf.s) f->buf.s = pkg_malloc(STR_BUF_SIZE); if (f->buf.s == NULL) { ERR("mysql: No memory left\n"); err = 1; goto error; } result[i].buffer = f->buf.s; fld[i].v.lstr.s = f->buf.s; result[i].buffer_length = STR_BUF_SIZE - 1; break; case DB_CSTR: result[i].buffer_type = MYSQL_TYPE_VAR_STRING; if (!f->buf.s) f->buf.s = pkg_malloc(STR_BUF_SIZE); if (f->buf.s == NULL) { ERR("mysql: No memory left\n"); err = 1; goto error; } result[i].buffer = f->buf.s; fld[i].v.cstr = f->buf.s; result[i].buffer_length = STR_BUF_SIZE - 1; break; case DB_BLOB: result[i].buffer_type = MYSQL_TYPE_BLOB; if (!f->buf.s) f->buf.s = pkg_malloc(STR_BUF_SIZE); if (f->buf.s == NULL) { ERR("mysql: No memory left\n"); err = 1; goto error; } result[i].buffer = f->buf.s; fld[i].v.blob.s = f->buf.s; result[i].buffer_length = STR_BUF_SIZE - 1; break; case DB_NONE: /* Eliminates gcc warning */ break; } } err = mysql_stmt_bind_result(st, result); if (err) { ERR("mysql: Error while binding result: %s\n", mysql_stmt_error(st)); goto error; } /* We do not need the array of MYSQL_BIND anymore, mysql_stmt_bind_param * creates a copy in the statement and we will update it there */ if (result) pkg_free(result); return 0; error: if (result) pkg_free(result); return err; }
StatementException::StatementException(MYSQL_STMT* stmt) throw() { m_error = mysql_stmt_errno(stmt); m_msg = mysql_stmt_error(stmt); }
int main() { int ret = 0, status = 0; MYSQL *mysql; MYSQL_RES *result; mysql = mysql_init(NULL); mysql = mysql_real_connect(mysql, "localhost", "root", "jiangxin", "mydb61", 0, NULL, 0); if (mysql == NULL) { ret = mysql_errno(mysql); printf("%s", mysql_error(mysql)); printf("func mysql_real_connect() err:%d\n", ret); return ret; } else { printf("conncet ok \n"); } MYSQL_TIME ts; MYSQL_BIND bind[3]; MYSQL_STMT *stmt; char query[1024] = "INSERT INTO test_table(date_field, time_field, timestamp_field) values(?,?,?)"; stmt = mysql_stmt_init(mysql); if (!stmt) { fprintf(stderr, "mysql_stmt_init(), out of memory\n"); exit(0); } if (mysql_stmt_prepare(stmt, query, strlen(query))) { fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed"); fprintf(stderr, "\n %s", mysql_stmt_error(stmt)); exit(0); } bind[0].buffer_type = MYSQL_TYPE_DATE; bind[0].buffer = (char *)&ts; bind[0].is_null = 0; bind[0].length = 0; bind[1] = bind[2] = bind[0]; mysql_stmt_bind_param(stmt, bind); ts.year = 2002; ts.month = 02; ts.day = 03; ts.hour = 10; ts.minute = 45; ts.second = 20; mysql_stmt_execute(stmt); if (mysql_stmt_close(stmt)) { fprintf(stderr, " failed while closing the statement\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } mysql_close(mysql); }
/** * This is the main command execution function. The function contains * all the necessary logic to detect reset or disconnected database * connections and uploads commands to the server if necessary. * @param cmd Command to be executed * @return 0 if OK, <0 on MySQL failure, >0 on DB API failure */ static int exec_cmd_safe(db_cmd_t* cmd) { int i, err; db_con_t* con; struct my_cmd* mcmd; struct my_con* mcon; /* First things first: retrieve connection info * from the currently active connection and also * mysql payload from the database command */ mcmd = DB_GET_PAYLOAD(cmd); con = cmd->ctx->con[db_payload_idx]; mcon = DB_GET_PAYLOAD(con); for(i = 0; i <= my_retries; i++) { if ((mcon->flags & MY_CONNECTED) == 0) { /* The connection is disconnected, try to reconnect */ if (my_con_connect(con)) { INFO("mysql: exec_cmd_safe failed to re-connect\n"); continue; } } /* Next check the number of resets in the database connection, if this * number is higher than the number we keep in my_cmd structure in * last_reset variable then the connection was reset and we need to * upload the command again to the server before executing it, because * the server recycles all server side information upon disconnect. */ if (mcon->resets > mcmd->last_reset) { INFO("mysql: Connection reset detected, uploading command to server\n"); err = upload_cmd(cmd); if (err < 0) { INFO("mysql: Error while uploading command\n"); continue; } else if (err > 0) { /* DB API error, this is a serious problem such as memory * allocation failure, bail out */ return 1; } } set_mysql_params(cmd); err = mysql_stmt_execute(mcmd->st); if (err == 0) { /* The command was executed successfully, now fetch all data to * the client if it was requested by the user */ if (mcmd->flags & MY_FETCH_ALL) { err = mysql_stmt_store_result(mcmd->st); if (err) { INFO("mysql: Error while fetching data to client.\n"); goto error; } } return 0; } error: /* Command execution failed, log a message and try to reconnect */ INFO("mysql: libmysql: %d, %s\n", mysql_stmt_errno(mcmd->st), mysql_stmt_error(mcmd->st)); INFO("mysql: Error while executing command on server, trying to reconnect\n"); my_con_disconnect(con); if (my_con_connect(con)) { INFO("mysql: Failed to reconnect server\n"); } else { INFO("mysql: Successfully reconnected server\n"); } } INFO("mysql: Failed to execute command, giving up\n"); return -1; }
static int statement_fetch_impl_cont (lua_State * L, statement_t * statement, /* {{{ */ int event, int named_columns) { int column_count; unsigned long *real_length = NULL; int values = 0; column_count = mysql_num_fields (statement->metadata); if (column_count > 0) { int i; real_length = calloc (column_count, sizeof (unsigned long)); statement->event = mysql_stmt_fetch_cont (&(statement->ret), statement->stmt, event); if (statement->event & MYSQL_WAIT_EXCEPT) { lua_pushnil (L); lua_pushfstring (L, mysql_stmt_error (statement->stmt)); values = 2; } if (statement->event & MYSQL_WAIT_TIMEOUT) { statement->timeout = 1000 * mysql_get_timeout_value_ms (statement->mysql); } /* Pretty sure statement->ret should be the return value, but it seems to return 1 */ /* using mysql_stmt_errno instead */ if (mysql_stmt_errno (statement->stmt) != 0) { lua_pushnil (L); lua_pushstring (L, mysql_stmt_error (statement->stmt)); values = 2; } if (statement->event > 0) { lua_pushboolean (L, 0); lua_pushnumber (L, convert_mysql_to_ev (statement->event)); values = 2; } if (mysql_stmt_errno (statement->stmt) == 0 || statement->ret == MYSQL_DATA_TRUNCATED) { int d = 1; lua_pushboolean (L, 1); lua_newtable (L); values = 2; for (i = 0; i < column_count; i++) { lua_push_type_t lua_push = mysql_to_lua_push (statement->fields[i].type); const char *name = statement->fields[i].name; if (statement->bind[i].buffer == NULL) { char *buffer = (char *) calloc (real_length[i] + 1, sizeof (char)); statement->bind[i].buffer = buffer; statement->bind[i].buffer_length = real_length[i]; mysql_stmt_fetch_column (statement->stmt, &(statement->bind[i]), i, 0); } if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL (name); } else { LUA_PUSH_ARRAY_NIL (d); } } else if (lua_push == LUA_PUSH_INTEGER) { if (statement->fields[i].type == MYSQL_TYPE_YEAR || statement->fields[i].type == MYSQL_TYPE_SHORT) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(short *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(short *) (statement-> bind[i].buffer)); } } else if (statement->fields[i].type == MYSQL_TYPE_TINY) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, (int) *(char *) (statement->bind [i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, (int) *(char *) (statement->bind [i].buffer)); } } else { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(int *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(int *) (statement-> bind[i].buffer)); } } } else if (lua_push == LUA_PUSH_NUMBER) { if (named_columns) { LUA_PUSH_ATTRIB_FLOAT (name, *(double *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_FLOAT (d, *(double *) (statement->bind[i].buffer)); } } else if (lua_push == LUA_PUSH_STRING) { if (statement->fields[i].type == MYSQL_TYPE_TIMESTAMP || statement->fields[i].type == MYSQL_TYPE_DATETIME) { char str[20]; struct st_mysql_time *t = statement->bind[i].buffer; snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (statement->fields[i].type == MYSQL_TYPE_TIME) { char str[9]; struct st_mysql_time *t = statement->bind[i].buffer; snprintf (str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (statement->fields[i].type == MYSQL_TYPE_DATE) { char str[20]; struct st_mysql_time *t = statement->bind[i].buffer; snprintf (str, 11, "%d-%02d-%02d", t->year, t->month, t->day); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else { if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, statement->bind[i].buffer); } else { LUA_PUSH_ARRAY_STRING (d, statement->bind[i].buffer); } } } else if (lua_push == LUA_PUSH_BOOLEAN) { if (named_columns) { LUA_PUSH_ATTRIB_BOOL (name, *(int *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_BOOL (d, *(int *) (statement-> bind[i].buffer)); } } else { luaL_error (L, DBI_ERR_UNKNOWN_PUSH); values = 1; } } } else { lua_pushnil (L); values = 1; } } if (statement->bind) { int i; for (i = 0; i < column_count; i++) { free (statement->bind[i].buffer); } free (statement->bind); } return values; } /* }}} */
static int statement_fetch_impl (lua_State * L, statement_t * statement, /* {{{ */ int named_columns) { int column_count, fetch_result_ok; MYSQL_BIND *bind = NULL; unsigned long *real_length = NULL; const char *error_message = NULL; if (!statement->stmt) { luaL_error (L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->metadata) { luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE); return 0; } column_count = mysql_num_fields (statement->metadata); if (column_count > 0) { int i; MYSQL_FIELD *fields; real_length = calloc (column_count, sizeof (unsigned long)); bind = malloc (sizeof (MYSQL_BIND) * column_count); memset (bind, 0, sizeof (MYSQL_BIND) * column_count); fields = mysql_fetch_fields (statement->metadata); for (i = 0; i < column_count; i++) { unsigned int length = mysql_buffer_size (&fields[i]); if (length > sizeof (MYSQL_TIME)) { bind[i].buffer = NULL; bind[i].buffer_length = 0; } else { char *buffer = (char *) malloc (length); memset (buffer, 0, length); bind[i].buffer = buffer; bind[i].buffer_length = length; } bind[i].buffer_type = fields[i].type; bind[i].length = &real_length[i]; } if (mysql_stmt_bind_result (statement->stmt, bind)) { error_message = DBI_ERR_BINDING_RESULTS; goto cleanup; } fetch_result_ok = mysql_stmt_fetch (statement->stmt); if (fetch_result_ok == 0 || fetch_result_ok == MYSQL_DATA_TRUNCATED) { int d = 1; lua_newtable (L); for (i = 0; i < column_count; i++) { lua_push_type_t lua_push = mysql_to_lua_push (fields[i].type); const char *name = fields[i].name; if (bind[i].buffer == NULL) { char *buffer = (char *) calloc (real_length[i] + 1, sizeof (char)); bind[i].buffer = buffer; bind[i].buffer_length = real_length[i]; mysql_stmt_fetch_column (statement->stmt, &bind[i], i, 0); } if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL (name); } else { LUA_PUSH_ARRAY_NIL (d); } } else if (lua_push == LUA_PUSH_INTEGER) { if (fields[i].type == MYSQL_TYPE_YEAR || fields[i].type == MYSQL_TYPE_SHORT) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(short *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(short *) (bind[i].buffer)); } } else if (fields[i].type == MYSQL_TYPE_TINY) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, (int) *(char *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, (int) *(char *) (bind[i].buffer)); } } else { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(int *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(int *) (bind[i].buffer)); } } } else if (lua_push == LUA_PUSH_NUMBER) { if (named_columns) { LUA_PUSH_ATTRIB_FLOAT (name, *(double *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_FLOAT (d, *(double *) (bind[i].buffer)); } } else if (lua_push == LUA_PUSH_STRING) { if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (fields[i].type == MYSQL_TYPE_TIME) { char str[9]; struct st_mysql_time *t = bind[i].buffer; snprintf (str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (fields[i].type == MYSQL_TYPE_DATE) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf (str, 11, "%d-%02d-%02d", t->year, t->month, t->day); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else { if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, bind[i].buffer); } else { LUA_PUSH_ARRAY_STRING (d, bind[i].buffer); } } } else if (lua_push == LUA_PUSH_BOOLEAN) { if (named_columns) { LUA_PUSH_ATTRIB_BOOL (name, *(int *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_BOOL (d, *(int *) (bind[i].buffer)); } } else { luaL_error (L, DBI_ERR_UNKNOWN_PUSH); } } } else { lua_pushnil (L); } } cleanup: free (real_length); if (bind) { int i; for (i = 0; i < column_count; i++) { free (bind[i].buffer); } free (bind); } if (error_message) { luaL_error (L, error_message, mysql_stmt_error (statement->stmt)); return 0; } return 1; } /* }}} */
/* * success,err = statement:execute(...) */ static int statement_execute (lua_State * L) /* {{{ */ { int n = lua_gettop (L); statement_t *statement = (statement_t *) luaL_checkudata (L, 1, DBD_MYSQL_STATEMENT); int num_bind_params = n - 1; int expected_params; unsigned char *buffer = NULL; int offset = 0; MYSQL_BIND *bind = NULL; MYSQL_RES *metadata = NULL; char *error_message = NULL; char *errstr = NULL; int p; if (statement->metadata) { /* * free existing metadata from any previous executions */ mysql_free_result (statement->metadata); statement->metadata = NULL; } if (!statement->stmt) { lua_pushboolean (L, 0); lua_pushstring (L, DBI_ERR_EXECUTE_INVALID); return 2; } expected_params = mysql_stmt_param_count (statement->stmt); if (expected_params != num_bind_params) { /* * mysql_stmt_bind_param does not handle this condition, * and the client library will segfault if these do no match */ lua_pushboolean (L, 0); lua_pushfstring (L, DBI_ERR_PARAM_MISCOUNT, expected_params, num_bind_params); return 2; } if (num_bind_params > 0) { bind = malloc (sizeof (MYSQL_BIND) * num_bind_params); if (bind == NULL) { luaL_error (L, "Could not alloc bind params\n"); } buffer = (unsigned char *) malloc (num_bind_params * sizeof (double)); memset (bind, 0, sizeof (MYSQL_BIND) * num_bind_params); } for (p = 2; p <= n; p++) { int type = lua_type (L, p); int i = p - 2; const char *str = NULL; size_t *str_len = NULL; double *num = NULL; int *boolean = NULL; char err[64]; switch (type) { case LUA_TNIL: bind[i].buffer_type = MYSQL_TYPE_NULL; bind[i].is_null = (my_bool *) 1; break; case LUA_TBOOLEAN: boolean = (int *) (buffer + offset); offset += sizeof (int); *boolean = lua_toboolean (L, p); bind[i].buffer_type = MYSQL_TYPE_LONG; bind[i].is_null = (my_bool *) 0; bind[i].buffer = (char *) boolean; bind[i].length = 0; break; case LUA_TNUMBER: /* * num needs to be it's own * memory here */ num = (double *) (buffer + offset); offset += sizeof (double); *num = lua_tonumber (L, p); bind[i].buffer_type = MYSQL_TYPE_DOUBLE; bind[i].is_null = (my_bool *) 0; bind[i].buffer = (char *) num; bind[i].length = 0; break; case LUA_TSTRING: str_len = (size_t *) (buffer + offset); offset += sizeof (size_t); str = lua_tolstring (L, p, str_len); bind[i].buffer_type = MYSQL_TYPE_STRING; bind[i].is_null = (my_bool *) 0; bind[i].buffer = (char *) str; bind[i].length = str_len; break; default: snprintf (err, sizeof (err) - 1, DBI_ERR_BINDING_TYPE_ERR, lua_typename (L, type)); errstr = err; error_message = DBI_ERR_BINDING_PARAMS; goto cleanup; } } if (mysql_stmt_bind_param (statement->stmt, bind)) { error_message = DBI_ERR_BINDING_PARAMS; goto cleanup; } if (mysql_stmt_execute (statement->stmt)) { error_message = DBI_ERR_BINDING_EXEC; goto cleanup; } metadata = mysql_stmt_result_metadata (statement->stmt); if (metadata) { mysql_stmt_store_result (statement->stmt); } cleanup: if (bind) { free (bind); } if (buffer) { free (buffer); } if (error_message) { lua_pushboolean (L, 0); lua_pushfstring (L, error_message, errstr ? errstr : mysql_stmt_error (statement->stmt)); return 2; } statement->metadata = metadata; lua_pushboolean (L, 1); return 1; } /* }}} */
static int statement_fetch_impl_start (lua_State * L, statement_t * statement) /* {{{ */ { int column_count; unsigned long *real_length = NULL; const char *error_message = NULL; if (!statement->stmt) { luaL_error (L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->metadata) { luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE); return 0; } column_count = mysql_num_fields (statement->metadata); if (column_count > 0) { int i; real_length = calloc (column_count, sizeof (unsigned long)); statement->bind = malloc (sizeof (MYSQL_BIND) * column_count); memset (statement->bind, 0, sizeof (MYSQL_BIND) * column_count); statement->fields = mysql_fetch_fields (statement->metadata); for (i = 0; i < column_count; i++) { unsigned int length = mysql_buffer_size (&statement->fields[i]); if (length > sizeof (MYSQL_TIME)) { statement->bind[i].buffer = NULL; statement->bind[i].buffer_length = 0; } else { char *buffer = (char *) malloc (length); memset (buffer, 0, length); statement->bind[i].buffer = buffer; statement->bind[i].buffer_length = length; } statement->bind[i].buffer_type = statement->fields[i].type; statement->bind[i].length = &real_length[i]; } if (mysql_stmt_bind_result (statement->stmt, statement->bind)) { error_message = DBI_ERR_BINDING_RESULTS; goto cleanup; } statement->event = mysql_stmt_fetch_start (&(statement->ret), statement->stmt); if (statement->event & MYSQL_WAIT_EXCEPT) { lua_pushnil (L); return 1; } if (statement->event & MYSQL_WAIT_TIMEOUT) { statement->timeout = 1000 * mysql_get_timeout_value_ms (statement->mysql); } lua_pushboolean (L, 1); lua_pushnumber (L, statement->event); return 2; } else { lua_pushnil (L); return 1; } cleanup: free (real_length); if (statement->bind) { int i; for (i = 0; i < column_count; i++) { free (statement->bind[i].buffer); } free (statement->bind); } if (error_message) { luaL_error (L, error_message, mysql_stmt_error (statement->stmt)); return 0; } return 1; } /* }}} */
/** * Get all of the keys in the datastore. * * @param cls closure * @param proc function to call on each key * @param proc_cls closure for proc */ static void mysql_plugin_get_keys (void *cls, PluginKeyProcessor proc, void *proc_cls) { struct Plugin *plugin = cls; const char *query = "SELECT hash FROM gn090"; int ret; MYSQL_STMT *statement; struct GNUNET_HashCode key; MYSQL_BIND cbind[1]; unsigned long length; statement = GNUNET_MYSQL_statement_get_stmt (plugin->mc, plugin->get_all_keys); if (statement == NULL) { GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } if (mysql_stmt_prepare (statement, query, strlen (query))) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", _("Failed to prepare statement `%s'\n"), query); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } GNUNET_assert (proc != NULL); if (mysql_stmt_execute (statement)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("`%s' for `%s' failed at %s:%d with error: %s\n"), "mysql_stmt_execute", query, __FILE__, __LINE__, mysql_stmt_error (statement)); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } memset (cbind, 0, sizeof (cbind)); cbind[0].buffer_type = MYSQL_TYPE_BLOB; cbind[0].buffer = &key; cbind[0].buffer_length = sizeof (key); cbind[0].length = &length; cbind[0].is_unsigned = GNUNET_NO; if (mysql_stmt_bind_result (statement, cbind)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_bind_result", __FILE__, __LINE__, mysql_stmt_error (statement)); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } while (0 == (ret = mysql_stmt_fetch (statement))) { if (sizeof (struct GNUNET_HashCode) == length) proc (proc_cls, &key, 1); } if (ret != MYSQL_NO_DATA) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_fetch", __FILE__, __LINE__, mysql_stmt_error (statement)); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } mysql_stmt_reset (statement); }
bool MySQLConnection::Execute(PreparedStatement* stmt) { if (!m_Mysql) return false; uint32 index = stmt->m_index; { MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query m_mStmt->m_stmt = stmt; // Cross reference them for debug output stmt->m_stmt = m_mStmt; // TODO: Cleaner way stmt->BindParameters(); MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); uint32 _s = 0; if (sLog->GetSQLDriverQueryLogging()) _s = getMSTime(); if (mysql_stmt_bind_param(msql_STMT, msql_BIND)) { uint32 lErrno = mysql_errno(m_Mysql); sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) return Execute(stmt); // Try again m_mStmt->ClearParameters(); return false; } if (mysql_stmt_execute(msql_STMT)) { uint32 lErrno = mysql_errno(m_Mysql); sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) return Execute(stmt); // Try again m_mStmt->ClearParameters(); return false; } if (sLog->GetSQLDriverQueryLogging()) sLog->outSQLDriver("[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString(m_queries[index].first).c_str()); m_mStmt->ClearParameters(); return true; } }
int sqlrow(DB db,SQL sql,const char *format,...) { int i; my_bool w; int *ii; char **t; MYSQL_FIELD *f; va_list ap; if(!db||!sql) { printf("sqlrow: bad database/query handle\n"); return -1; } if(!sql->result) { w=1; if(mysql_stmt_attr_set(sql->sql,STMT_ATTR_UPDATE_MAX_LENGTH,&w)) { printf("sqlsetattr: %s\n",mysql_stmt_error(sql->sql)); goto out0; } if(mysql_stmt_execute(sql->sql)) { printf("sqlexecute: %s\n",mysql_stmt_error(sql->sql)); goto out0; } if(!(sql->restotal=mysql_stmt_field_count(sql->sql)))return 1; if(mysql_stmt_store_result(sql->sql)) { printf("sqlstore: %s\n",mysql_stmt_error(sql->sql)); goto out0; } if(!(sql->result=mysql_stmt_result_metadata(sql->sql)))return 1; if(!(f=mysql_fetch_fields(sql->result))) { printf("sqlfields: %s\n",mysql_stmt_error(sql->sql)); goto out0; } if(!(sql->reslbuf=malloc(sql->restotal*sizeof(unsigned long)))) { printf("sqlrow: out of memory\n"); goto out0; } if(!(sql->resibuf=malloc(sql->restotal*sizeof(int)))) { printf("sqlrow: out of memory\n"); goto out0; } if(!(sql->resparam=malloc(sql->restotal*sizeof(MYSQL_BIND)))) { printf("sqlrow: out of memory\n"); goto out0; } memset(sql->resparam,0,sql->restotal*sizeof(MYSQL_BIND)); for(i=0;i<sql->restotal;i++)switch(f[i].type) { case FIELD_TYPE_TINY: case FIELD_TYPE_SHORT: case FIELD_TYPE_LONG: case FIELD_TYPE_LONGLONG: case FIELD_TYPE_INT24: sql->resparam[i].buffer_type=MYSQL_TYPE_LONG; sql->resparam[i].buffer=&sql->resibuf[i]; break; case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_BLOB: sql->resparam[i].buffer_type=MYSQL_TYPE_BLOB; sql->resparam[i].buffer_length=f[i].max_length+1; sql->resparam[i].length=&sql->reslbuf[i]; if(!(sql->resparam[i].buffer=malloc(f[i].max_length+1))) { while(i--)if(sql->resparam[i].buffer_type== MYSQL_TYPE_BLOB) free(sql->resparam[i].buffer); free(sql->resparam); sql->resparam=NULL; printf("sqlrow: out of memory\n"); goto out0; } break; default: printf("sqlrow: unknown field type %d\n",f[i].type); return -1; } if(mysql_stmt_bind_result(sql->sql,sql->resparam)) { printf("sqlresbind: %s\n",mysql_stmt_error(sql->sql)); goto out0; } } if(mysql_stmt_fetch(sql->sql))return 1; va_start(ap,format); for(i=0;*format;i++)if(i==sql->restotal) { va_end(ap); goto out1; } else switch(*format++) { case 'i': if(sql->resparam[i].buffer_type!=MYSQL_TYPE_LONG) { va_end(ap); goto out1; } ii=va_arg(ap,int *); *ii=sql->resibuf[i]; break; break; case 't': if(sql->resparam[i].buffer_type!=MYSQL_TYPE_BLOB) { va_end(ap); goto out1; } t=va_arg(ap,char **); *t=sql->resparam[i].buffer; (*t)[sql->reslbuf[i]]=0; break; default:printf("unknown format %c\n",format[-1]); va_end(ap); goto out0; } va_end(ap); return 0; out1: printf("sqlrow format mismatch\n"); out0: return -1; }
/// Fetches the next row. int SqlStmt_NextRow(SqlStmt* self) { int err; size_t i; size_t cols; MYSQL_BIND* column; unsigned long length; if( self == NULL ) return SQL_ERROR; // bind columns if( self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns) ) err = 1;// error binding columns else err = mysql_stmt_fetch(self->stmt);// fetch row // check for errors if( err == MYSQL_NO_DATA ) return SQL_NO_DATA; #if defined(MYSQL_DATA_TRUNCATED) // MySQL 5.0/5.1 defines and returns MYSQL_DATA_TRUNCATED [FlavioJS] if( err == MYSQL_DATA_TRUNCATED ) { my_bool truncated; if( !self->bind_columns ) { ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n"); return SQL_ERROR; } // find truncated column cols = SqlStmt_NumColumns(self); for( i = 0; i < cols; ++i ) { column = &self->columns[i]; column->error = &truncated; mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0); column->error = NULL; if( truncated ) {// report truncated column SqlStmt_P_ShowDebugTruncatedColumn(self, i); return SQL_ERROR; } } ShowSQL("DB error - data truncated (unknown source)\n"); return SQL_ERROR; } #endif if( err ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); return SQL_ERROR; } // propagate column lengths and clear unused parts of string/enum/blob buffers cols = SqlStmt_NumColumns(self); for( i = 0; i < cols; ++i ) { length = self->column_lengths[i].length; column = &self->columns[i]; #if !defined(MYSQL_DATA_TRUNCATED) // MySQL 4.1/(below?) returns success even if data is truncated, so we test truncation manually [FlavioJS] if( column->buffer_length < length ) {// report truncated column if( column->buffer_type == MYSQL_TYPE_STRING || column->buffer_type == MYSQL_TYPE_BLOB ) {// string/enum/blob column SqlStmt_P_ShowDebugTruncatedColumn(self, i); return SQL_ERROR; } // FIXME numeric types and null [FlavioJS] } #endif if( self->column_lengths[i].out_length ) *self->column_lengths[i].out_length = (uint32)length; if( column->buffer_type == MYSQL_TYPE_STRING ) {// clear unused part of the string/enum buffer (and nul-terminate) memset((char*)column->buffer + length, 0, column->buffer_length - length + 1); } else if( column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length ) {// clear unused part of the blob buffer memset((char*)column->buffer + length, 0, column->buffer_length - length); } } return SQL_SUCCESS; }
static int st_init_dbconnection(storage_mysql_t *st, db_connection_t *dbc) { MYSQL *mysql = mysql_init(&dbc->dbh); if (!mysql) { fprintf(stderr, "Can't initialize the mysql handler\n"); return -1; } #ifndef __MACH__ pthread_spin_init(&dbc->lock, 0); #endif dbc->initialized = 1; my_bool b = 1; if (!mysql_real_connect(&dbc->dbh, st->dbhost, st->dbuser, st->dbpasswd, st->dbname, st->dbport, st->unix_socket, 0)) { fprintf(stderr, "Can't connect to mysql database: %s\n", mysql_error(&dbc->dbh)); return -1; } if (!st->table_checked) { char create_table_sql[2048]; snprintf(create_table_sql, sizeof(create_table_sql), "CREATE TABLE IF NOT EXISTS `%s` (`%s` char(255) primary key, `%s` blob, `%s` int, `%s` longblob)", st->table, st->keyfield, st->keybytesfield, st->valuesizefield, st->valuefield); mysql_query(&dbc->dbh, create_table_sql); st->table_checked = 1; } char sql[2048]; snprintf(sql, sizeof(sql), "SELECT `%s` FROM `%s` WHERE `%s` = ?", st->valuefield, st->table, st->keyfield); dbc->select_stmt = mysql_stmt_init(mysql); int rc = mysql_stmt_prepare(dbc->select_stmt, sql, strlen(sql)); if (rc != 0) { fprintf(stderr, "Can't prepare the select_stmt '%s' : %s\n", sql, mysql_stmt_error(dbc->select_stmt)); return -1; } snprintf(sql, sizeof(sql), "REPLACE INTO `%s` VALUES(?, ?, ?, ?)", st->table); dbc->insert_stmt = mysql_stmt_init(mysql); rc = mysql_stmt_prepare(dbc->insert_stmt, sql, strlen(sql)); if (rc != 0) { fprintf(stderr, "Can't prepare the insert_stmt '%s' : %s\n", sql, mysql_stmt_error(dbc->insert_stmt)); return -1; } snprintf(sql, sizeof(sql), "DELETE FROM `%s` WHERE `%s` = ?", st->table, st->keyfield); dbc->delete_stmt = mysql_stmt_init(mysql); rc = mysql_stmt_prepare(dbc->delete_stmt, sql, strlen(sql)); if (rc != 0) { fprintf(stderr, "Can't prepare the delete_stmt '%s' : %s\n", sql, mysql_stmt_error(dbc->delete_stmt)); return -1; } snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM `%s` WHERE `%s` = ?", st->table, st->keyfield); dbc->exist_stmt = mysql_stmt_init(mysql); rc = mysql_stmt_prepare(dbc->exist_stmt, sql, strlen(sql)); if (rc != 0) { fprintf(stderr, "Can't prepare the exist_stmt '%s' : %s\n", sql, mysql_stmt_error(dbc->exist_stmt)); return -1; } snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM `%s`", st->table); dbc->count_stmt = mysql_stmt_init(mysql); rc = mysql_stmt_prepare(dbc->count_stmt, sql, strlen(sql)); if (rc != 0) { fprintf(stderr, "Can't prepare the count_stmt '%s' : %s\n", sql, mysql_stmt_error(dbc->count_stmt)); return -1; } snprintf(sql, sizeof(sql), "SELECT `%s`, `%s` FROM `%s`", st->keybytesfield, st->valuesizefield, st->table); dbc->index_stmt = mysql_stmt_init(mysql); rc = mysql_stmt_prepare(dbc->index_stmt, sql, strlen(sql)); if (rc != 0) { fprintf(stderr, "Can't prepare the index_stmt '%s' : %s\n", sql, mysql_stmt_error(dbc->index_stmt)); return -1; } return 0; }
bool MySQLConnection::Execute(PreparedStatement* stmt) { if (!m_Mysql) return false; uint32 index = stmt->m_index; { // guarded block for thread-safe mySQL request ACE_Guard<ACE_Thread_Mutex> query_connection_guard(m_Mutex); MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query m_mStmt->m_stmt = stmt; // Cross reference them for debug output stmt->m_stmt = m_mStmt; // TODO: Cleaner way stmt->BindParameters(); MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); #ifdef SQLQUERY_LOG uint32 _s = getMSTime(); #endif if (mysql_stmt_bind_param(msql_STMT, msql_BIND)) { sLog.outSQLDriver("[ERROR]: PreparedStatement (id: %u) error binding params: %s", index, mysql_stmt_error(msql_STMT)); m_mStmt->ClearParameters(); return false; } if (mysql_stmt_execute(msql_STMT)) { sLog.outSQLDriver("[ERROR]: PreparedStatement (id: %u) error executing: %s", index, mysql_stmt_error(msql_STMT)); m_mStmt->ClearParameters(); return false; } else { #ifdef SQLQUERY_LOG sLog.outSQLDriver("[%u ms] Prepared SQL: %u", getMSTimeDiff(_s, getMSTime()), index); #endif m_mStmt->ClearParameters(); return true; } } }
static int st_fetch(void *key, size_t klen, void **value, size_t *vlen, void *priv) { storage_mysql_t *st = (storage_mysql_t *)priv; char *keystr = malloc((klen*2)+ 1); char *p = (char *)key; char *o = (char *)keystr; int i; for (i = 0; i < klen; i++) { snprintf(o, 3, "%02x", p[i]); o += 2; } *o = 0; db_connection_t *dbc = st_get_dbconnection(st); if (!dbc) { free(keystr); return -1; } MYSQL_BIND bnd = { .buffer_type = MYSQL_TYPE_STRING, .buffer = keystr, .buffer_length = strlen(keystr) }; if (mysql_stmt_bind_param(dbc->select_stmt, &bnd) != 0) { // TODO - error messages SPIN_UNLOCK(&dbc->lock); free(keystr); return -1; } if (mysql_stmt_execute(dbc->select_stmt) != 0) { // TODO - error messages fprintf(stderr, "Can't execute fetch statement : %s\n", mysql_stmt_error(dbc->select_stmt)); SPIN_UNLOCK(&dbc->lock); free(keystr); return -1; } size_t size = 256; void *data = malloc(size); my_bool error = 0; MYSQL_BIND obnd = { .buffer_type = MYSQL_TYPE_LONG_BLOB, .buffer = data, .buffer_length = size, .length = &size, .error = &error }; mysql_stmt_bind_result(dbc->select_stmt, &obnd); int rc = mysql_stmt_fetch(dbc->select_stmt); if (error == 1) { data = realloc(data, size); obnd.buffer = data; obnd.buffer_length = size; error = 0; mysql_stmt_bind_result(dbc->select_stmt, &obnd); mysql_stmt_fetch(dbc->select_stmt); } if (rc != 0 || obnd.is_null) { free(data); data = NULL; } else { if (value) { *value = data; } else { free(data); } if (vlen) { *vlen = size; } } mysql_stmt_free_result(dbc->select_stmt); mysql_stmt_reset(dbc->select_stmt); SPIN_UNLOCK(&dbc->lock); free(keystr); return 0; }
/** * Upload database command to the server * @param cmd Command to be uploaded * @return 0 if OK, >0 on DB API errors, <0 on MySQL errors */ static int upload_cmd(db_cmd_t* cmd) { struct my_cmd* res; struct my_con* mcon; int err = 0; res = DB_GET_PAYLOAD(cmd); /* FIXME: The function should take the connection as one of parameters */ mcon = DB_GET_PAYLOAD(cmd->ctx->con[db_payload_idx]); /* Do not upload the command if the connection is not connected */ if ((mcon->flags & MY_CONNECTED) == 0) { err = 1; goto error; } /* If there is a previous pre-compiled statement, close it first */ if (res->st) mysql_stmt_close(res->st); res->st = NULL; /* Create a new pre-compiled statement data structure */ res->st = mysql_stmt_init(mcon->con); if (res->st == NULL) { ERR("mysql: Error while creating new MySQL_STMT data structure (no memory left)\n"); err = 1; goto error; } /* Try to upload the command to the server */ if (mysql_stmt_prepare(res->st, res->sql_cmd.s, res->sql_cmd.len)) { err = mysql_stmt_errno(res->st); ERR("mysql: libmysql: %d, %s\n", err, mysql_stmt_error(res->st)); ERR("mysql: An error occurred while uploading command to server\n"); } if (err == CR_SERVER_LOST || err == CR_SERVER_GONE_ERROR) { /* Connection to the server was lost, mark the connection as * disconnected. In this case mysql_stmt_prepare invalidates the * connection internally and calling another mysql function on that * connection would crash. To make sure that no other mysql function * gets called unless the connection is reconnected we disconnect it * explicitly here. This is a workaround for mysql bug #33384. */ my_con_disconnect(cmd->ctx->con[db_payload_idx]); } if (err) { /* Report mysql error to the caller */ err = -1; goto error; } err = bind_mysql_params(res->st, cmd->vals, cmd->match); if (err) goto error; if (cmd->type == DB_GET || cmd->type == DB_SQL) { err = check_result(cmd, res); if (err) goto error; err = bind_result(res->st, cmd->result); if (err) goto error; } res->last_reset = mcon->resets; return 0; error: if (res->st) { mysql_stmt_close(res->st); res->st = NULL; } return err; }
int driverMySQL_prepareStatement(struct xsb_queryHandle* handle) { struct driverMySQL_preparedresultset* rs; MYSQL* mysql; MYSQL_STMT* stmt; MYSQL_RES* res; int i; char* sqlQuery; int numResultCols; MYSQL_FIELD* field; sqlQuery = (char *)malloc((strlen(handle->query) + 1) * sizeof(char)); strcpy(sqlQuery, handle->query); mysql = NULL; for (i = 0 ; i < numHandles ; i++) { if (!strcmp(mysqlHandles[i]->handle, handle->connHandle->handle)) { mysql = mysqlHandles[i]->mysql; break; } } if ((stmt = mysql_stmt_init(mysql)) == NULL) { errorMesg = "mysql_stmt_init() failed\n"; //errorMesg = mysql_stmt_error(stmt); free(sqlQuery); sqlQuery = NULL; return FAILURE; } if ( mysql_stmt_prepare(stmt, sqlQuery, (unsigned long)strlen(sqlQuery))) { errorMesg = mysql_stmt_error(stmt); free(sqlQuery); sqlQuery = NULL; return FAILURE; } rs = (struct driverMySQL_preparedresultset *)malloc(sizeof(struct driverMySQL_preparedresultset)); rs->statement = stmt; res = mysql_stmt_result_metadata(stmt); numResultCols = 0; if (res == NULL) { if (mysql_errno(mysql)) { errorMesg = mysql_stmt_error(stmt); free(sqlQuery); sqlQuery = NULL; free(rs); rs = NULL; return FAILURE; } } else numResultCols = mysql_num_fields(res); rs->returnFields = numResultCols; handle->numParams = mysql_stmt_param_count(stmt); handle->numResultCols = rs->returnFields; handle->state = QUERY_BEGIN; rs->handle = handle; rs->bindResult = NULL; rs->metaInfo = (struct xsb_data **)malloc(rs->returnFields * sizeof(struct xsb_data *)); for (i = 0 ; i < rs->returnFields ; i++) { rs->metaInfo[i] = (struct xsb_data *)malloc(sizeof(struct xsb_data)); field = mysql_fetch_field_direct(res, i); rs->metaInfo[i]->type = driverMySQL_getXSBType(field); rs->metaInfo[i]->length = field->length; } prepQueries[numPrepQueries++] = rs; free(sqlQuery); sqlQuery = NULL; return rs->handle->numParams; }
/* * FIXME: This function will only work if we have one db connection * in every context, otherwise it would initialize the result set * from the first connection in the context. */ static int check_result(db_cmd_t* cmd, struct my_cmd* payload) { int i, n; MYSQL_FIELD *fld; MYSQL_RES *meta = NULL; meta = mysql_stmt_result_metadata(payload->st); if (meta == NULL) { /* No error means no result set to be checked */ if (mysql_stmt_errno(payload->st) == 0) return 0; ERR("mysql: Error while getting metadata of SQL command: %d, %s\n", mysql_stmt_errno(payload->st), mysql_stmt_error(payload->st)); return -1; } n = mysql_num_fields(meta); if (cmd->result == NULL) { /* The result set parameter of db_cmd function was empty, that * means the command is select * and we have to create the array * of result fields in the cmd structure manually. */ cmd->result = db_fld(n + 1); cmd->result_count = n; for(i = 0; i < cmd->result_count; i++) { struct my_fld *f; if (my_fld(cmd->result + i, cmd->table.s) < 0) goto error; f = DB_GET_PAYLOAD(cmd->result + i); fld = mysql_fetch_field_direct(meta, i); f->name = pkg_malloc(strlen(fld->name)+1); if (f->name == NULL) { ERR("mysql: Out of private memory\n"); goto error; } strcpy(f->name, fld->name); cmd->result[i].name = f->name; } } else { if (cmd->result_count != n) { BUG("mysql: Number of fields in MySQL result does not match number of parameters in DB API\n"); goto error; } } /* Now iterate through all the columns in the result set and replace * any occurrence of DB_UNKNOWN type with the type of the column * retrieved from the database and if no column name was provided then * update it from the database as well. */ for(i = 0; i < cmd->result_count; i++) { fld = mysql_fetch_field_direct(meta, i); if (cmd->result[i].type != DB_NONE) continue; switch(fld->type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: cmd->result[i].type = DB_INT; break; case MYSQL_TYPE_FLOAT: cmd->result[i].type = DB_FLOAT; break; case MYSQL_TYPE_DOUBLE: cmd->result[i].type = DB_DOUBLE; break; case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: cmd->result[i].type = DB_DATETIME; break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: cmd->result[i].type = DB_STR; break; default: ERR("mysql: Unsupported MySQL column type: %d, table: %s, column: %s\n", fld->type, cmd->table.s, fld->name); goto error; } } if (meta) mysql_free_result(meta); return 0; error: if (meta) mysql_free_result(meta); return 1; }
int_vector *mysql_exec(struct stmt_singleton *stmt) { journal_strace("mysql_exec"); int ret, num_row, itr; int_vector *data_vtr; static int buf = 0; /* XXX being static fixes a bad bug */ printf("Running MySQL query\n\n\t%s\n\n", stmt->stmt); if (stmt->out_buf_count > 1) { journal_notice("%s :: %s:%i\n", "mysql_exec() does not support multicolumn vector", __FILE__, __LINE__); return NULL; } ret = mysql_stmt_prepare(mysql_stmt, stmt->stmt, stmt->stmt_length); printf("mysql_stmt_prepare (%i)\n", ret); ret = mysql_stmt_bind_param(mysql_stmt, stmt->in_buf); printf("mysql_stmt_bind_param (%i)\n", ret); ret = mysql_stmt_param_count(mysql_stmt); printf("mysql_stmt_param_count (%i)\n", ret); if (ret != stmt->in_buf_count) { journal_notice("%s :: %s:%i\n", "corrupted dbal method", __FILE__, __LINE__); return NULL; } if (stmt->out_buf) { stmt->out_buf->buffer = (char *)&buf; ret = mysql_stmt_bind_result(mysql_stmt, stmt->out_buf); printf("mysql_stmt_bind_result (%i)\n", ret); } ret = mysql_stmt_execute(mysql_stmt); printf("mysql_stmt_execute (%i)\n", ret); if (ret == 1) { // I dont know why... printf("err: %s\n", mysql_stmt_error(mysql_stmt)); return NULL; } ret = mysql_stmt_store_result(mysql_stmt); printf("mysql_stmt_store_result (%i)\n", ret); num_row = mysql_stmt_num_rows(mysql_stmt); printf("mysql_stmt_num_rows (%i)\n", num_row); data_vtr = calloc(VECTOR_SET_MAX(num_row), sizeof(int_vector)); data_vtr[VECTOR_IDX_MAX] = num_row; for (itr = VECTOR_IDX_BEGIN; !mysql_stmt_fetch(mysql_stmt); itr++) { data_vtr[itr] = buf; printf("MySQL returned value %i\n", buf); } data_vtr[VECTOR_IDX_SIZE] = VECTOR_SET_SIZE(itr); return data_vtr; }
PreparedResultSet::PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES *result, uint64 rowCount, uint32 fieldCount) : m_rowCount(rowCount), m_rowPosition(0), m_fieldCount(fieldCount), m_rBind(NULL), m_stmt(stmt), m_res(result), m_isNull(NULL), m_length(NULL) { if (!m_res) return; if (m_stmt->bind_result_done) { delete[] m_stmt->bind->length; delete[] m_stmt->bind->is_null; } m_rBind = new MYSQL_BIND[m_fieldCount]; m_isNull = new my_bool[m_fieldCount]; m_length = new unsigned long[m_fieldCount]; memset(m_isNull, 0, sizeof(my_bool) * m_fieldCount); memset(m_rBind, 0, sizeof(MYSQL_BIND) * m_fieldCount); memset(m_length, 0, sizeof(unsigned long) * m_fieldCount); //- This is where we store the (entire) resultset if (mysql_stmt_store_result(m_stmt)) { sLog->outSQLDriver("%s:mysql_stmt_store_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt)); return; } //- This is where we prepare the buffer based on metadata uint32 i = 0; MYSQL_FIELD* field = mysql_fetch_field(m_res); while (field) { size_t size = Field::SizeForType(field); m_rBind[i].buffer_type = field->type; m_rBind[i].buffer = malloc(size); memset(m_rBind[i].buffer, 0, size); m_rBind[i].buffer_length = size; m_rBind[i].length = &m_length[i]; m_rBind[i].is_null = &m_isNull[i]; m_rBind[i].error = NULL; m_rBind[i].is_unsigned = field->flags & UNSIGNED_FLAG; ++i; field = mysql_fetch_field(m_res); } //- This is where we bind the bind the buffer to the statement if (mysql_stmt_bind_result(m_stmt, m_rBind)) { sLog->outSQLDriver("%s:mysql_stmt_bind_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt)); delete[] m_rBind; delete[] m_isNull; delete[] m_length; return; } m_rowCount = mysql_stmt_num_rows(m_stmt); m_rows.resize(uint32(m_rowCount)); while (_NextRow()) { m_rows[uint32(m_rowPosition)] = new Field[m_fieldCount]; for (uint64 fIndex = 0; fIndex < m_fieldCount; ++fIndex) { if (!*m_rBind[fIndex].is_null) m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( m_rBind[fIndex].buffer, m_rBind[fIndex].buffer_length, m_rBind[fIndex].buffer_type, *m_rBind[fIndex].length ); else switch (m_rBind[fIndex].buffer_type) { case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( "", m_rBind[fIndex].buffer_length, m_rBind[fIndex].buffer_type, *m_rBind[fIndex].length ); break; default: m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( 0, m_rBind[fIndex].buffer_length, m_rBind[fIndex].buffer_type, *m_rBind[fIndex].length ); } } m_rowPosition++; } m_rowPosition = 0; /// All data is buffered, let go of mysql c api structures CleanUp(); }
void Event::updateNotes( const StringSetMap &newNoteSetMap ) { bool update = false; //Info( "Checking notes, %d <> %d", noteSetMap.size(), newNoteSetMap.size() ); if ( newNoteSetMap.size() > 0 ) { if ( noteSetMap.size() == 0 ) { noteSetMap = newNoteSetMap; update = true; } else { for ( StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); newNoteSetMapIter != newNoteSetMap.end(); ++newNoteSetMapIter ) { const std::string &newNoteGroup = newNoteSetMapIter->first; const StringSet &newNoteSet = newNoteSetMapIter->second; //Info( "Got %d new strings", newNoteSet.size() ); if ( newNoteSet.size() > 0 ) { StringSetMap::iterator noteSetMapIter = noteSetMap.find( newNoteGroup ); if ( noteSetMapIter == noteSetMap.end() ) { //Info( "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size() ); noteSetMap.insert( StringSetMap::value_type( newNoteGroup, newNoteSet ) ); update = true; } else { StringSet ¬eSet = noteSetMapIter->second; //Info( "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size() ); for ( StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); newNoteSetIter != newNoteSet.end(); ++newNoteSetIter ) { const std::string &newNote = *newNoteSetIter; StringSet::iterator noteSetIter = noteSet.find( newNote ); if ( noteSetIter == noteSet.end() ) { noteSet.insert( newNote ); update = true; } } // end for } // end if ( noteSetMap.size() == 0 } // end if newNoteSetupMap.size() > 0 } // end foreach newNoteSetMap } // end if have old notes } // end if have new notes if ( update ) { std::string notes; createNotes( notes ); Debug( 2, "Updating notes for event %d, '%s'", id, notes.c_str() ); static char sql[ZM_SQL_MED_BUFSIZ]; #if USE_PREPARED_SQL static MYSQL_STMT *stmt = 0; char notesStr[ZM_SQL_MED_BUFSIZ] = ""; unsigned long notesLen = 0; if ( !stmt ) { const char *sql = "update Events set Notes = ? where Id = ?"; stmt = mysql_stmt_init( &dbconn ); if ( mysql_stmt_prepare( stmt, sql, strlen(sql) ) ) { Fatal( "Unable to prepare sql '%s': %s", sql, mysql_stmt_error(stmt) ); } /* Get the parameter count from the statement */ if ( mysql_stmt_param_count( stmt ) != 2 ) { Fatal( "Unexpected parameter count %ld in sql '%s'", mysql_stmt_param_count( stmt ), sql ); } MYSQL_BIND bind[2]; memset(bind, 0, sizeof(bind)); /* STRING PARAM */ bind[0].buffer_type = MYSQL_TYPE_STRING; bind[0].buffer = (char *)notesStr; bind[0].buffer_length = sizeof(notesStr); bind[0].is_null = 0; bind[0].length = ¬esLen; bind[1].buffer_type= MYSQL_TYPE_LONG; bind[1].buffer= (char *)&id; bind[1].is_null= 0; bind[1].length= 0; /* Bind the buffers */ if ( mysql_stmt_bind_param( stmt, bind ) ) { Fatal( "Unable to bind sql '%s': %s", sql, mysql_stmt_error(stmt) ); } } strncpy( notesStr, notes.c_str(), sizeof(notesStr) ); if ( mysql_stmt_execute( stmt ) ) { Fatal( "Unable to execute sql '%s': %s", sql, mysql_stmt_error(stmt) ); } #else static char escapedNotes[ZM_SQL_MED_BUFSIZ]; mysql_real_escape_string(&dbconn, escapedNotes, notes.c_str(), notes.length()); snprintf(sql, sizeof(sql), "UPDATE Events SET Notes = '%s' WHERE Id = %" PRIu64, escapedNotes, id); db_mutex.lock(); if ( mysql_query(&dbconn, sql) ) { Error("Can't insert event: %s", mysql_error(&dbconn)); } db_mutex.unlock(); #endif } // end if update }
/* [noscript] long init (in AString query); */ NS_IMETHODIMP jxMySQL50Statement::Init(const nsAString & query, PRInt32 *_retval) { nsresult rv = NS_OK; if (mConnection == nsnull) { SET_ERROR_RETURN (JX_MYSQL50_ERROR_NOT_CONNECTED); } if (mSTMT != nsnull) { SET_ERROR_RETURN (JX_MYSQL50_ERROR_STMT_ALREADY_INITIALIZED); } MYSQL * mysql; mConnection->GetMysql(&mysql); // Create a new statement handle if ((mSTMT = mysql_stmt_init(mysql))) { // Get the query string char * stmt = ToNewUTF8String(query); // Prepare the statement int ret = mysql_stmt_prepare(mSTMT, stmt, query.Length()); nsMemory::Free(stmt); if (ret) { // Statement prep failed #if 0 char err[512]; sprintf(err, " %s", mysql_stmt_error(mSTMT)); #endif *_retval = ret; SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR); } else { mIn.mCount = mysql_stmt_param_count(mSTMT); mOut.mCount = mysql_stmt_field_count(mSTMT); // Statement prep succeeded *_retval = 0; // Allocated the BIND array and supporting structures if (mIn.mBIND == nsnull && mIn.mCount > 0) { rv = mIn.Allocate(); if (rv != NS_OK) { *_retval = -1; SET_ERROR_RETURN (rv); } } } } else { // Statement prep failed *_retval = -1; SET_ERROR_RETURN (JX_MYSQL50_MYSQL_ERROR); } return NS_OK; }
bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount) { if (!m_Mysql) return false; uint32 index = stmt->m_index; { MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query m_mStmt->m_stmt = stmt; // Cross reference them for debug output stmt->m_stmt = m_mStmt; // TODO: Cleaner way stmt->BindParameters(); MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); uint32 _s = 0; if (sLog->GetSQLDriverQueryLogging()) _s = getMSTime(); if (mysql_stmt_bind_param(msql_STMT, msql_BIND)) { uint32 lErrno = mysql_errno(m_Mysql); sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_statementTable[index].query, lErrno, mysql_stmt_error(msql_STMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled succesfuly (ie reconnection) return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again m_mStmt->ClearParameters(); return false; } if (mysql_stmt_execute(msql_STMT)) { uint32 lErrno = mysql_errno(m_Mysql); sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_statementTable[index].query, lErrno, mysql_stmt_error(msql_STMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled succesfuly (ie reconnection) return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again m_mStmt->ClearParameters(); return false; } if (sLog->GetSQLDriverQueryLogging()) sLog->outSQLDriver("[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_statementTable[index].query); m_mStmt->ClearParameters(); *pResult = mysql_stmt_result_metadata(msql_STMT); *pRowCount = mysql_stmt_num_rows(msql_STMT); *pFieldCount = mysql_stmt_field_count(msql_STMT); return true; } }
my_bool fetch_n(const char **query_list, unsigned query_count, enum fetch_type fetch_type) { unsigned open_statements= query_count; int rc, error_count= 0; Stmt_fetch *fetch_array= (Stmt_fetch*) calloc(1, sizeof(Stmt_fetch) * query_count); Stmt_fetch *fetch; DBUG_ENTER("fetch_n"); for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) { /* Init will exit(1) in case of error */ stmt_fetch_init(fetch, fetch - fetch_array, query_list[fetch - fetch_array]); } if (fetch_type == USE_STORE_RESULT) { for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) { rc= mysql_stmt_store_result(fetch->handle); check_execute(fetch->handle, rc); } } while (open_statements) { for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) { if (fetch->is_open && (rc= stmt_fetch_fetch_row(fetch))) { open_statements--; /* We try to fetch from the rest of the statements in case of error */ if (rc != MYSQL_NO_DATA) { fprintf(stderr, "Got error reading rows from statement %d,\n" "query is: %s,\n" "error message: %s", (int) (fetch - fetch_array), fetch->query, mysql_stmt_error(fetch->handle)); error_count++; } } } } if (error_count) fprintf(stderr, "Fetch FAILED"); else { unsigned total_row_count= 0; for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) total_row_count+= fetch->row_count; if (!opt_silent) printf("Success, total rows fetched: %d\n", total_row_count); } for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) stmt_fetch_close(fetch); free(fetch_array); DBUG_RETURN(error_count != 0); }
DatabaseException::DatabaseException(MYSQL_STMT *stmt, const std::string &initialMessage) { _errno = mysql_stmt_errno(stmt); _errorMessage = mysql_stmt_error(stmt); _sqlState = mysql_stmt_sqlstate(stmt); _initialMessage = initialMessage; }
if_status_t IF_db_log_wind_record ( time_t iStartDTM, time_t iEndDTM, int iNumMeasurements, float fSpeedMin, float fSpeedMax, float fSpeedAve, float fAngleAve) { /* static function variables */ static MYSQL_BIND bind[7]; static MYSQL_TIME bStartDTM; static MYSQL_TIME bEndDTM; static int ibNumMeasurements; static float fbSpeedMin; static float fbSpeedMax; static float fbSpeedAve; static float fbAngleAve; /* function variables */ if_status_t retval = IF_OK; /* Do one-off setup if insert statement has not been prepared */ if ( stmtInsertRecord == NULL ) { stmtInsertRecord = mysql_stmt_init(&mysql); if (mysql_stmt_prepare(stmtInsertRecord, WIND_REC_INSERT_STMT, strlen(WIND_REC_INSERT_STMT))) { IF_log_event ( 0, IF_SEV_ERROR, "Failed to prepare statement for wind data record insert: '%s' [%d]", mysql_stmt_error(stmtInsertRecord), mysql_stmt_errno(stmtInsertRecord) ); mysql_stmt_close(stmtInsertRecord); stmtInsertRecord = NULL; retval = IF_ERR; } memset ( bind, 0, sizeof(bind) ); /* start datetime */ bind[0].buffer_type = MYSQL_TYPE_DATETIME; bind[0].buffer = &bStartDTM; bind[0].buffer_length = sizeof(bStartDTM); bind[0].length = 0; /* ignored for numeric & temporal types */ bind[0].is_null = (my_bool*) 0; /* Never null */ bind[0].is_unsigned = (my_bool) 0; /* signed */ /* end datetime */ bind[1].buffer_type = MYSQL_TYPE_DATETIME; bind[1].buffer = &bEndDTM; bind[1].buffer_length = sizeof(bEndDTM); bind[1].length = 0; /* ignored for numeric & temporal types */ bind[1].is_null = (my_bool*) 0; /* Never null */ bind[1].is_unsigned = (my_bool) 0; /* signed */ /* number of measurements */ bind[2].buffer_type = MYSQL_TYPE_LONG; bind[2].buffer = &ibNumMeasurements; bind[2].buffer_length = sizeof(ibNumMeasurements); bind[2].length = 0; /* ignored for numeric & temporal types */ bind[2].is_null = (my_bool*) 0; /* Never null */ bind[2].is_unsigned = (my_bool) 0; /* signed */ /* minimum speed */ bind[3].buffer_type = MYSQL_TYPE_FLOAT; bind[3].buffer = &fbSpeedMin; bind[3].buffer_length = sizeof(fbSpeedMin); bind[3].length = 0; /* ignored for numeric & temporal types */ bind[3].is_null = (my_bool*) 0; /* Never null */ bind[3].is_unsigned = (my_bool) 0; /* signed */ /* maximum speed */ bind[4].buffer_type = MYSQL_TYPE_FLOAT; bind[4].buffer = &fbSpeedMax; bind[4].buffer_length = sizeof(fbSpeedMax); bind[4].length = 0; /* ignored for numeric & temporal types */ bind[4].is_null = (my_bool*) 0; /* Never null */ bind[4].is_unsigned = (my_bool) 0; /* signed */ /* average speed */ bind[5].buffer_type = MYSQL_TYPE_FLOAT; bind[5].buffer = &fbSpeedAve; bind[5].buffer_length = sizeof(fbSpeedAve); bind[5].length = 0; /* ignored for numeric & temporal types */ bind[5].is_null = (my_bool*) 0; /* Never null */ bind[5].is_unsigned = (my_bool) 0; /* signed */ /* average angle */ bind[6].buffer_type = MYSQL_TYPE_FLOAT; bind[6].buffer = &fbAngleAve; bind[6].buffer_length = sizeof(fbAngleAve); bind[6].length = 0; /* ignored for numeric & temporal types */ bind[6].is_null = (my_bool*) 0; /* Never null */ bind[6].is_unsigned = (my_bool) 0; /* signed */ if ( mysql_stmt_bind_param ( stmtInsertRecord, bind ) != 0 ) { IF_log_event ( 0, IF_SEV_ERROR, "Failed to bind wind data record input parameters: '%s' [%d]", mysql_stmt_error(stmtInsertRecord), mysql_stmt_errno(stmtInsertRecord) ); mysql_stmt_close(stmtInsertRecord); stmtInsertRecord = NULL; retval = IF_ERR; } } convert_time ( iStartDTM, &bStartDTM ); convert_time ( iEndDTM, &bEndDTM ); ibNumMeasurements = iNumMeasurements; fbSpeedMin = fSpeedMin; fbSpeedMax = fSpeedMax; fbSpeedAve = fSpeedAve; fbAngleAve = fAngleAve; /* Execute the INSERT statement */ if (mysql_stmt_execute(stmtInsertRecord) != 0 ) { IF_log_event ( 0, IF_SEV_ERROR, "Failed to insert wind data record : '%s' [%d]", mysql_error(&mysql), mysql_errno(&mysql) ); retval = IF_ERR; } return retval; }
bool SqlStatement::fetch() { for (unsigned i = 0, e = data_.size(); i != e; ++i) { MYSQL_BIND *d = &data_[i]; if (!fixedLengths_[i]) { // var-size field if (d->buffer) free(d->buffer); d->buffer = NULL; d->buffer_length = 0; } nulls_[i] = 0; } if (mysql_stmt_bind_result(stmt_, &data_.front()) != 0) { error_ = mysql_stmt_error(stmt_); fprintf(stderr, "mysql_stmt_bind_result step 1 failed: %s\n", error_); return false; } int rc = mysql_stmt_fetch(stmt_); switch (rc) { case 1: error_ = mysql_stmt_error(stmt_); fprintf(stderr, "mysql_stmt_fetch failed (%d): %s\n", rc, error_); return false; case MYSQL_NO_DATA: //DEBUG("end of result set."); return false; case 0: case MYSQL_DATA_TRUNCATED: default: break; } for (unsigned i = 0, e = data_.size(); i != e; ++i) { MYSQL_BIND *d = &data_[i]; /*TRACE("[%2u] length: result(%lu) given(%lu) %s", i, *d->length, d->buffer_length, mysql_type_str(d->buffer_type));*/ if (fixedLengths_[i]) { //TRACE("fixed-length value[%d]: %s", i, this->valueAt<std::string>(i).c_str()); continue; } d->buffer_length = *d->length; d->buffer = malloc(d->buffer_length + 1); ((char *)d->buffer)[d->buffer_length] = '\0'; if (mysql_stmt_fetch_column(stmt_, d, i, 0) != 0) { error_ = mysql_stmt_error(stmt_); fprintf(stderr, "mysql_stmt_fetch step 1 failed: %s\n", error_); return false; } } return true; }