mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=3736
This commit is contained in:
parent
64c86f7cb6
commit
fccf8d83ab
159
db/boinc_db.C
159
db/boinc_db.C
|
@ -59,7 +59,7 @@ DB_HOST::DB_HOST() : DB_BASE(boinc_db, "host"){}
|
|||
DB_WORKUNIT::DB_WORKUNIT() : DB_BASE(boinc_db, "workunit"){}
|
||||
DB_RESULT::DB_RESULT() : DB_BASE(boinc_db, "result"){}
|
||||
DB_MSG_FROM_HOST::DB_MSG_FROM_HOST() : DB_BASE(boinc_db, "msg_from_host"){}
|
||||
DB_TRANSITIONER_QUEUE::DB_TRANSITIONER_QUEUE() : DB_BASE(boinc_db), current_entry_start_position(0), current_entry_workunit_id(0){}
|
||||
DB_TRANSITIONER_ITEM_SET::DB_TRANSITIONER_ITEM_SET() : DB_BASE_SPECIAL(boinc_db){}
|
||||
|
||||
int DB_PLATFORM::get_id() {return id;}
|
||||
int DB_CORE_VERSION::get_id() {return id;}
|
||||
|
@ -571,23 +571,29 @@ void DB_MSG_TO_HOST::db_parse(MYSQL_ROW& r) {
|
|||
strcpy2(xml, r[i++]);
|
||||
}
|
||||
|
||||
int DB_TRANSITIONER_QUEUE::enumerate_queue_entries(int transition_time, int ntotal_transitioners, int ntransitioner, int nresult_limit) {
|
||||
int DB_TRANSITIONER_ITEM_SET::enumerate(
|
||||
int transition_time, int ntotal_transitioners, int ntransitioner,
|
||||
int nresult_limit,
|
||||
std::vector<TRANSITIONER_ITEM>& items
|
||||
) {
|
||||
int x;
|
||||
char query[MAX_QUERY_LEN];
|
||||
char priority[16];
|
||||
char mod[64];
|
||||
char priority[256];
|
||||
char mod[256];
|
||||
MYSQL_ROW row;
|
||||
int temp_workunit_id;
|
||||
MYSQL_ROW_OFFSET temp_entry_position;
|
||||
TRANSITIONER_ITEM new_item;
|
||||
|
||||
if (!cursor.active) {
|
||||
cursor.active = true;
|
||||
|
||||
memset(priority, '\0', sizeof(priority));
|
||||
if (db->mysql) { strcpy(priority, "HIGH_PRIORITY"); }
|
||||
strcpy(priority, "");
|
||||
if (db->mysql) strcpy(priority, "HIGH_PRIORITY");
|
||||
|
||||
memset(mod, '\0', sizeof(mod));
|
||||
if (0 < ntotal_transitioners) { sprintf(mod, "MOD(wu.id, %d) = %d", ntotal_transitioners, ntransitioner); }
|
||||
strcpy(mod, "");
|
||||
if (ntotal_transitioners > 1) {
|
||||
sprintf(mod, "MOD(wu.id, %d) = %d",
|
||||
ntotal_transitioners, ntransitioner
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(query,
|
||||
"SELECT %s "
|
||||
|
@ -625,104 +631,63 @@ int DB_TRANSITIONER_QUEUE::enumerate_queue_entries(int transition_time, int ntot
|
|||
|
||||
x = db->do_query(query);
|
||||
if (x) return mysql_errno(db->mysql);
|
||||
|
||||
// the following stores the entire result set in memory
|
||||
cursor.rp = mysql_store_result(db->mysql);
|
||||
if (!cursor.rp) return mysql_errno(db->mysql);
|
||||
cursor.active = true;
|
||||
//nrows = mysql_num_rows(cursor.rp);
|
||||
//current_row = 0;
|
||||
|
||||
current_entry_start_position = mysql_row_tell(cursor.rp);
|
||||
}
|
||||
|
||||
mysql_row_seek(current_entry_start_position);
|
||||
|
||||
do
|
||||
{
|
||||
temp_entry_position = mysql_row_tell(cursor.rp);
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
mysql_free_result(cursor.rp);
|
||||
cursor.active = false;
|
||||
return -1;
|
||||
} else {
|
||||
fetch_field_value(cursor.rp, row, "id", temp_workunit_id);
|
||||
}
|
||||
last_item.parse(row);
|
||||
}
|
||||
while ( row && ( temp_workunit_id == current_entry_workunit_id ));
|
||||
|
||||
// New Workunit Detected
|
||||
current_entry_workunit_id = temp_workunit_id;
|
||||
current_entry_start_position = temp_entry_position;
|
||||
items.clear();
|
||||
while (true) {
|
||||
items.push_back(last_item);
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
cursor.active = false;
|
||||
return -1;
|
||||
}
|
||||
new_item.parse(row);
|
||||
if (new_item.id != last_item.id) {
|
||||
last_item = new_item;
|
||||
return 0;
|
||||
}
|
||||
last_item = new_item;
|
||||
}
|
||||
|
||||
parse_entry(cursor.rp, row);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DB_TRANSITIONER_QUEUE::parse_entry(MYSQL_RES *result, MYSQL_ROW& row) {
|
||||
int temp_need_validate = 0;
|
||||
fetch_field_value(result, row, "id", id);
|
||||
fetch_field_value(result, row, "name", name, sizeof(name));
|
||||
fetch_field_value(result, row, "appid", appid);
|
||||
fetch_field_value(result, row, "min_quorum", min_quorum);
|
||||
fetch_field_value(result, row, "need_validate", temp_need_validate);
|
||||
if (temp_need_validate) { need_validate = true; } else { need_validate = false; }
|
||||
fetch_field_value(result, row, "canonical_resultid", canonical_resultid);
|
||||
fetch_field_value(result, row, "transition_time", transition_time);
|
||||
fetch_field_value(result, row, "delay_bound", delay_bound);
|
||||
fetch_field_value(result, row, "error_mask", error_mask);
|
||||
fetch_field_value(result, row, "max_error_results", max_error_results);
|
||||
fetch_field_value(result, row, "max_total_results", max_total_results);
|
||||
fetch_field_value(result, row, "file_delete_state", file_delete_state);
|
||||
fetch_field_value(result, row, "assimilate_state", assimilate_state);
|
||||
fetch_field_value(result, row, "target_nresults", target_nresults);
|
||||
fetch_field_value(result, row, "result_template_file", result_template_file, sizeof(result_template_file));
|
||||
parse_result(result, row);
|
||||
void TRANSITIONER_ITEM::parse(MYSQL_ROW& r) {
|
||||
int i=0;
|
||||
memset(this, 0, sizeof(TRANSITIONER_ITEM));
|
||||
id = atoi(r[i++]);
|
||||
strcpy2(name, r[i++]);
|
||||
appid = atoi(r[i++]);
|
||||
min_quorum = atoi(r[i++]);
|
||||
canonical_resultid = atoi(r[i++]);
|
||||
transition_time = atoi(r[i++]);
|
||||
delay_bound = atoi(r[i++]);
|
||||
error_mask = atoi(r[i++]);
|
||||
max_error_results = atoi(r[i++]);
|
||||
max_total_results = atoi(r[i++]);
|
||||
file_delete_state = atoi(r[i++]);
|
||||
assimilate_state = atoi(r[i++]);
|
||||
target_nresults = atoi(r[i++]);
|
||||
strcpy2(result_template_file, r[i++]);
|
||||
res_id = atoi(r[i++]);
|
||||
res_report_deadline = atoi(r[i++]);
|
||||
res_server_state = atoi(r[i++]);
|
||||
res_outcome = atoi(r[i++]);
|
||||
res_validate_state = atoi(r[i++]);
|
||||
res_file_delete_state = atoi(r[i++]);
|
||||
res_sent_time = atoi(r[i++]);
|
||||
}
|
||||
|
||||
void DB_TRANSITIONER_QUEUE::parse_result(MYSQL_RES *result, MYSQL_ROW& row) {
|
||||
fetch_field_value(result, row, "res_id", res_id);
|
||||
fetch_field_value(result, row, "res_report_deadline", res_report_deadline);
|
||||
fetch_field_value(result, row, "res_server_state", res_server_state);
|
||||
fetch_field_value(result, row, "res_outcome", res_outcome);
|
||||
fetch_field_value(result, row, "res_validate_state", res_validate_state);
|
||||
fetch_field_value(result, row, "res_file_delete_state", res_file_delete_state);
|
||||
fetch_field_value(result, row, "res_sent_time", res_sent_time);
|
||||
}
|
||||
|
||||
int DB_TRANSITIONER_QUEUE::seek_first_result() {
|
||||
int retval;
|
||||
MYSQL_ROW row;
|
||||
|
||||
mysql_row_seek(current_entry_start_position);
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
retval = -1;
|
||||
} else {
|
||||
parse_result(cursor.rp, row);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int DB_TRANSITIONER_QUEUE::seek_next_result() {
|
||||
int retval;
|
||||
int temp_workunit_id;
|
||||
MYSQL_ROW row;
|
||||
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
seek_first_result();
|
||||
retval = -1;
|
||||
} else {
|
||||
fetch_field_value(result, row, "id", temp_workunit_id);
|
||||
if ( temp_workunit_id != current_entry_workunit_id ) {
|
||||
seek_first_result();
|
||||
retval = -1;
|
||||
} else {
|
||||
parse_result(cursor.rp, row);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
// They don't necessarily serialize the entire records.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#include "db_base.h"
|
||||
|
||||
|
@ -427,7 +428,7 @@ struct MSG_TO_HOST {
|
|||
void clear();
|
||||
};
|
||||
|
||||
struct TRANSITIONER_QUEUE {
|
||||
struct TRANSITIONER_ITEM {
|
||||
int id;
|
||||
char name[256];
|
||||
int appid;
|
||||
|
@ -451,6 +452,7 @@ struct TRANSITIONER_QUEUE {
|
|||
int res_file_delete_state;
|
||||
int res_sent_time;
|
||||
void clear();
|
||||
void parse(MYSQL_ROW&);
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
@ -563,20 +565,21 @@ public:
|
|||
void db_parse(MYSQL_ROW &row);
|
||||
};
|
||||
|
||||
class DB_TRANSITIONER_QUEUE : public DB_BASE, public TRANSITIONER_QUEUE {
|
||||
// The transitioner uses this to get (WU, result) pairs efficiently.
|
||||
// Each call to enumerate() returns a list of the pairs for a single WU
|
||||
//
|
||||
class DB_TRANSITIONER_ITEM_SET : public DB_BASE_SPECIAL {
|
||||
public:
|
||||
DB_TRANSITIONER_QUEUE();
|
||||
|
||||
MYSQL_ROW_OFFSET current_entry_start_position;
|
||||
int current_entry_workunit_id;
|
||||
|
||||
int enumerate_entries(int transition_time, int ntotal_transitioners, int ntransitioner, int nresult_limit);
|
||||
void parse_entry(MYSQL_RES *result, MYSQL_ROW& row);
|
||||
void parse_result(MYSQL_RES *result, MYSQL_ROW& row);
|
||||
|
||||
int seek_first_result();
|
||||
int seek_next_result();
|
||||
DB_TRANSITIONER_ITEM_SET();
|
||||
TRANSITIONER_ITEM last_item;
|
||||
|
||||
int enumerate(
|
||||
int transition_time,
|
||||
int ntotal_transitioners,
|
||||
int ntransitioner,
|
||||
int nresult_limit,
|
||||
std::vector<TRANSITIONER_ITEM>& items
|
||||
);
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
|
61
db/db_base.C
61
db/db_base.C
|
@ -10,9 +10,6 @@
|
|||
#include "fcgi_stdio.h"
|
||||
#endif
|
||||
|
||||
#define MAX_QUERY_LEN 256000
|
||||
// TODO: use "string" instead of char[]
|
||||
|
||||
DB_CONN::DB_CONN() {
|
||||
mysql = 0;
|
||||
}
|
||||
|
@ -254,66 +251,10 @@ int DB_BASE::sum(double& x, char* field, char* clause) {
|
|||
}
|
||||
|
||||
|
||||
DB_BASE_PERF::DB_BASE_PERF(DB_CONN& p) : db(&p) {
|
||||
DB_BASE_SPECIAL::DB_BASE_SPECIAL(DB_CONN& p) : db(&p) {
|
||||
cursor.active = false;
|
||||
}
|
||||
|
||||
int DB_BASE_PERF::fetch_field_value(MYSQL_RES *result, MYSQL_ROW& row, const char* field_name, int& field_value)
|
||||
{
|
||||
unsigned int num_fields;
|
||||
unsigned int i;
|
||||
MYSQL_FIELD* fields;
|
||||
|
||||
num_fields = mysql_num_fields(result);
|
||||
fields = mysql_fetch_fields(result);
|
||||
for(i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (0 == strncmp(field_name, fields[i].name, strlen(field_name))) {
|
||||
field_value = safe_atoi(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DB_BASE_PERF::fetch_field_value(MYSQL_RES *result, MYSQL_ROW& row, const char* field_name, float& field_value)
|
||||
{
|
||||
unsigned int num_fields;
|
||||
unsigned int i;
|
||||
MYSQL_FIELD* fields;
|
||||
|
||||
num_fields = mysql_num_fields(result);
|
||||
fields = mysql_fetch_fields(result);
|
||||
for(i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (0 == strncmp(field_name, fields[i].name, strlen(field_name))) {
|
||||
field_value = safe_atof(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DB_BASE_PERF::fetch_field_value(MYSQL_RES *result, MYSQL_ROW& row, const char* field_name, char* field_value, int field_size)
|
||||
{
|
||||
unsigned int num_fields;
|
||||
unsigned int i;
|
||||
MYSQL_FIELD* fields;
|
||||
|
||||
num_fields = mysql_num_fields(result);
|
||||
fields = mysql_fetch_fields(result);
|
||||
for(i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (0 == strncmp(field_name, fields[i].name, strlen(field_name))) {
|
||||
memset(field_value, '\0', field_size);
|
||||
strlcpy(field_value, row[i], field_size);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// convert a string into a form that allows it to be used
|
||||
// in SQL queries delimited by single quotes:
|
||||
// replace ' with \', \ with \\
|
||||
|
|
25
db/db_base.h
25
db/db_base.h
|
@ -25,14 +25,15 @@
|
|||
// if SQL columns are not 'not null', you must use these safe_atoi, safe_atof
|
||||
// instead of atoi, atof, since the strings returned by MySQL may be NULL.
|
||||
//
|
||||
|
||||
inline int safe_atoi(const char* s) {
|
||||
if (!s) return 0;
|
||||
return atoi(s);
|
||||
if (!s) return 0;
|
||||
return atoi(s);
|
||||
}
|
||||
|
||||
inline float safe_atof(const char* s) {
|
||||
if (!s) return 0;
|
||||
return atof(s);
|
||||
if (!s) return 0;
|
||||
return atof(s);
|
||||
}
|
||||
|
||||
#define strcpy2(x, y) \
|
||||
|
@ -45,6 +46,9 @@ inline float safe_atof(const char* s) {
|
|||
} \
|
||||
}
|
||||
|
||||
#define MAX_QUERY_LEN 256000
|
||||
// TODO: use string for queries, get rid of this
|
||||
|
||||
struct CURSOR {
|
||||
bool active;
|
||||
MYSQL_RES *rp;
|
||||
|
@ -92,17 +96,12 @@ public:
|
|||
virtual void db_parse(MYSQL_ROW&);
|
||||
};
|
||||
|
||||
// Base for derived classes that can access the DB
|
||||
// Defines various generic operations on DB tables
|
||||
// for specially designed queries
|
||||
// Base for derived classes that can get special-purpose data,
|
||||
// perhaps spanning multiple tables
|
||||
//
|
||||
class DB_BASE_PERF {
|
||||
class DB_BASE_SPECIAL {
|
||||
public:
|
||||
DB_BASE_PERF(DB_CONN&);
|
||||
|
||||
int fetch_field_value(MYSQL_RES* result, MYSQL_ROW& row, const char* field_name, int& field_value);
|
||||
int fetch_field_value(MYSQL_RES* result, MYSQL_ROW& row, const char* field_name, float& field_value);
|
||||
int fetch_field_value(MYSQL_RES* result, MYSQL_ROW& row, const char* field_name, char* field_value, int field_size);
|
||||
DB_BASE_SPECIAL(DB_CONN&);
|
||||
|
||||
DB_CONN* db;
|
||||
CURSOR cursor;
|
||||
|
|
Loading…
Reference in New Issue