void wxMySQLRecordset::SetHandle(MYSQL_STMT * stmt) { m_Stmt = stmt; m_HasResult = false; if(m_Stmt) { printf("MYSQL_STMT_RESULT_METADATA\r\n"); MYSQL_RES * metadata_result = mysql_stmt_result_metadata(m_Stmt); if(metadata_result) { m_HasResult = true; SetFieldCount(mysql_num_fields(metadata_result)); mysql_free_result(metadata_result); } else SetFieldCount(mysql_stmt_param_count(m_Stmt)); } }
MySQLPreparedStatement(MySQLConnection *_conn, MySQLStatement *_stmt) : conn(_conn), stmt(_stmt) { // Create bindings for input parameters inputBindings.init(mysql_stmt_param_count(*stmt)); // And for results res.setown(new MySQLResult(mysql_stmt_result_metadata(*stmt))); if (*res) { resultBindings.bindResults(*res); /* Bind the result buffers */ if (mysql_stmt_bind_result(*stmt, resultBindings.queryBindings())) fail(mysql_stmt_error(*stmt)); } else if (mysql_stmt_errno(*stmt)) // SQL actions don't return results... fail(mysql_stmt_error(*stmt)); }
/// Reports debug information about a truncated column. /// /// @private static void SqlStmt_P_ShowDebugTruncatedColumn(SqlStmt* self, size_t i) { MYSQL_RES* meta; MYSQL_FIELD* field; MYSQL_BIND* column; meta = mysql_stmt_result_metadata(self->stmt); field = mysql_fetch_field_direct(meta, (unsigned int)i); ShowSQL("DB error - data of field '%s' was truncated.\n", field->name); ShowDebug("column - %lu\n", (unsigned long)i); Sql_P_ShowDebugMysqlFieldInfo("data - ", field->type, field->flags&UNSIGNED_FLAG, self->column_lengths[i].length, ""); column = &self->columns[i]; if( column->buffer_type == MYSQL_TYPE_STRING ) Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "+1(nul-terminator)"); else Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, ""); mysql_free_result(meta); }
MyStatement::MyStatement(MyDatabase *db, MYSQL_STMT *stmt) : m_mysql(db->m_mysql), m_pParent(db), m_stmt(stmt), m_rs(NULL), m_Results(false) { m_Params = (unsigned int)mysql_stmt_param_count(m_stmt); if (m_Params) { m_pushinfo = (ParamBind *)malloc(sizeof(ParamBind) * m_Params); memset(m_pushinfo, 0, sizeof(ParamBind) * m_Params); m_bind = (MYSQL_BIND *)malloc(sizeof(MYSQL_BIND) * m_Params); memset(m_bind, 0, sizeof(MYSQL_BIND) * m_Params); } else { m_pushinfo = NULL; m_bind = NULL; } m_pRes = mysql_stmt_result_metadata(stmt); m_Results = false; }
/* call-seq: stmt.fields # => array * * Returns a list of fields that will be returned by this statement. */ static VALUE fields(VALUE self) { MYSQL_FIELD *fields; MYSQL_RES *metadata; unsigned int field_count; unsigned int i; VALUE field_list; MYSQL_STMT* stmt; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc, *conn_enc; #endif GET_STATEMENT(self); stmt = stmt_wrapper->stmt; #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); { GET_CLIENT(stmt_wrapper->client); conn_enc = rb_to_encoding(wrapper->encoding); } #endif metadata = mysql_stmt_result_metadata(stmt); fields = mysql_fetch_fields(metadata); field_count = mysql_stmt_field_count(stmt); field_list = rb_ary_new2((long)field_count); for(i = 0; i < field_count; i++) { VALUE rb_field; rb_field = rb_str_new(fields[i].name, fields[i].name_length); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(rb_field, conn_enc); if (default_internal_enc) { rb_field = rb_str_export_to_enc(rb_field, default_internal_enc); } #endif rb_ary_store(field_list, (long)i, rb_field); } mysql_free_result(metadata); return field_list; }
void GetBindings( MYSQL_STMT * stmt, DatabaseConnectionMySqlSPtr connection, DatabaseValuedObjectInfosPtrArray const & columns, std::vector< std::unique_ptr< SInMySqlBindBase > > & inbinds, std::vector< MYSQL_BIND > & binds ) { MYSQL_RES * data = mysql_stmt_result_metadata( stmt ); if ( !data ) { DB_EXCEPT( EDatabaseExceptionCodes_ConnectionError, ERROR_MYSQL_STMT_METADATA ); } binds.resize( columns.size() ); auto bindIt = binds.begin(); for ( auto & column : columns ) { MYSQL_FIELD * field = mysql_fetch_field( data ); inbinds.emplace_back( GetInBind( column->GetType(), field->type, *bindIt++, field->length, field->decimals, std::max( field->length, field->max_length ) ) ); } mysql_free_result( data ); }
bool SqlPreparedStatement::Prepare() { auto sql = Sql(); mSTMT = mysql_stmt_init(Sql()); if (mSTMT == nullptr) { throw SqlException(sql, "Error in SqlPreparedStatement::mysql_stmt_init"); } if (mysql_stmt_prepare(mSTMT, mStatement.c_str(), (ulong)mStatement.Length()) != 0) { SqlException e(mSTMT, "Error in SqlPreparedStatement::mysql_stmt_prepare"); mysql_stmt_free_result(mSTMT); mysql_stmt_close(mSTMT); throw e; } mParamterCount = mysql_stmt_param_count(mSTMT); mResultCount = mysql_stmt_field_count(mSTMT); if (mResultCount!=0) { if ((mResultMetadata = mysql_stmt_result_metadata(mSTMT)) == NULL) { throw SqlException(mSTMT, "Error in SqlPreparedStatement::mysql_stmt_result_metadata"); } MYSQL_FIELD* field = nullptr; while ((field = mysql_fetch_field(mResultMetadata)) != nullptr) { mResultFields.Add(field); } } return true; }
bool MySQLStmtVariables::bind_result(MYSQL_STMT *stmt) { assert(m_arr.size() == mysql_stmt_field_count(stmt)); MYSQL_RES *res = mysql_stmt_result_metadata(stmt); MYSQL_FIELD *fields = mysql_fetch_fields(res); for(int i = 0; i < m_arr.size(); i++) { MYSQL_BIND *b = &m_vars[i]; b->is_unsigned = (fields[i].flags & UNSIGNED_FLAG) ? 1 : 0; switch (fields[i].type) { case MYSQL_TYPE_NULL: b->buffer_type = MYSQL_TYPE_NULL; case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_FLOAT: b->buffer_type = MYSQL_TYPE_DOUBLE; b->buffer_length = sizeof(double); break; case MYSQL_TYPE_LONGLONG: #if MYSQL_VERSION_ID > 50002 case MYSQL_TYPE_BIT: #endif case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_TINY: b->buffer_type = MYSQL_TYPE_LONGLONG; b->buffer_length = sizeof(int64_t); break; case MYSQL_TYPE_DATE: case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_TIME: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: b->buffer_type = MYSQL_TYPE_STRING; b->buffer_length = fields[i].max_length ? fields[i].max_length : fields[i].length; break; default: // There exists some more types in this enum like MYSQL_TYPE_TIMESTAMP2 // MYSQL_TYPE_DATETIME2, MYSQL_TYPE_TIME2 but they are just used on the // server assert(false); } if (b->buffer_length > 0) { b->buffer = calloc(1, b->buffer_length); } } mysql_free_result(res); return !mysql_stmt_bind_result(stmt, m_vars); }
void fun() { const uint32_t STRING_SIZE = 50; const std::string SELECT_SAMPLE = "SELECT fid, fipbegin, fipend, flocation FROM tiptable"; MYSQL_BIND bind[4]; MYSQL_RES *prepare_meta_result; MYSQL_TIME ts; (void)ts; int param_count; MYSQL* mysql = init(); if (!mysql) { printf("error\n"); return; } /* Prepare a SELECT query to fetch data from test_table */ MYSQL_STMT* stmt = mysql_stmt_init(mysql); if (!stmt) { fprintf(stderr, " mysql_stmt_init(), out of memory\n"); exit(0); } if (mysql_stmt_prepare(stmt, SELECT_SAMPLE.c_str(), SELECT_SAMPLE.size())) { fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } fprintf(stdout, " prepare, SELECT successful\n"); /* Get the parameter count from the statement */ param_count = (int)mysql_stmt_param_count(stmt); fprintf(stdout, " total parameters in SELECT: %d\n", param_count); if (param_count != 0) { fprintf(stderr, " invalid parameter count returned by MySQL\n"); exit(0); } /* Fetch result set meta information */ prepare_meta_result = mysql_stmt_result_metadata(stmt); if (!prepare_meta_result) { fprintf(stderr, " mysql_stmt_result_metadata(), returned no meta information\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } /* Get total columns in the query */ int column_count = mysql_num_fields(prepare_meta_result); fprintf(stdout, " total columns in SELECT statement: %d\n", column_count); if (column_count != 4) { fprintf(stderr, " invalid column count returned by MySQL\n"); exit(0); } /* Execute the SELECT query */ if (mysql_stmt_execute(stmt)) { fprintf(stderr, " mysql_stmt_execute(), failed\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } /* Bind the result buffers for all 4 columns before fetching them */ unsigned long length[4]; my_bool is_null[4]; my_bool error[4]; short small_data; (void)small_data; int int_data[4]; char str_data[4][STRING_SIZE]; std::memset(bind, 0, sizeof(bind)); /* INTEGER COLUMN */ bind[0].buffer_type = MYSQL_TYPE_LONG; bind[0].buffer = (char *)&int_data[0]; bind[0].is_null = &is_null[0]; bind[0].length = &length[0]; bind[0].error = &error[0]; bind[1].buffer_type = MYSQL_TYPE_LONG; bind[1].buffer = (char *)&int_data[1]; bind[1].is_null = &is_null[1]; bind[1].length = &length[1]; bind[1].error = &error[1]; bind[2].buffer_type = MYSQL_TYPE_LONG; bind[2].buffer = (char *)&int_data[2]; bind[2].is_null = &is_null[2]; bind[2].length = &length[2]; bind[2].error = &error[2]; bind[3].buffer_type = MYSQL_TYPE_STRING; bind[3].buffer = (char *)&str_data[3]; bind[3].buffer_length = STRING_SIZE; bind[3].is_null = &is_null[3]; bind[3].length = &length[3]; bind[3].error = &error[3]; /* TIMESTAMP COLUMN */ /* bind[3].buffer_type = MYSQL_TYPE_TIMESTAMP; bind[3].buffer = (char *)&ts; bind[3].is_null = &is_null[3]; bind[3].length = &length[3]; bind[3].error = &error[3]; */ /* Bind the result buffers */ if (mysql_stmt_bind_result(stmt, bind)) { fprintf(stderr, " mysql_stmt_bind_result() failed\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } /* Now buffer all results to client (optional step) */ auto tbegin = std::chrono::system_clock::now(); if (mysql_stmt_store_result(stmt)) { fprintf(stderr, " mysql_stmt_store_result() failed\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } auto tend = std::chrono::system_clock::now(); fprintf(stderr, "mysql_stmt_store_result use %d\n", (int)std::chrono::duration_cast<std::chrono::seconds>(tend-tbegin).count()); fprintf(stderr, "total rows:%d\n",(int)::mysql_stmt_num_rows(stmt)); /* Fetch all rows */ int row_count = 0; fprintf(stdout, "Fetching results ...\n"); while (!mysql_stmt_fetch(stmt)) { row_count++; fprintf(stdout, " row %d\n", row_count); /* column 1 */ fprintf(stdout, " column1: "); if (is_null[0]) fprintf(stdout, " NULL\t"); else fprintf(stdout, " %d(%ld)\t", int_data[0], length[0]); /* column 2 */ fprintf(stdout, " column2: "); if (is_null[1]) fprintf(stdout, " NULL\t"); else fprintf(stdout, " %d(%ld)\t", int_data[1], length[1]); /* column 3 */ fprintf(stdout, " column3: "); if (is_null[2]) fprintf(stdout, " NULL\t"); else fprintf(stdout, " %d(%ld)\t", int_data[2], length[2]); fprintf(stdout, " column4: "); if (is_null[3]) fprintf(stdout, " NULL\t"); else fprintf(stdout, " %s(%ld)\t", str_data[3], length[3]); /* column 4 */ /* fprintf(stdout, " column4 (timestamp): "); if (is_null[3]) fprintf(stdout, " NULL\n"); else fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, length[3]); */ fprintf(stdout, "\n"); if (row_count > 10) break; } /* Validate rows fetched */ fprintf(stdout, " total rows fetched: %d\n", row_count); /* Free the prepared result metadata */ mysql_free_result(prepare_meta_result); /* Close the statement */ if (mysql_stmt_close(stmt)) { fprintf(stderr, " failed while closing the statement\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } }
long MyRecordset::LoadStmt(MYSQL_STMT* stmt, long indcol) { MYSQL_FIELD *fields; MYSQL_BIND* binds = NULL; /* for output buffers */ MYSQL_RES *result = NULL; result = mysql_stmt_result_metadata(stmt); test_stmt_error(stmt, result == NULL); char* buffer = NULL; nbcol = mysql_stmt_field_count(stmt); fields = mysql_fetch_fields(result); binds = new MYSQL_BIND[nbcol*sizeof(MYSQL_BIND)]; memset(binds, 0, sizeof (MYSQL_BIND) * nbcol); int size=0; for(int i = 0; i < nbcol; i++) size+=fields[i].length; buffer = new char[size*8]; memset(buffer, 0, sizeof (char) * size*8); int pos = 0; for(int i = 0; i < nbcol; i++) { colname.push_back(fields[i].name); coltype.push_back(fields[i].type); binds[i].buffer_type = fields[i].type; binds[i].is_null = 0; binds[i].buffer = &buffer[pos]; binds[i].buffer_length = fields[i].length; pos+=fields[i].length; } int status = mysql_stmt_bind_result(stmt, binds); test_stmt_error(stmt, status); int linenum = 0; char tmp[8000]; while(true) { status = mysql_stmt_fetch(stmt); if (status == 1 || status == MYSQL_NO_DATA) break; data.push_back(vector<string>()); MYSQL_TIME ts; string stmp; for(int i = 0; i < nbcol; i++) { switch (binds[i].buffer_type) { case MYSQL_TYPE_TINY: snprintf(tmp, 8000, "%d", *((signed char*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_SHORT: snprintf(tmp, 8000, "%d", *((short int*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_LONG: snprintf(tmp, 8000, "%d", *((int*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_LONGLONG: snprintf(tmp, 8000, "%lld", *((long long int*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_DECIMAL: snprintf(tmp, 8000, "%s", ((char*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_NEWDECIMAL: snprintf(tmp, 8000, "%s", (char*)(binds[i].buffer)); stmp = string(tmp); data.back().push_back(stmp); break; case MYSQL_TYPE_FLOAT: snprintf(tmp, 8000, "%f", *((float*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_DOUBLE: snprintf(tmp, 8000, "%f", *((double*)(binds[i].buffer))); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_TIME: ts = *((MYSQL_TIME*)(binds[i].buffer)); snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_DATE: ts = *((MYSQL_TIME*)(binds[i].buffer)); snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_DATETIME: ts = *((MYSQL_TIME*)(binds[i].buffer)); snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_TIMESTAMP: ts = *((MYSQL_TIME*)(binds[i].buffer)); snprintf(tmp, 8000, "%04d-%02d-%02d %02d:%02d:%02d", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_STRING: snprintf(tmp, 8000, "%s", (char*)binds[i].buffer); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_VAR_STRING: snprintf(tmp, 8000, "%s", (char*)binds[i].buffer); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_BLOB: snprintf(tmp, 8000, "%s", (char*)binds[i].buffer); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_BIT: snprintf(tmp, 8000, "%s", (char*)binds[i].buffer); data.back().push_back(string(tmp)); break; case MYSQL_TYPE_NULL: data.back().push_back(""); break; default: printf("UNKNOWN TYPE %s %d\n", fields[i].name, binds[i].buffer_type); exit(1); break; } if(indcol != -1 && i == indcol) { int cval = *((int*)(binds[i].buffer)); index[cval] = linenum; } } linenum++; } nbrow = linenum; while(mysql_stmt_next_result(stmt) == 0) { linenum+=0; } mysql_free_result(result); delete[] binds; delete[] buffer; return 0; }
static DWORD GroupSyncIncrChanges(DB_CONTEXT *db, SYNC_CONTEXT *sync) { CHAR *query; BYTE syncEvent; CHAR syncInfo[255]; CHAR groupName[_MAX_NAME + 1]; DWORD error; GROUPFILE groupFile; INT result; MYSQL_BIND bindInput[2]; MYSQL_BIND bindOutput[3]; MYSQL_RES *metadata; MYSQL_STMT *stmt; ASSERT(db != NULL); ASSERT(sync != NULL); // // Prepare statement and bind parameters // stmt = db->stmt[7]; query = "SELECT name, type, info FROM io_group_changes" " WHERE time BETWEEN ? AND ?" " ORDER BY id ASC"; result = mysql_stmt_prepare(stmt, query, strlen(query)); if (result != 0) { TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } DB_CHECK_PARAMS(bindInput, stmt); ZeroMemory(&bindInput, sizeof(bindInput)); bindInput[0].buffer_type = MYSQL_TYPE_LONG; bindInput[0].buffer = &sync->prevUpdate; bindInput[0].is_unsigned = TRUE; bindInput[1].buffer_type = MYSQL_TYPE_LONG; bindInput[1].buffer = &sync->currUpdate; bindInput[1].is_unsigned = TRUE; result = mysql_stmt_bind_param(stmt, bindInput); if (result != 0) { TRACE("Unable to bind parameters: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Execute prepared statement // result = mysql_stmt_execute(stmt); if (result != 0) { LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Bind and fetch results // DB_CHECK_RESULTS(bindOutput, metadata); ZeroMemory(&bindOutput, sizeof(bindOutput)); bindOutput[0].buffer_type = MYSQL_TYPE_STRING; bindOutput[0].buffer = groupName; bindOutput[0].buffer_length = sizeof(groupName); bindOutput[1].buffer_type = MYSQL_TYPE_TINY; bindOutput[1].buffer = &syncEvent; bindOutput[1].is_unsigned = TRUE; bindOutput[2].buffer_type = MYSQL_TYPE_STRING; bindOutput[2].buffer = syncInfo; bindOutput[2].buffer_length = sizeof(syncInfo); result = mysql_stmt_bind_result(stmt, bindOutput); if (result != 0) { TRACE("Unable to bind results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_store_result(stmt); if (result != 0) { TRACE("Unable to buffer results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Process result set // for (;;) { if (mysql_stmt_fetch(stmt) != 0) { break; } switch ((SYNC_EVENT)syncEvent) { case SYNC_EVENT_CREATE: TRACE("GroupSyncIncr: Create(%s)", groupName); // Read group file from database ZeroMemory(&groupFile, sizeof(GROUPFILE)); error = DbGroupRead(db, groupName, &groupFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to read group \"%s\" (error %lu).", groupName, error); } else { // Create local user error = GroupEventCreate(groupName, &groupFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to create group \"%s\" (error %lu).", groupName, error); } } break; case SYNC_EVENT_RENAME: TRACE("GroupSyncIncr: Rename(%s,%s)", groupName, syncInfo); error = GroupEventRename(groupName, syncInfo); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to rename group \"%s\" to \"%s\" (error %lu).", groupName, syncInfo, error); } break; case SYNC_EVENT_DELETE: TRACE("GroupSyncIncr: Delete(%s)", groupName); error = GroupEventDelete(groupName); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to delete group \"%s\" (error %lu).", groupName, error); } break; default: LOG_ERROR("Unknown sync event %d.", syncEvent); break; } } mysql_free_result(metadata); return ERROR_SUCCESS; }
static int dbd_mysql_pselect_internal(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **res, apr_dbd_prepared_t *statement, int random, MYSQL_BIND *bind) { int nfields, i; my_bool *is_nullr; #if MYSQL_VERSION_ID >= 50000 my_bool *error; #endif int ret; unsigned long *length, maxlen; ret = mysql_stmt_bind_param(statement->stmt, bind); if (ret == 0) { ret = mysql_stmt_execute(statement->stmt); if (!ret) { if (!*res) { *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); } (*res)->random = random; (*res)->statement = statement->stmt; (*res)->res = mysql_stmt_result_metadata(statement->stmt); (*res)->pool = pool; apr_pool_cleanup_register(pool, (*res)->res, free_result, apr_pool_cleanup_null); nfields = mysql_num_fields((*res)->res); if (!(*res)->bind) { (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND)); length = apr_pcalloc(pool, nfields*sizeof(unsigned long)); #if MYSQL_VERSION_ID >= 50000 error = apr_palloc(pool, nfields*sizeof(my_bool)); #endif is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool)); for ( i = 0; i < nfields; ++i ) { maxlen = ((*res)->res->fields[i].length < sql->fldsz ? (*res)->res->fields[i].length : sql->fldsz) + 1; if ((*res)->res->fields[i].type == MYSQL_TYPE_BLOB) { (*res)->bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB; } else { (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; } (*res)->bind[i].buffer_length = maxlen; (*res)->bind[i].length = &length[i]; (*res)->bind[i].buffer = apr_palloc(pool, maxlen); (*res)->bind[i].is_null = is_nullr+i; #if MYSQL_VERSION_ID >= 50000 (*res)->bind[i].error = error+i; #endif } } ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind); if (!ret) { ret = mysql_stmt_store_result(statement->stmt); } } } if (ret != 0) { ret = mysql_stmt_errno(statement->stmt); } return ret; }
static int dbd_mysql_pvselect(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **res, apr_dbd_prepared_t *statement, int random, va_list args) { int i; int nfields; char *arg; my_bool is_null = FALSE; my_bool *is_nullr; #if MYSQL_VERSION_ID >= 50000 my_bool *error; #endif int ret; unsigned long *length, maxlen; int nargs; MYSQL_BIND *bind; if (sql->trans && sql->trans->errnum) { return sql->trans->errnum; } nargs = mysql_stmt_param_count(statement->stmt); bind = apr_palloc(pool, nargs*sizeof(MYSQL_BIND)); for (i=0; i < nargs; ++i) { arg = va_arg(args, char*); bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; bind[i].buffer = arg; bind[i].buffer_length = strlen(arg); bind[i].length = &bind[i].buffer_length; bind[i].is_null = &is_null; bind[i].is_unsigned = 0; } ret = mysql_stmt_bind_param(statement->stmt, bind); if (ret == 0) { ret = mysql_stmt_execute(statement->stmt); if (!ret) { if (!*res) { *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); } (*res)->random = random; (*res)->statement = statement->stmt; (*res)->res = mysql_stmt_result_metadata(statement->stmt); apr_pool_cleanup_register(pool, (*res)->res, free_result, apr_pool_cleanup_null); nfields = mysql_num_fields((*res)->res); if (!(*res)->bind) { (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND)); length = apr_pcalloc(pool, nfields*sizeof(unsigned long)); #if MYSQL_VERSION_ID >= 50000 error = apr_palloc(pool, nfields*sizeof(my_bool)); #endif is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool)); for ( i = 0; i < nfields; ++i ) { maxlen = ((*res)->res->fields[i].length < sql->fldsz ? (*res)->res->fields[i].length : sql->fldsz) + 1; (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; (*res)->bind[i].buffer_length = maxlen; (*res)->bind[i].length = &length[i]; (*res)->bind[i].buffer = apr_palloc(pool, maxlen); (*res)->bind[i].is_null = is_nullr+i; #if MYSQL_VERSION_ID >= 50000 (*res)->bind[i].error = error+i; #endif } } ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind); if (!ret) { ret = mysql_stmt_store_result(statement->stmt); } } } if (ret != 0) { ret = mysql_stmt_errno(statement->stmt); } if (sql->trans) { sql->trans->errnum = ret; } return ret; }
int sqlite3_prepare(sqlite3* db, /* Database handle */ const char* zSql, /* SQL statement, UTF-8 encoded */ int nBytes, /* Maximum length of zSql in bytes. */ mysqlite3_stmt** ppStmt, /* OUT: Statement handle */ const char** pzTail /* OUT: Pointer to unused portion of zSql */ ) { int rc = SQLITE_OK; mysqlite3_stmt* stmt = (mysqlite3_stmt*)malloc(sizeof(mysqlite3_stmt)); stmt->mydb = db; stmt->mystmt = mysql_stmt_init(db); stmt->myres = NULL; stmt->myparams = NULL; stmt->results = NULL; stmt->nresults = 0; stmt->executed = 0; stmt->nrow = 0; stmt->lengths = NULL; int stmt_len = statement_length(zSql, nBytes); if (nBytes > 0 && nBytes < stmt_len) { stmt_len = nBytes; } // "Strip" trailing semicolon, if present if (zSql[stmt_len-1] == ';') { stmt_len -= 1; } // Make a copy of the SQL and save it stmt->sql = strndup(zSql, stmt_len); mysql_stmt_prepare(stmt->mystmt, stmt->sql, stmt_len); stmt->nparams = mysql_stmt_param_count(stmt->mystmt); if (stmt->nparams > 0) { stmt->myparams = (MYSQL_BIND*)malloc(sizeof(MYSQL_BIND)*stmt->nparams); } /* Result set information */ stmt->myres = mysql_stmt_result_metadata(stmt->mystmt); stmt->ncolumns = 0; if (stmt->myres) { /* Get total columns in the query */ stmt->ncolumns = mysql_num_fields(stmt->myres); // Set STMT_ATTR_UPDATE_MAX_LENGTH attribute my_bool aBool = 1; mysql_stmt_attr_set(stmt->mystmt, STMT_ATTR_UPDATE_MAX_LENGTH, &aBool); if (stmt->ncolumns > 0) { stmt->results = malloc(sizeof(MYSQL_BIND)* stmt->ncolumns); stmt->lengths = malloc(sizeof(unsigned long)* stmt->ncolumns); memset(stmt->results, 0, sizeof(MYSQL_BIND)* stmt->ncolumns); int i; for (i=0; i < stmt->ncolumns; i++) { //stmt->results[i].buffer = malloc(stmt->myres->fields[i].max_length); //stmt->results[i].buffer_type = stmt->myres->fields[i].type; //stmt->results[i].buffer_length = stmt->myres->fields[i].max_length; stmt->results[i].buffer = 0; stmt->results[i].is_null = 0; stmt->results[i].buffer_length = 0; stmt->results[i].length = &stmt->lengths[i]; } } } *ppStmt = (mysqlite3_stmt*)stmt; if (pzTail) { (*pzTail) = NULL; if (stmt_len < strlen(zSql)) { (*pzTail) = zSql+stmt_len; if (*pzTail[0] == ';') { (*pzTail)++; } if (*pzTail[0] == '\0') { *pzTail = NULL; } } } return rc; };
static DWORD UserSyncFull(DB_CONTEXT *db) { BOOL removed; CHAR *query; CHAR userName[_MAX_NAME + 1]; DWORD error; DWORD i; USERFILE userFile; INT result; NAME_ENTRY *entry; NAME_LIST list; MYSQL_BIND bind[17]; MYSQL_RES *metadata; MYSQL_STMT *stmt; ASSERT(db != NULL); TRACE("db=%p", db); // // Build list of user IDs // error = NameListCreateUsers(&list); if (error != ERROR_SUCCESS) { LOG_ERROR("Unable to create user ID list (error %lu).", error); return error; } // // Prepare and execute statement // stmt = db->stmt[7]; query = "SELECT name,description,flags,home,limits,password,vfsfile,credits," " ratio,alldn,allup,daydn,dayup,monthdn,monthup,wkdn,wkup" " FROM io_user"; result = mysql_stmt_prepare(stmt, query, strlen(query)); if (result != 0) { LOG_WARN("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { LOG_WARN("Unable to retrieve result metadata: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_execute(stmt); if (result != 0) { LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Bind and fetch results // DB_CHECK_RESULTS(bind, metadata); ZeroMemory(&bind, sizeof(bind)); bind[0].buffer_type = MYSQL_TYPE_STRING; bind[0].buffer = userName; bind[0].buffer_length = sizeof(userName); bind[1].buffer_type = MYSQL_TYPE_STRING; bind[1].buffer = userFile.Tagline; bind[1].buffer_length = sizeof(userFile.Tagline); bind[2].buffer_type = MYSQL_TYPE_STRING; bind[2].buffer = userFile.Flags; bind[2].buffer_length = sizeof(userFile.Flags); bind[3].buffer_type = MYSQL_TYPE_STRING; bind[3].buffer = userFile.Home; bind[3].buffer_length = sizeof(userFile.Home); bind[4].buffer_type = MYSQL_TYPE_BLOB; bind[4].buffer = &userFile.Limits; bind[4].buffer_length = sizeof(userFile.Limits); bind[5].buffer_type = MYSQL_TYPE_BLOB; bind[5].buffer = &userFile.Password; bind[5].buffer_length = sizeof(userFile.Password); bind[6].buffer_type = MYSQL_TYPE_STRING; bind[6].buffer = userFile.MountFile; bind[6].buffer_length = sizeof(userFile.MountFile); bind[7].buffer_type = MYSQL_TYPE_BLOB; bind[7].buffer = &userFile.Ratio; bind[7].buffer_length = sizeof(userFile.Ratio); bind[8].buffer_type = MYSQL_TYPE_BLOB; bind[8].buffer = &userFile.Credits; bind[8].buffer_length = sizeof(userFile.Credits); bind[9].buffer_type = MYSQL_TYPE_BLOB; bind[9].buffer = &userFile.DayUp; bind[9].buffer_length = sizeof(userFile.DayUp); bind[10].buffer_type = MYSQL_TYPE_BLOB; bind[10].buffer = &userFile.DayDn; bind[10].buffer_length = sizeof(userFile.DayDn); bind[11].buffer_type = MYSQL_TYPE_BLOB; bind[11].buffer = &userFile.WkUp; bind[11].buffer_length = sizeof(userFile.WkUp); bind[12].buffer_type = MYSQL_TYPE_BLOB; bind[12].buffer = &userFile.WkDn; bind[12].buffer_length = sizeof(userFile.WkDn); bind[13].buffer_type = MYSQL_TYPE_BLOB; bind[13].buffer = &userFile.MonthUp; bind[13].buffer_length = sizeof(userFile.MonthUp); bind[14].buffer_type = MYSQL_TYPE_BLOB; bind[14].buffer = &userFile.MonthDn; bind[14].buffer_length = sizeof(userFile.MonthDn); bind[15].buffer_type = MYSQL_TYPE_BLOB; bind[15].buffer = &userFile.AllUp; bind[15].buffer_length = sizeof(userFile.AllUp); bind[16].buffer_type = MYSQL_TYPE_BLOB; bind[16].buffer = &userFile.AllDn; bind[16].buffer_length = sizeof(userFile.AllDn); result = mysql_stmt_bind_result(stmt, bind); if (result != 0) { LOG_WARN("Unable to bind results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_store_result(stmt); if (result != 0) { LOG_WARN("Unable to buffer results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Process result set // for (;;) { ZeroMemory(&userFile, sizeof(USERFILE)); if (mysql_stmt_fetch(stmt) != 0) { break; } // Remove user from the list beforehand in case DbUserReadExtra() fails removed = NameListRemove(&list, userName); // Read the user's admin-groups, groups, and hosts error = DbUserReadExtra(db, userName, &userFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to read user \"%s\" (error %lu).", userName, error); continue; } // // If ioFTPD fails to open a user at start-up, the user will still // have an entry in the UserIdTable file but ioFTPD considers them // gone. The call to UserExists() is done to check for this. // if (!removed || !UserExists(userName)) { TRACE("UserSyncFull: Create(%s)", userName); // User does not exist locally, create it. error = UserEventCreate(userName, &userFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to create user \"%s\" (error %lu).", userName, error); } } else { TRACE("UserSyncFull: Update(%s)", userName); // User already exists locally, update it. error = UserEventUpdate(userName, &userFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to update user \"%s\" (error %lu).", userName, error); } } } mysql_free_result(metadata); // // Delete remaining users // for (i = 0; i < list.count; i++) { entry = list.array[i]; TRACE("UserSyncFull: Delete(%s,%d)", entry->name, entry->id); // User does not exist on database, delete it. error = UserEventDeleteEx(entry->name, entry->id); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to delete user \"%s\" (error %lu).", entry->name, error); } } NameListDestroy(&list); return ERROR_SUCCESS; }
static VALUE each(VALUE self) { VALUE block; MYSQL_STMT *stmt; MYSQL_RES *result; Data_Get_Struct(self, MYSQL_STMT, stmt); result = mysql_stmt_result_metadata(stmt); if (result) { MYSQL_BIND *result_buffers; my_bool *is_null; my_bool *error; unsigned long *length; MYSQL_FIELD *fields; unsigned long field_count; unsigned long i; if (mysql_stmt_store_result(stmt)) { rb_raise(cMysql2Error, "%s", mysql_stmt_error(stmt)); } fields = mysql_fetch_fields(result); field_count = mysql_num_fields(result); result_buffers = xcalloc(field_count, sizeof(MYSQL_BIND)); is_null = xcalloc(field_count, sizeof(my_bool)); error = xcalloc(field_count, sizeof(my_bool)); length = xcalloc(field_count, sizeof(unsigned long)); for (i = 0; i < field_count; i++) { result_buffers[i].buffer_type = fields[i].type; // mysql type | C type switch(fields[i].type) { case MYSQL_TYPE_NULL: // NULL break; case MYSQL_TYPE_TINY: // signed char result_buffers[i].buffer = xcalloc(1, sizeof(signed char)); result_buffers[i].buffer_length = sizeof(signed char); break; case MYSQL_TYPE_SHORT: // short int result_buffers[i].buffer = xcalloc(1, sizeof(short int)); result_buffers[i].buffer_length = sizeof(short int); break; case MYSQL_TYPE_INT24: // int case MYSQL_TYPE_LONG: // int case MYSQL_TYPE_YEAR: // int result_buffers[i].buffer = xcalloc(1, sizeof(int)); result_buffers[i].buffer_length = sizeof(int); break; case MYSQL_TYPE_LONGLONG: // long long int result_buffers[i].buffer = xcalloc(1, sizeof(long long int)); result_buffers[i].buffer_length = sizeof(long long int); break; case MYSQL_TYPE_FLOAT: // float case MYSQL_TYPE_DOUBLE: // double result_buffers[i].buffer = xcalloc(1, sizeof(double)); result_buffers[i].buffer_length = sizeof(double); break; case MYSQL_TYPE_TIME: // MYSQL_TIME case MYSQL_TYPE_DATE: // MYSQL_TIME case MYSQL_TYPE_NEWDATE: // MYSQL_TIME case MYSQL_TYPE_DATETIME: // MYSQL_TIME case MYSQL_TYPE_TIMESTAMP: // MYSQL_TIME result_buffers[i].buffer = xcalloc(1, sizeof(MYSQL_TIME)); result_buffers[i].buffer_length = sizeof(MYSQL_TIME); break; case MYSQL_TYPE_DECIMAL: // char[] case MYSQL_TYPE_NEWDECIMAL: // char[] case MYSQL_TYPE_STRING: // char[] case MYSQL_TYPE_VAR_STRING: // char[] case MYSQL_TYPE_VARCHAR: // char[] case MYSQL_TYPE_TINY_BLOB: // char[] case MYSQL_TYPE_BLOB: // char[] case MYSQL_TYPE_MEDIUM_BLOB: // char[] case MYSQL_TYPE_LONG_BLOB: // char[] case MYSQL_TYPE_BIT: // char[] case MYSQL_TYPE_SET: // char[] case MYSQL_TYPE_ENUM: // char[] case MYSQL_TYPE_GEOMETRY: // char[] result_buffers[i].buffer = malloc(fields[i].max_length); result_buffers[i].buffer_length = fields[i].max_length; break; default: rb_raise(cMysql2Error, "unhandled mysql type: %d", fields[i].type); } result_buffers[i].is_null = &is_null[i]; result_buffers[i].length = &length[i]; result_buffers[i].error = &error[i]; result_buffers[i].is_unsigned = ((fields[i].flags & UNSIGNED_FLAG) != 0); } if(mysql_stmt_bind_result(stmt, result_buffers)) { for(i = 0; i < field_count; i++) { if (result_buffers[i].buffer) { free(result_buffers[i].buffer); } } free(result_buffers); free(is_null); free(error); free(length); rb_raise(cMysql2Error, "%s", mysql_stmt_error(stmt)); } block = rb_block_proc(); while(!mysql_stmt_fetch(stmt)) { VALUE row = rb_ary_new2((long)field_count); for(i = 0; i < field_count; i++) { VALUE column = Qnil; MYSQL_TIME *ts; if (is_null[i]) { column = Qnil; } else { switch(result_buffers[i].buffer_type) { case MYSQL_TYPE_TINY: // signed char if (result_buffers[i].is_unsigned) { column = UINT2NUM(*((unsigned char*)result_buffers[i].buffer)); } else { column = INT2NUM(*((signed char*)result_buffers[i].buffer)); } break; case MYSQL_TYPE_SHORT: // short int if (result_buffers[i].is_unsigned) { column = UINT2NUM(*((unsigned short int*)result_buffers[i].buffer)); } else { column = INT2NUM(*((short int*)result_buffers[i].buffer)); } break; case MYSQL_TYPE_INT24: // int case MYSQL_TYPE_LONG: // int case MYSQL_TYPE_YEAR: // int if (result_buffers[i].is_unsigned) { column = UINT2NUM(*((unsigned int*)result_buffers[i].buffer)); } else { column = INT2NUM(*((int*)result_buffers[i].buffer)); } break; case MYSQL_TYPE_LONGLONG: // long long int if (result_buffers[i].is_unsigned) { column = ULL2NUM(*((unsigned long long int*)result_buffers[i].buffer)); } else { column = LL2NUM(*((long long int*)result_buffers[i].buffer)); } break; case MYSQL_TYPE_FLOAT: // float column = rb_float_new((double)(*((float*)result_buffers[i].buffer))); break; case MYSQL_TYPE_DOUBLE: // double column = rb_float_new((double)(*((double*)result_buffers[i].buffer))); break; case MYSQL_TYPE_DATE: // MYSQL_TIME ts = (MYSQL_TIME*)result_buffers[i].buffer; column = rb_funcall(cDate, rb_intern("new"), 3, INT2NUM(ts->year), INT2NUM(ts->month), INT2NUM(ts->day)); break; case MYSQL_TYPE_TIME: // MYSQL_TIME ts = (MYSQL_TIME*)result_buffers[i].buffer; column = rb_funcall(rb_cTime, rb_intern("mktime"), 6, UINT2NUM(Qnil), UINT2NUM(Qnil), UINT2NUM(Qnil), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second)); break; case MYSQL_TYPE_NEWDATE: // MYSQL_TIME case MYSQL_TYPE_DATETIME: // MYSQL_TIME case MYSQL_TYPE_TIMESTAMP: // MYSQL_TIME ts = (MYSQL_TIME*)result_buffers[i].buffer; column = rb_funcall(rb_cTime, rb_intern("mktime"), 6, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second)); break; case MYSQL_TYPE_DECIMAL: // char[] case MYSQL_TYPE_NEWDECIMAL: // char[] column = rb_funcall(cBigDecimal, rb_intern("new"), 1, rb_str_new(result_buffers[i].buffer, *(result_buffers[i].length))); break; case MYSQL_TYPE_STRING: // char[] case MYSQL_TYPE_VAR_STRING: // char[] case MYSQL_TYPE_VARCHAR: // char[] case MYSQL_TYPE_TINY_BLOB: // char[] case MYSQL_TYPE_BLOB: // char[] case MYSQL_TYPE_MEDIUM_BLOB: // char[] case MYSQL_TYPE_LONG_BLOB: // char[] case MYSQL_TYPE_BIT: // char[] case MYSQL_TYPE_SET: // char[] case MYSQL_TYPE_ENUM: // char[] case MYSQL_TYPE_GEOMETRY: // char[] column = rb_str_new(result_buffers[i].buffer, *(result_buffers[i].length)); break; default: rb_raise(cMysql2Error, "unhandled buffer type: %d", result_buffers[i].buffer_type); break; } } rb_ary_store(row, (long)i, column); } rb_yield(row); } free(result_buffers); free(is_null); free(error); free(length); } return self; }
/* * 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; }
const RecordSet &MySqlDataProvider::processSql() { if (!mIsConnected) throw std::runtime_error("not connected to database"); // Since we'll have to return something in all cases, // we clear the result member first. mRecordSet.clear(); if (!mBind) { LOG_ERROR("MySqlDataProvider::processSql: " "No bind done before processing."); return mRecordSet; } if (mysql_stmt_bind_param(mStmt, mBind)) { LOG_ERROR("MySqlDataProvider::processSql Bind params failed: " << mysql_stmt_error(mStmt)); return mRecordSet; } if (mysql_stmt_field_count(mStmt) > 0) { MYSQL_BIND* resultBind; MYSQL_RES* res; if (mysql_stmt_execute(mStmt)) { LOG_ERROR("MySqlDataProvider::processSql Execute failed: " << mysql_stmt_error(mStmt)); } res = mysql_stmt_result_metadata(mStmt); // set the field names. unsigned nFields = mysql_num_fields(res); MYSQL_FIELD* fields = mysql_fetch_fields(res); Row fieldNames; resultBind = new MYSQL_BIND[mysql_num_fields(res)]; unsigned i = 0; for (i = 0; i < mysql_num_fields(res); ++i) { resultBind[i].buffer_type = MYSQL_TYPE_STRING; resultBind[i].buffer = (void*) new char[255]; resultBind[i].buffer_length = 255; resultBind[i].is_null = new my_bool; resultBind[i].length = new unsigned long; resultBind[i].error = new my_bool; } if (mysql_stmt_bind_result(mStmt, resultBind)) { LOG_ERROR("MySqlDataProvider::processSql Bind result failed: " << mysql_stmt_error(mStmt)); } for (i = 0; i < nFields; ++i) fieldNames.push_back(fields[i].name); mRecordSet.setColumnHeaders(fieldNames); // store the result of the query. if (mysql_stmt_store_result(mStmt)) throw DbSqlQueryExecFailure(mysql_stmt_error(mStmt)); // populate the RecordSet. while (!mysql_stmt_fetch(mStmt)) { Row r; for (i = 0; i < nFields; ++i) r.push_back(static_cast<char *>(resultBind[i].buffer)); mRecordSet.add(r); } delete[] resultBind; } else { if (mysql_stmt_execute(mStmt)) { LOG_ERROR("MySqlDataProvider::processSql Execute failed: " << mysql_stmt_error(mStmt)); } } // Free memory mysql_stmt_free_result(mStmt); return mRecordSet; }
static int my_process_stmt_result(MYSQL_STMT *stmt) { int field_count; int row_count= 0; MYSQL_BIND buffer[MAX_RES_FIELDS]; MYSQL_FIELD *field; MYSQL_RES *result; char data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE]; ulong length[MAX_RES_FIELDS]; my_bool is_null[MAX_RES_FIELDS]; int rc, i; if (!(result= mysql_stmt_result_metadata(stmt))) /* No meta info */ { while (!mysql_stmt_fetch(stmt)) row_count++; return row_count; } field_count= MY_MIN(mysql_num_fields(result), MAX_RES_FIELDS); memset(buffer, 0, sizeof(buffer)); memset(length, 0, sizeof(length)); memset(is_null, 0, sizeof(is_null)); for(i= 0; i < field_count; i++) { buffer[i].buffer_type= MYSQL_TYPE_STRING; buffer[i].buffer_length= MAX_FIELD_DATA_SIZE; buffer[i].length= &length[i]; buffer[i].buffer= (void *) data[i]; buffer[i].is_null= &is_null[i]; } rc= mysql_stmt_bind_result(stmt, buffer); check_execute(stmt, rc); rc= 1; mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); rc= mysql_stmt_store_result(stmt); check_execute(stmt, rc); my_print_result_metadata(result); mysql_field_seek(result, 0); while ((rc= mysql_stmt_fetch(stmt)) == 0) { if (!opt_silent) { fputc('\t', stdout); fputc('|', stdout); } mysql_field_seek(result, 0); for (i= 0; i < field_count; i++) { field= mysql_fetch_field(result); if (!opt_silent) { if (is_null[i]) fprintf(stdout, " %-*s |", (int) field->max_length, "NULL"); else if (length[i] == 0) { data[i][0]= '\0'; /* unmodified buffer */ fprintf(stdout, " %*s |", (int) field->max_length, data[i]); } else if (IS_NUM(field->type)) fprintf(stdout, " %*s |", (int) field->max_length, data[i]); else fprintf(stdout, " %-*s |", (int) field->max_length, data[i]); } } if (!opt_silent) { fputc('\t', stdout); fputc('\n', stdout); } row_count++; } DIE_UNLESS(rc == MYSQL_NO_DATA); if (!opt_silent) { if (row_count) my_print_dashes(result); fprintf(stdout, "\n\t%d %s returned\n", row_count, row_count == 1 ? "row" : "rows"); } mysql_free_result(result); return row_count; }
/* * the @ps struct is modified and transferred to the new data model created in * this function * * See MySQL's documentation "C API Prepared Statement Type Codes": * http://docs.oracle.com/cd/E17952_01/refman-5.5-en/c-api-prepared-statement-type-codes.html */ GdaDataModel * gda_mysql_recordset_new (GdaConnection *cnc, GdaMysqlPStmt *ps, GdaSet *exec_params, GdaDataModelAccessFlags flags, GType *col_types) { GdaMysqlRecordset *model; MysqlConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (ps != NULL, NULL); cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; g_assert (ps->mysql_stmt); /* make sure @ps reports the correct number of columns using the API*/ if (_GDA_PSTMT (ps)->ncols < 0) _GDA_PSTMT(ps)->ncols = mysql_stmt_field_count (ps->mysql_stmt); /* completing @ps if not yet done */ g_assert (! ps->stmt_used); ps->stmt_used = TRUE; if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { /* create prepared statement's columns */ for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, gda_column_new ()); _GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns); /* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */ _GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols); for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL; if (col_types) { for (i = 0; ; i++) { if (col_types [i] > 0) { if (col_types [i] == G_TYPE_NONE) break; if (i >= _GDA_PSTMT (ps)->ncols) { g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, _GDA_PSTMT (ps)->ncols - 1); break; } else _GDA_PSTMT (ps)->types [i] = col_types [i]; } } } } /* get rid of old bound result if any */ if (ps->mysql_bind_result) { gint i; for (i = 0; i < ((GdaPStmt *) ps)->ncols; ++i) { g_free (ps->mysql_bind_result[i].buffer); g_free (ps->mysql_bind_result[i].is_null); g_free (ps->mysql_bind_result[i].length); } g_free (ps->mysql_bind_result); ps->mysql_bind_result = NULL; } /* fill bind result */ MYSQL_RES *mysql_res = mysql_stmt_result_metadata (ps->mysql_stmt); MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res); MYSQL_BIND *mysql_bind_result = g_new0 (MYSQL_BIND, GDA_PSTMT (ps)->ncols); GSList *list; for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; i < GDA_PSTMT (ps)->ncols; i++, list = list->next) { GdaColumn *column = GDA_COLUMN (list->data); /* use C API to set columns' information using gda_column_set_*() */ MYSQL_FIELD *field = &mysql_fields[i]; GType gtype = _GDA_PSTMT(ps)->types[i]; if (gtype == GDA_TYPE_NULL) { gtype = _gda_mysql_type_to_gda (cdata, field->type, field->charsetnr); _GDA_PSTMT(ps)->types[i] = gtype; } gda_column_set_g_type (column, gtype); gda_column_set_name (column, field->name); gda_column_set_description (column, field->name); /* binding results with types */ mysql_bind_result[i].buffer_type = field->type; mysql_bind_result[i].is_unsigned = field->flags & UNSIGNED_FLAG ? TRUE : FALSE; mysql_bind_result[i].is_null = g_malloc0 (sizeof (my_bool)); switch (mysql_bind_result[i].buffer_type) { case MYSQL_TYPE_TINY: mysql_bind_result[i].buffer = g_malloc0 (sizeof (signed char)); break; case MYSQL_TYPE_SHORT: mysql_bind_result[i].buffer = g_malloc0 (sizeof (short int)); break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_YEAR: mysql_bind_result[i].buffer = g_malloc0 (sizeof (int)); break; case MYSQL_TYPE_LONGLONG: mysql_bind_result[i].buffer = g_malloc0 (sizeof (long long)); break; case MYSQL_TYPE_NULL: break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: mysql_bind_result[i].buffer = g_malloc0 (sizeof (MYSQL_TIME)); break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: mysql_bind_result[i].buffer = g_malloc0 (sizeof (double)); break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_BIT: mysql_bind_result[i].buffer = g_malloc0 (field->max_length + 1); mysql_bind_result[i].buffer_length = field->max_length + 1; mysql_bind_result[i].length = g_malloc0 (sizeof (unsigned long)); break; default: g_warning (_("Invalid column bind data type. %d\n"), mysql_bind_result[i].buffer_type); } /*g_print ("%s(): NAME=%s, TYPE=%d, GTYPE=%s, unsigned: %d\n", __FUNCTION__, field->name, field->type, g_type_name (gtype), field->flags & UNSIGNED_FLAG);*/ } if (mysql_stmt_bind_result (ps->mysql_stmt, mysql_bind_result)) { g_warning ("mysql_stmt_bind_result failed: %s\n", mysql_stmt_error (ps->mysql_stmt)); } mysql_free_result (mysql_res); ps->mysql_bind_result = mysql_bind_result; /* determine access mode: RANDOM or CURSOR FORWARD are the only supported */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; /* create data model */ model = g_object_new (GDA_TYPE_MYSQL_RECORDSET, "connection", cnc, "prepared-stmt", ps, "model-usage", rflags, "exec-params", exec_params, NULL); model->priv->cnc = cnc; g_object_ref (G_OBJECT(cnc)); model->priv->mysql_stmt = ps->mysql_stmt; ((GdaDataSelect *) model)->advertized_nrows = mysql_stmt_affected_rows (ps->mysql_stmt); return GDA_DATA_MODEL (model); }
void stmt_fetch_init(Stmt_fetch *fetch, unsigned stmt_no_arg, const char *query_arg) { unsigned long type= CURSOR_TYPE_READ_ONLY; int rc; unsigned i; MYSQL_RES *metadata; DBUG_ENTER("stmt_fetch_init"); /* Save query and statement number for error messages */ fetch->stmt_no= stmt_no_arg; fetch->query= query_arg; fetch->handle= mysql_stmt_init(mysql); rc= mysql_stmt_prepare(fetch->handle, fetch->query, (ulong)strlen(fetch->query)); check_execute(fetch->handle, rc); /* The attribute is sent to server on execute and asks to open read-only for result set */ mysql_stmt_attr_set(fetch->handle, STMT_ATTR_CURSOR_TYPE, (const void*) &type); rc= mysql_stmt_execute(fetch->handle); check_execute(fetch->handle, rc); /* Find out total number of columns in result set */ metadata= mysql_stmt_result_metadata(fetch->handle); fetch->column_count= mysql_num_fields(metadata); mysql_free_result(metadata); /* Now allocate bind handles and buffers for output data: calloc memory to reduce number of MYSQL_BIND members we need to set up. */ fetch->bind_array= (MYSQL_BIND *) calloc(1, sizeof(MYSQL_BIND) * fetch->column_count); fetch->out_data= (char**) calloc(1, sizeof(char*) * fetch->column_count); fetch->out_data_length= (ulong*) calloc(1, sizeof(ulong) * fetch->column_count); for (i= 0; i < fetch->column_count; ++i) { fetch->out_data[i]= (char*) calloc(1, MAX_COLUMN_LENGTH); fetch->bind_array[i].buffer_type= MYSQL_TYPE_STRING; fetch->bind_array[i].buffer= fetch->out_data[i]; fetch->bind_array[i].buffer_length= MAX_COLUMN_LENGTH; fetch->bind_array[i].length= fetch->out_data_length + i; } mysql_stmt_bind_result(fetch->handle, fetch->bind_array); fetch->row_count= 0; fetch->is_open= TRUE; /* Ready for reading rows */ DBUG_VOID_RETURN; }
int mysql_dumper_dump(struct mysql_login_info *mysql_login_info, const char *outputdir, const char *dbname, const char *tablename, const char *query, size_t query_len, struct mysql_dumper_type *types) { MYSQL mysql; MYSQL_STMT *stmt = NULL; mysql_init(&mysql); my_bool b_flag = 1; if (0 != mysql_options(&mysql, MYSQL_OPT_RECONNECT, (const char *)&b_flag)) return report_error(&mysql); if (NULL == mysql_real_connect(&mysql, mysql_login_info->host, mysql_login_info->user, mysql_login_info->pass, mysql_login_info->db, mysql_login_info->port, NULL, CLIENT_COMPRESS)) return report_error(&mysql); b_flag = 0; if (0 != mysql_options(&mysql, MYSQL_REPORT_DATA_TRUNCATION, (const char *)&b_flag)) return report_error(&mysql); stmt = mysql_stmt_init(&mysql); if (!stmt) return report_error(&mysql); if (0 != mysql_stmt_prepare(stmt, query, query_len)) return report_stmt_error(&mysql, stmt); MYSQL_RES *rs = mysql_stmt_result_metadata(stmt); if (!rs) return report_stmt_error(&mysql, stmt); unsigned int n = mysql_num_fields(rs); MYSQL_FIELD *fields = mysql_fetch_fields(rs); int field_types[n]; MYSQL_BIND bind[n]; my_bool is_null[n]; unsigned long length[n]; my_bool error[n]; memset(bind, 0, sizeof(MYSQL_BIND) * n); int null_terminate_str[n]; memset(null_terminate_str, 0, sizeof(int) * n); struct file_writer ffields[n]; struct file_writer vfields[2][n]; struct vmbuf buf = VMBUF_INITIALIZER; vmbuf_init(&buf, 4096); vmbuf_sprintf(&buf, "%s/%s/%s/schema.txt", outputdir, dbname, tablename); mkdir_for_file_recursive(vmbuf_data(&buf)); int fdschema = creat(vmbuf_data(&buf), 0644); struct vmfile ds_txt = VMFILE_INITIALIZER; vmbuf_reset(&buf); vmbuf_sprintf(&buf, "%s/%s/%s/ds.txt", outputdir, dbname, tablename); if (0 > vmfile_init(&ds_txt, vmbuf_data(&buf), 4096)) return LOGGER_ERROR("failed to create: %s", vmbuf_data(&buf)), vmbuf_free(&buf), -1; vmfile_sprintf(&ds_txt, "DS_LOADER_BEGIN()\n"); vmfile_sprintf(&ds_txt, "/*\n * DB: %s\n */\n", dbname); vmfile_sprintf(&ds_txt, "#undef DB_NAME\n#define DB_NAME %s\n", dbname); ssize_t len = 80 - strlen(tablename); if (len < 0) len = 4; char header[len]; memset(header, '=', len); vmfile_sprintf(&ds_txt, "/* %.*s[ %s ]%.*s */\n", (int)len / 2, header, tablename, (int)(len - (len / 2)), header); vmfile_sprintf(&ds_txt, "# undef TABLE_NAME\n# define TABLE_NAME %s\n", tablename); /* * initialize output files */ unsigned int i; for (i = 0; i < n; ++i) { file_writer_make(&ffields[i]); file_writer_make(&vfields[0][i]); file_writer_make(&vfields[1][i]); } struct hashtable ht_types = HASHTABLE_INITIALIZER; hashtable_init(&ht_types, 32); if (NULL != types) { struct mysql_dumper_type *t = types; for (; t->name; ++t) { /* storing ptr here which points to static str */ hashtable_insert(&ht_types, t->name, strlen(t->name), t, sizeof(struct mysql_dumper_type)); } } /* * parse meta data and construct bind array */ int err = 0; for (i = 0; i < n; ++i) { field_types[i] = fields[i].type; bind[i].is_unsigned = IS_UNSIGNED(fields[i].flags); int64_t ds_type = -1; const char *ds_type_str = "VAR"; /* * handle overrides */ while (NULL != types) { uint32_t ofs = hashtable_lookup(&ht_types, fields[i].name, strlen(fields[i].name)); if (!ofs) break; struct mysql_dumper_type *type = (struct mysql_dumper_type *)hashtable_get_val(&ht_types, ofs); null_terminate_str[i] = MYSQL_DUMPER_CSTR & type->flags; if (type->mysql_type) field_types[i] = type->mysql_type; bind[i].is_unsigned = (type->flags & MYSQL_DUMPER_UNSIGNED) > 0 ? 1 : 0; break; } vmbuf_reset(&buf); vmbuf_sprintf(&buf, "%s/%s/%s/%s", outputdir, dbname, tablename, fields[i].name); mkdir_for_file_recursive(vmbuf_data(&buf)); if (is_var_length_field(field_types[i])) { size_t ofs = vmbuf_wlocpos(&buf); vmbuf_sprintf(&buf, ".ofs"); if (0 > (err = file_writer_init(&vfields[0][i], vmbuf_data(&buf)))) break; vmbuf_wlocset(&buf, ofs); vmbuf_sprintf(&buf, ".dat"); if (0 > (err = file_writer_init(&vfields[1][i], vmbuf_data(&buf)))) break; } else { ds_type = get_ds_type(field_types[i], bind[i].is_unsigned); const char *s = get_ds_type_str(ds_type); if (*s) ds_type_str = s; if (0 > (err = file_writer_init(&ffields[i], vmbuf_data(&buf))) || 0 > (err = file_writer_write(&ffields[i], &ds_type, sizeof(ds_type)))) break;; } len = ribs_mysql_get_storage_size(field_types[i], fields[i].length); if (fdschema > 0) dprintf(fdschema, "%03d name = %s, size=%zu, length=%lu, type=%s (%s), is_prikey=%d, ds_type=%s\n", i, fields[i].name, len, fields[i].length, ribs_mysql_get_type_name(field_types[i]), bind[i].is_unsigned ? "unsigned" : "signed", IS_PRI_KEY(fields[i].flags), ds_type_str); if (is_var_length_field(field_types[i])) { vmfile_sprintf(&ds_txt, " DS_VAR_FIELD_LOADER(%s)\n", fields[i].name); } else { vmfile_sprintf(&ds_txt, " DS_FIELD_LOADER(%s, %s)\n", ds_type_str, fields[i].name); } bind[i].buffer_type = field_types[i]; bind[i].buffer_length = len; bind[i].buffer = malloc(len); bind[i].is_null = &is_null[i]; bind[i].length = &length[i]; bind[i].error = &error[i]; } hashtable_free(&ht_types); mysql_free_result(rs); close(fdschema); //vmfile_sprintf(&ds_txt, "/*\n * TABLE END: %s\n */\n", tablename); vmfile_sprintf(&ds_txt, "DS_LOADER_END()\n"); vmfile_close(&ds_txt); /* * execute & bind */ if (0 != err || 0 != mysql_stmt_execute(stmt) || 0 != mysql_stmt_bind_result(stmt, bind)) { err = -1; report_stmt_error(&mysql, stmt); goto dumper_close_writer; } char zeros[4096]; memset(zeros, 0, sizeof(zeros)); int mysql_err = 0; size_t count = 0, num_rows_errors = 0; /* * write all rows to output files */ while (0 == (mysql_err = mysql_stmt_fetch(stmt))) { int b = 0; for (i = 0; i < n && !b; ++i) b = b || error[i]; if (b) { ++num_rows_errors; continue; } for (i = 0; i < n; ++i) { if (is_var_length_field(field_types[i])) { size_t ofs = file_writer_wlocpos(&vfields[1][i]); if (0 > (err = file_writer_write(&vfields[0][i], &ofs, sizeof(ofs))) || 0 > (err = file_writer_write(&vfields[1][i], is_null[i] ? NULL : bind[i].buffer, is_null[i] ? 0 : length[i]))) goto dumper_error; if (null_terminate_str[i]) { const char c = '\0'; if (0 > (err = file_writer_write(&vfields[1][i], &c, sizeof(c)))) goto dumper_error; } } else { if (0 > (err = file_writer_write(&ffields[i], is_null[i] ? zeros : bind[i].buffer, bind[i].buffer_length))) goto dumper_error; } } ++count; } /* no dumper errors */ goto dumper_ok; dumper_error: LOGGER_ERROR("failed to write data, aborting"); dumper_ok: /* we are done with mysql, close it */ mysql_stmt_close(stmt); mysql_close(&mysql); LOGGER_INFO("%s: %zu records, %zu skipped", tablename, count, num_rows_errors); /* check for mysql errors */ if (mysql_err != MYSQL_NO_DATA) { LOGGER_ERROR("mysql_stmt_fetch returned an error (code=%d)\n", mysql_err); err = -1; } dumper_close_writer: /* * finalize & free memory */ for (i = 0; i < n; ++i) { if (is_var_length_field(field_types[i])) { size_t ofs = file_writer_wlocpos(&vfields[1][i]); if (0 > (err = file_writer_write(&vfields[0][i], &ofs, sizeof(ofs)))) LOGGER_ERROR("failed to write offset"); file_writer_close(&vfields[0][i]); file_writer_close(&vfields[1][i]); } else { file_writer_close(&ffields[i]); } free(bind[i].buffer); } vmbuf_free(&buf); return err; }
static DWORD UserSyncIncrUpdates(DB_CONTEXT *db, SYNC_CONTEXT *sync) { CHAR *query; CHAR userName[_MAX_NAME + 1]; DWORD error; INT result; USERFILE userFile; MYSQL_BIND bindInput[2]; MYSQL_BIND bindOutput[17]; MYSQL_RES *metadata; MYSQL_STMT *stmt; ASSERT(db != NULL); ASSERT(sync != NULL); // // Prepare statement and bind parameters // stmt = db->stmt[7]; query = "SELECT name,description,flags,home,limits,password,vfsfile,credits," " ratio,alldn,allup,daydn,dayup,monthdn,monthup,wkdn,wkup" " FROM io_user" " WHERE updated BETWEEN ? AND ?"; result = mysql_stmt_prepare(stmt, query, strlen(query)); if (result != 0) { LOG_WARN("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } DB_CHECK_PARAMS(bindInput, stmt); ZeroMemory(&bindInput, sizeof(bindInput)); bindInput[0].buffer_type = MYSQL_TYPE_LONG; bindInput[0].buffer = &sync->prevUpdate; bindInput[0].is_unsigned = TRUE; bindInput[1].buffer_type = MYSQL_TYPE_LONG; bindInput[1].buffer = &sync->currUpdate; bindInput[1].is_unsigned = TRUE; result = mysql_stmt_bind_param(stmt, bindInput); if (result != 0) { LOG_WARN("Unable to bind parameters: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { LOG_WARN("Unable to retrieve result metadata: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Execute prepared statement // result = mysql_stmt_execute(stmt); if (result != 0) { LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Bind and fetch results // DB_CHECK_RESULTS(bindOutput, metadata); ZeroMemory(&bindOutput, sizeof(bindOutput)); bindOutput[0].buffer_type = MYSQL_TYPE_STRING; bindOutput[0].buffer = userName; bindOutput[0].buffer_length = sizeof(userName); bindOutput[1].buffer_type = MYSQL_TYPE_STRING; bindOutput[1].buffer = userFile.Tagline; bindOutput[1].buffer_length = sizeof(userFile.Tagline); bindOutput[2].buffer_type = MYSQL_TYPE_STRING; bindOutput[2].buffer = userFile.Flags; bindOutput[2].buffer_length = sizeof(userFile.Flags); bindOutput[3].buffer_type = MYSQL_TYPE_STRING; bindOutput[3].buffer = userFile.Home; bindOutput[3].buffer_length = sizeof(userFile.Home); bindOutput[4].buffer_type = MYSQL_TYPE_BLOB; bindOutput[4].buffer = &userFile.Limits; bindOutput[4].buffer_length = sizeof(userFile.Limits); bindOutput[5].buffer_type = MYSQL_TYPE_BLOB; bindOutput[5].buffer = &userFile.Password; bindOutput[5].buffer_length = sizeof(userFile.Password); bindOutput[6].buffer_type = MYSQL_TYPE_STRING; bindOutput[6].buffer = userFile.MountFile; bindOutput[6].buffer_length = sizeof(userFile.MountFile); bindOutput[7].buffer_type = MYSQL_TYPE_BLOB; bindOutput[7].buffer = &userFile.Ratio; bindOutput[7].buffer_length = sizeof(userFile.Ratio); bindOutput[8].buffer_type = MYSQL_TYPE_BLOB; bindOutput[8].buffer = &userFile.Credits; bindOutput[8].buffer_length = sizeof(userFile.Credits); bindOutput[9].buffer_type = MYSQL_TYPE_BLOB; bindOutput[9].buffer = &userFile.DayUp; bindOutput[9].buffer_length = sizeof(userFile.DayUp); bindOutput[10].buffer_type = MYSQL_TYPE_BLOB; bindOutput[10].buffer = &userFile.DayDn; bindOutput[10].buffer_length = sizeof(userFile.DayDn); bindOutput[11].buffer_type = MYSQL_TYPE_BLOB; bindOutput[11].buffer = &userFile.WkUp; bindOutput[11].buffer_length = sizeof(userFile.WkUp); bindOutput[12].buffer_type = MYSQL_TYPE_BLOB; bindOutput[12].buffer = &userFile.WkDn; bindOutput[12].buffer_length = sizeof(userFile.WkDn); bindOutput[13].buffer_type = MYSQL_TYPE_BLOB; bindOutput[13].buffer = &userFile.MonthUp; bindOutput[13].buffer_length = sizeof(userFile.MonthUp); bindOutput[14].buffer_type = MYSQL_TYPE_BLOB; bindOutput[14].buffer = &userFile.MonthDn; bindOutput[14].buffer_length = sizeof(userFile.MonthDn); bindOutput[15].buffer_type = MYSQL_TYPE_BLOB; bindOutput[15].buffer = &userFile.AllUp; bindOutput[15].buffer_length = sizeof(userFile.AllUp); bindOutput[16].buffer_type = MYSQL_TYPE_BLOB; bindOutput[16].buffer = &userFile.AllDn; bindOutput[16].buffer_length = sizeof(userFile.AllDn); result = mysql_stmt_bind_result(stmt, bindOutput); if (result != 0) { LOG_WARN("Unable to bind results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_store_result(stmt); if (result != 0) { LOG_WARN("Unable to buffer results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Process result set // for (;;) { ZeroMemory(&userFile, sizeof(USERFILE)); if (mysql_stmt_fetch(stmt) != 0) { break; } TRACE("UserSyncIncr: Update(%s)", userName); // Read the user's admin-groups, groups, and hosts error = DbUserReadExtra(db, userName, &userFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to read user \"%s\" (error %lu).", userName, error); } else { // Update user file error = UserEventUpdate(userName, &userFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to update user \"%s\" (error %lu).", userName, error); } } } mysql_free_result(metadata); return ERROR_SUCCESS; }
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, 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; }
static SLVAL sl_mysql_stmt_execute(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv) { mysql_stmt_t* stmt = get_mysql_stmt(vm, self); size_t req = mysql_stmt_param_count(stmt->stmt); if(argc < req) { char buff[100]; sprintf(buff, "Prepared statement has %lu parameter markers, but only %lu parameters were given", req, argc); sl_throw_message2(vm, vm->lib.ArgumentError, buff); } if(!stmt->bind) { stmt->bind = sl_alloc(vm->arena, sizeof(MYSQL_BIND) * req); } for(size_t i = 0; i < req; i++) { stmt->bind[i].buffer_type = MYSQL_TYPE_STRING; sl_string_t* str = sl_get_string(vm, sl_to_s(vm, argv[i])); stmt->bind[i].buffer = str->buff; stmt->bind[i].buffer_length = str->buff_len; stmt->bind[i].length = NULL; stmt->bind[i].is_null = NULL; stmt->bind[i].is_unsigned = 1; stmt->bind[i].error = NULL; } if(mysql_stmt_bind_param(stmt->stmt, stmt->bind)) { sl_mysql_stmt_check_error(vm, stmt->stmt); } if(mysql_stmt_execute(stmt->stmt)) { sl_mysql_stmt_check_error(vm, stmt->stmt); } MYSQL_RES* res = mysql_stmt_result_metadata(stmt->stmt); if(!res) { /* query did not produce a result set */ return sl_make_int(vm, mysql_stmt_affected_rows(stmt->stmt)); } int field_count = mysql_stmt_field_count(stmt->stmt); MYSQL_FIELD* field; SLVAL field_names[field_count]; enum enum_field_types field_types[field_count]; size_t field_i = 0; while((field = mysql_fetch_field(res))) { field_names[field_i] = sl_make_cstring(vm, field->name); if(field->type == MYSQL_TYPE_LONG || field->type == MYSQL_TYPE_SHORT || field->type == MYSQL_TYPE_TINY) { field_types[field_i] = MYSQL_TYPE_LONG; } else { field_types[field_i] = MYSQL_TYPE_STRING; } field_i++; } MYSQL_BIND output_binds[field_count]; my_bool output_errors[field_count]; my_bool output_is_nulls[field_count]; unsigned long output_lengths[field_count]; for(int i = 0; i < field_count; i++) { output_binds[i].buffer_type = MYSQL_TYPE_STRING; output_binds[i].buffer = NULL; output_binds[i].buffer_length = 0; output_binds[i].length = &output_lengths[i]; output_binds[i].is_null = &output_is_nulls[i]; output_binds[i].error = &output_errors[i]; } if(mysql_stmt_bind_result(stmt->stmt, output_binds)) { sl_mysql_stmt_check_error(vm, stmt->stmt); } SLVAL result_rows = sl_make_array(vm, 0, NULL); while(1) { int code = mysql_stmt_fetch(stmt->stmt); if(code == MYSQL_NO_DATA) { break; } if(code == 1) { sl_mysql_stmt_check_error(vm, stmt->stmt); } SLVAL row = sl_make_dict(vm, 0, NULL); for(int i = 0; i < field_count; i++) { MYSQL_BIND cell; cell.length = &output_lengths[i]; cell.is_null = &output_is_nulls[i]; cell.error = &output_errors[i]; cell.buffer_type = field_types[i]; int buffer_long; switch(field_types[i]) { case MYSQL_TYPE_LONG: cell.buffer = &buffer_long; cell.buffer_length = sizeof(buffer_long); break; default: /* MYSQL_TYPE_STRING */ cell.buffer = sl_alloc_buffer(vm->arena, output_lengths[i] + 1); cell.buffer_length = output_lengths[i]; break; } if(mysql_stmt_fetch_column(stmt->stmt, &cell, i, 0)) { sl_mysql_stmt_check_error(vm, stmt->stmt); } switch(field_types[i]) { case MYSQL_TYPE_LONG: sl_dict_set(vm, row, field_names[i], sl_make_int(vm, buffer_long)); break; default: /* MYSQL_TYPE_STRING */ sl_dict_set(vm, row, field_names[i], sl_make_string(vm, cell.buffer, output_lengths[i])); break; } } sl_array_push(vm, result_rows, 1, &row); } return result_rows; }
void mysql_stmt_resultset::get_results() { if (stmt_ == NULL || bindings_ != NULL || status_ != -1) return; if ((status_ = mysql_stmt_execute(stmt_))) { throw database_exception(last_stmt_error(stmt_)); } metadata_ = mysql_stmt_result_metadata(stmt_); if (metadata_ == NULL) throw database_exception("No result data found."); columnCount_ = mysql_num_fields(metadata_); bindings_ = (MYSQL_BIND *) calloc(columnCount_, sizeof(MYSQL_BIND)); auto fields = mysql_fetch_fields(metadata_); for (auto i = 0; i < columnCount_; i++) { switch (fields[i].type) { case MYSQL_TYPE_INT24: bindings_[i].buffer_type = MYSQL_TYPE_LONGLONG; break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: bindings_[i].buffer_type = MYSQL_TYPE_DOUBLE; break; case MYSQL_TYPE_BIT: bindings_[i].buffer_type = MYSQL_TYPE_TINY; break; case MYSQL_TYPE_YEAR: break; case MYSQL_TYPE_VAR_STRING: bindings_[i].buffer_type = MYSQL_TYPE_STRING; break; case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: case MYSQL_TYPE_GEOMETRY: break; default: bindings_[i].buffer_type = fields[i].type; break; } bindings_[i].is_null = (my_bool *) calloc(1, sizeof(my_bool)); bindings_[i].is_unsigned = 0; bindings_[i].error = 0; bindings_[i].buffer_length = fields[i].length; bindings_[i].length = (size_t *) calloc(1, sizeof(size_t)); bindings_[i].buffer = calloc(1, fields[i].length); } if (mysql_stmt_bind_result(stmt_, bindings_) != 0) { throw database_exception(last_stmt_error(stmt_)); } }
static DWORD GroupSyncFull(DB_CONTEXT *db) { CHAR *query; CHAR groupName[_MAX_NAME + 1]; DWORD error; DWORD i; GROUPFILE groupFile; INT result; NAME_ENTRY *entry; NAME_LIST list; MYSQL_BIND bind[5]; MYSQL_RES *metadata; MYSQL_STMT *stmt; ASSERT(db != NULL); TRACE("db=%p", db); // // Build list of group IDs // error = NameListCreateGroups(&list); if (error != ERROR_SUCCESS) { LOG_ERROR("Unable to create group ID list (error %lu).", error); return error; } // // Prepare and execute statement // stmt = db->stmt[7]; query = "SELECT name, description, slots, users, vfsfile" " FROM io_group"; result = mysql_stmt_prepare(stmt, query, strlen(query)); if (result != 0) { TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_execute(stmt); if (result != 0) { LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Bind and fetch results // DB_CHECK_RESULTS(bind, metadata); ZeroMemory(&bind, sizeof(bind)); bind[0].buffer_type = MYSQL_TYPE_STRING; bind[0].buffer = groupName; bind[0].buffer_length = sizeof(groupName); bind[1].buffer_type = MYSQL_TYPE_STRING; bind[1].buffer = groupFile.szDescription; bind[1].buffer_length = sizeof(groupFile.szDescription); bind[2].buffer_type = MYSQL_TYPE_BLOB; bind[2].buffer = groupFile.Slots; bind[2].buffer_length = sizeof(groupFile.Slots); bind[3].buffer_type = MYSQL_TYPE_LONG; bind[3].buffer = &groupFile.Users; bind[4].buffer_type = MYSQL_TYPE_STRING; bind[4].buffer = groupFile.szVfsFile; bind[4].buffer_length = sizeof(groupFile.szVfsFile); result = mysql_stmt_bind_result(stmt, bind); if (result != 0) { TRACE("Unable to bind results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_store_result(stmt); if (result != 0) { TRACE("Unable to buffer results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Process result set // for (;;) { ZeroMemory(&groupFile, sizeof(GROUPFILE)); if (mysql_stmt_fetch(stmt) != 0) { break; } // // If ioFTPD fails to open a group at start-up, the group will still // have an entry in the GroupIdTable file but ioFTPD considers them // gone. The call to GroupExists() is done to check for this. // if (!NameListRemove(&list, groupName) || !GroupExists(groupName)) { TRACE("GroupSyncFull: Create(%s)", groupName); // Group does not exist locally, create it. error = GroupEventCreate(groupName, &groupFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to create group \"%s\" (error %lu).", groupName, error); } } else { TRACE("GroupSyncFull: Update(%s)", groupName); // Group already exists locally, update it. error = GroupEventUpdate(groupName, &groupFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to update group \"%s\" (error %lu).", groupName, error); } } } mysql_free_result(metadata); // // Delete remaining groups // for (i = 0; i < list.count; i++) { entry = list.array[i]; TRACE("GroupSyncFull: Delete(%s,%d)", entry->name, entry->id); // Group does not exist on database, delete it. error = GroupEventDeleteEx(entry->name, entry->id); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to delete group \"%s\" (error %lu).", entry->name, error); } } NameListDestroy(&list); return ERROR_SUCCESS; }
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("[ERROR]: PreparedStatement (id: %u, database: `%s`) error binding params: [%u] %s", index, m_connectionInfo.database.c_str(), 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("[ERROR]: PreparedStatement (id: %u, database: `%s`) error executing: [%u] %s", index, m_connectionInfo.database.c_str(), 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] Prepared SQL: %u on database `%s`", getMSTimeDiff(_s, getMSTime()), index, m_connectionInfo.database.c_str()); 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; } }
static DWORD GroupSyncIncrUpdates(DB_CONTEXT *db, SYNC_CONTEXT *sync) { CHAR *query; CHAR groupName[_MAX_NAME + 1]; DWORD error; GROUPFILE groupFile; INT result; MYSQL_BIND bindInput[2]; MYSQL_BIND bindOutput[5]; MYSQL_RES *metadata; MYSQL_STMT *stmt; ASSERT(db != NULL); ASSERT(sync != NULL); // // Prepare statement and bind parameters // stmt = db->stmt[7]; query = "SELECT name, description, slots, users, vfsfile" " FROM io_group" " WHERE updated BETWEEN ? AND ?"; result = mysql_stmt_prepare(stmt, query, strlen(query)); if (result != 0) { TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } DB_CHECK_PARAMS(bindInput, stmt); ZeroMemory(&bindInput, sizeof(bindInput)); bindInput[0].buffer_type = MYSQL_TYPE_LONG; bindInput[0].buffer = &sync->prevUpdate; bindInput[0].is_unsigned = TRUE; bindInput[1].buffer_type = MYSQL_TYPE_LONG; bindInput[1].buffer = &sync->currUpdate; bindInput[1].is_unsigned = TRUE; result = mysql_stmt_bind_param(stmt, bindInput); if (result != 0) { TRACE("Unable to bind parameters: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { TRACE("Unable to prepare statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Execute prepared statement // result = mysql_stmt_execute(stmt); if (result != 0) { LOG_ERROR("Unable to execute statement: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Bind and fetch results // DB_CHECK_RESULTS(bindOutput, metadata); ZeroMemory(&bindOutput, sizeof(bindOutput)); bindOutput[0].buffer_type = MYSQL_TYPE_STRING; bindOutput[0].buffer = groupName; bindOutput[0].buffer_length = sizeof(groupName); bindOutput[1].buffer_type = MYSQL_TYPE_STRING; bindOutput[1].buffer = groupFile.szDescription; bindOutput[1].buffer_length = sizeof(groupFile.szDescription); bindOutput[2].buffer_type = MYSQL_TYPE_BLOB; bindOutput[2].buffer = groupFile.Slots; bindOutput[2].buffer_length = sizeof(groupFile.Slots); bindOutput[3].buffer_type = MYSQL_TYPE_LONG; bindOutput[3].buffer = &groupFile.Users; bindOutput[4].buffer_type = MYSQL_TYPE_STRING; bindOutput[4].buffer = groupFile.szVfsFile; bindOutput[4].buffer_length = sizeof(groupFile.szVfsFile); result = mysql_stmt_bind_result(stmt, bindOutput); if (result != 0) { TRACE("Unable to bind results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } result = mysql_stmt_store_result(stmt); if (result != 0) { TRACE("Unable to buffer results: %s", mysql_stmt_error(stmt)); return DbMapErrorFromStmt(stmt); } // // Process result set // for (;;) { ZeroMemory(&groupFile, sizeof(GROUPFILE)); if (mysql_stmt_fetch(stmt) != 0) { break; } TRACE("GroupSyncIncr: Update(%s)", groupName); error = GroupEventUpdate(groupName, &groupFile); if (error != ERROR_SUCCESS) { LOG_WARN("Unable to update group \"%s\" (error %lu).", groupName, error); } } mysql_free_result(metadata); return ERROR_SUCCESS; }
void Statement::Prepare() { if (! _db.IsConnected()) { throw DatabaseException("Error in Statement::Prepare", 0, "----", "Database is not connected"); } _numberAffectedRows = 0; if ((_stmt = mysql_stmt_init(_db._db)) == NULL) { throw DatabaseException(_db._db, "Error in Statement::Prepare during initialize"); } if (mysql_stmt_prepare(_stmt, _sqlStatement.c_str(), _sqlStatement.length()) != 0) { mysql_stmt_close(_stmt); throw DatabaseException(_stmt, "Error in Statement::Prepare during prepare"); } _bind = NULL; unsigned long parameterCount = ParameterCount(); if (parameterCount > 0) { _bind = (MYSQL_BIND *) malloc(sizeof(MYSQL_BIND) * parameterCount); memset(_bind, 0, sizeof(MYSQL_BIND) * parameterCount); } _numberResultColumns = 0; _hasBlobField = false; MYSQL_RES *metaData; if ((metaData = mysql_stmt_result_metadata(_stmt)) == NULL) { return; } _resultBind = NULL; _numberResultColumns = mysql_num_fields(metaData); if (_numberResultColumns > 0) { _resultBind = (MYSQL_BIND *) malloc(sizeof(MYSQL_BIND) * _numberResultColumns); memset(_resultBind, 0, sizeof(MYSQL_BIND) * _numberResultColumns); } int fieldPos = 0; MYSQL_FIELD *field; while ((field = mysql_fetch_field(metaData)) != NULL) { ParamBuffer *buffer = NULL; if ((field->type == MYSQL_TYPE_VAR_STRING) || (field->type == MYSQL_TYPE_STRING) || (field->type == MYSQL_TYPE_DECIMAL) || (field->type == MYSQL_TYPE_BIT) || (field->type == MYSQL_TYPE_VARCHAR)) { std::string str; buffer = new ParamBuffer(str, field->length); _resultBind[fieldPos].buffer_type = field->type; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); } else if (field->type == MYSQL_TYPE_TINY) { if ((field->flags & UNSIGNED_FLAG) != 0) { buffer = new ParamBuffer((const unsigned char) 0); } else { buffer = new ParamBuffer((const char) 0); } _resultBind[fieldPos].buffer_type = MYSQL_TYPE_TINY; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); _resultBind[fieldPos].is_unsigned = buffer->IsUnsigned(); } else if ((field->type == MYSQL_TYPE_SHORT) || (field->type == MYSQL_TYPE_YEAR)) { if ((field->flags & UNSIGNED_FLAG) != 0) { buffer = new ParamBuffer((const unsigned short int) 0); } else { buffer = new ParamBuffer((const short int) 0); } _resultBind[fieldPos].buffer_type = MYSQL_TYPE_SHORT; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); _resultBind[fieldPos].is_unsigned = buffer->IsUnsigned(); } else if ((field->type == MYSQL_TYPE_LONG) || (field->type == MYSQL_TYPE_INT24)) { if ((field->flags & UNSIGNED_FLAG) != 0) { buffer = new ParamBuffer((const unsigned int) 0); } else { buffer = new ParamBuffer((const int) 0); } _resultBind[fieldPos].buffer_type = field->type; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); _resultBind[fieldPos].is_unsigned = buffer->IsUnsigned(); } else if (field->type == MYSQL_TYPE_FLOAT) { _resultBind[fieldPos].buffer_type = field->type; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); _resultBind[fieldPos].is_unsigned = buffer->IsUnsigned(); } else if (field->type == MYSQL_TYPE_DOUBLE) { _resultBind[fieldPos].buffer_type = field->type; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); _resultBind[fieldPos].is_unsigned = buffer->IsUnsigned(); } else if ((field->type == MYSQL_TYPE_TIMESTAMP) || (field->type == MYSQL_TYPE_DATE) || (field->type == MYSQL_TYPE_TIME) || (field->type == MYSQL_TYPE_DATETIME)) { Julian time; buffer = new ParamBuffer(time); _resultBind[fieldPos].buffer_type = field->type; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); } else if ((field->type == MYSQL_TYPE_BLOB) || (field->type == MYSQL_TYPE_TINY_BLOB) || (field->type == MYSQL_TYPE_MEDIUM_BLOB) || (field->type == MYSQL_TYPE_LONG_BLOB)) { _hasBlobField = true; Binary data(field->length); buffer = new ParamBuffer(data); _resultBind[fieldPos].buffer_type = field->type; _resultBind[fieldPos].buffer = buffer->Buffer(); _resultBind[fieldPos].buffer_length = buffer->BufferSize(); _resultBind[fieldPos].length = buffer->BufferLength(); _resultBind[fieldPos].is_null = buffer->IsNull(); _resultBind[fieldPos].error = buffer->Error(); } if (buffer != NULL) { _resultParams.push_back(buffer); } fieldPos++; } if (_resultParams.size() != _numberResultColumns) { mysql_free_result(metaData); mysql_stmt_close(_stmt); throw DatabaseException("Error in Statement::Prepare", 0, "----", "was not able to bind all parameters"); } if (_hasBlobField) { my_bool setMax = 1; mysql_stmt_attr_set(_stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &setMax); } if (_numberResultColumns > 0) { if (mysql_stmt_bind_result(_stmt, _resultBind) != 0) { mysql_free_result(metaData); mysql_stmt_close(_stmt); throw DatabaseException(_stmt, "Error in Statement::Prepare while binding results"); } } mysql_free_result(metaData); }