1 // This file is part of BOINC. 2 // http://boinc.berkeley.edu 3 // Copyright (C) 2008 University of California 4 // 5 // BOINC is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU Lesser General Public License 7 // as published by the Free Software Foundation, 8 // either version 3 of the License, or (at your option) any later version. 9 // 10 // BOINC is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 // See the GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with BOINC. If not, see <http://www.gnu.org/licenses/>. 17 18 #ifndef _BOINC_DB_ 19 #define _BOINC_DB_ 20 21 // Structures corresponding to database records. 22 // Some of these types have counterparts in client/types.h, 23 // but don't be deceived - client and server have different variants. 24 25 // The parse and write functions are for use in scheduler RPC. 26 // They don't necessarily serialize the entire records. 27 28 #include <cstdio> 29 #include <vector> 30 #include <string.h> 31 32 #include "db_base.h" 33 #include "boinc_db_types.h" 34 35 extern DB_CONN boinc_db; 36 37 struct TRANSITIONER_ITEM { 38 DB_ID_TYPE id; // WARNING: this is the WU ID 39 char name[256]; 40 DB_ID_TYPE appid; 41 int min_quorum; 42 bool need_validate; 43 DB_ID_TYPE canonical_resultid; 44 int transition_time; 45 int delay_bound; 46 int error_mask; 47 int max_error_results; 48 int max_total_results; 49 int file_delete_state; 50 int assimilate_state; 51 int target_nresults; 52 char result_template_file[64]; 53 int priority; 54 int hr_class; 55 int batch; 56 DB_ID_TYPE app_version_id; 57 int transitioner_flags; 58 int size_class; 59 DB_ID_TYPE res_id; // This is the RESULT ID 60 char res_name[256]; 61 int res_report_deadline; 62 int res_server_state; 63 int res_outcome; 64 int res_validate_state; 65 int res_file_delete_state; 66 int res_sent_time; 67 DB_ID_TYPE res_hostid; 68 int res_received_time; 69 DB_ID_TYPE res_app_version_id; 70 int res_exit_status; 71 72 void clear(); 73 void parse(MYSQL_ROW&); 74 }; 75 76 struct DB_HOST_APP_VERSION : public DB_BASE, public HOST_APP_VERSION { 77 DB_HOST_APP_VERSION(DB_CONN* p=0); 78 void db_print(char*); 79 void db_parse(MYSQL_ROW &row); 80 int update_scheduler(DB_HOST_APP_VERSION&); 81 int update_validator(DB_HOST_APP_VERSION&); 82 }; 83 84 struct DB_USER_SUBMIT : public DB_BASE, public USER_SUBMIT { 85 DB_USER_SUBMIT(DB_CONN* p=0); 86 void db_print(char*); 87 void db_parse(MYSQL_ROW &row); 88 }; 89 90 struct STATE_COUNTS { 91 DB_ID_TYPE appid; 92 int last_update_time; 93 int result_server_state_2; 94 int result_server_state_4; 95 int result_file_delete_state_1; 96 int result_file_delete_state_2; 97 int result_server_state_5_and_file_delete_state_0; 98 int workunit_need_validate_1; 99 int workunit_assimilate_state_1; 100 int workunit_file_delete_state_1; 101 int workunit_file_delete_state_2; 102 103 void clear(); 104 }; 105 106 struct DB_STATE_COUNTS : public DB_BASE, public STATE_COUNTS { 107 DB_STATE_COUNTS(DB_CONN* p=0); 108 DB_ID_TYPE get_id(); 109 void db_print(char *); 110 void db_parse(MYSQL_ROW &row); 111 }; 112 113 struct VALIDATOR_ITEM { 114 WORKUNIT wu; 115 RESULT res; 116 117 void clear(); 118 void parse(MYSQL_ROW&); 119 }; 120 121 class DB_PLATFORM : public DB_BASE, public PLATFORM { 122 public: 123 DB_PLATFORM(DB_CONN* p=0); 124 DB_ID_TYPE get_id(); 125 void db_print(char*); 126 void db_parse(MYSQL_ROW &row); 127 }; 128 129 class DB_APP : public DB_BASE, public APP { 130 public: 131 DB_APP(DB_CONN* p=0); 132 DB_ID_TYPE get_id(); 133 void db_print(char*); 134 void db_parse(MYSQL_ROW &row); 135 }; 136 137 class DB_APP_VERSION : public DB_BASE, public APP_VERSION { 138 public: 139 DB_APP_VERSION(DB_CONN* p=0); 140 DB_ID_TYPE get_id(); 141 void db_print(char*); 142 void db_parse(MYSQL_ROW &row); 143 void operator=(APP_VERSION& w) {APP_VERSION::operator=(w);} 144 }; 145 146 class DB_USER : public DB_BASE, public USER { 147 public: 148 DB_USER(DB_CONN* p=0); 149 DB_ID_TYPE get_id(); 150 void db_print(char*); 151 void db_parse(MYSQL_ROW &row); 152 void operator=(USER& r) {USER::operator=(r);} 153 }; 154 155 class DB_TEAM : public DB_BASE, public TEAM { 156 public: 157 DB_TEAM(DB_CONN* p=0); 158 DB_ID_TYPE get_id(); 159 void db_print(char*); 160 void db_parse(MYSQL_ROW &row); 161 }; 162 163 class DB_HOST : public DB_BASE, public HOST { 164 public: 165 DB_HOST(DB_CONN* p=0); 166 DB_ID_TYPE get_id(); 167 int update_diff_sched(HOST&); 168 int update_diff_validator(HOST&); 169 int fpops_percentile(double percentile, double& fpops); 170 // return the given percentile of p_fpops 171 int fpops_mean(double& mean); 172 int fpops_stddev(double& stddev); 173 void db_print(char*); 174 void db_parse(MYSQL_ROW &row); 175 void operator=(HOST& r) {HOST::operator=(r);} 176 }; 177 178 class DB_RESULT : public DB_BASE, public RESULT { 179 public: 180 DB_RESULT(DB_CONN* p=0); 181 DB_ID_TYPE get_id(); 182 int mark_as_sent(int old_server_state, int report_grace_period); 183 void db_print(char*); 184 void db_print_values(char*); 185 void db_parse(MYSQL_ROW &row); 186 void operator=(RESULT& r) {RESULT::operator=(r);} 187 int get_unsent_counts(APP&, int* unsent, int count_max); 188 int make_unsent( 189 APP&, int size_class, int n, const char* order_clause, int& nchanged 190 ); 191 }; 192 193 class DB_WORKUNIT : public DB_BASE, public WORKUNIT { 194 public: 195 DB_WORKUNIT(DB_CONN* p=0); 196 DB_ID_TYPE get_id(); 197 void db_print(char*); 198 void db_print_values(char*); 199 void db_parse(MYSQL_ROW &row); 200 void operator=(WORKUNIT& w) {WORKUNIT::operator=(w);} 201 }; 202 203 class DB_CREDITED_JOB : public DB_BASE, public CREDITED_JOB { 204 public: 205 DB_CREDITED_JOB(DB_CONN* p=0); 206 void db_print(char*); 207 void db_parse(MYSQL_ROW &row); 208 void operator=(CREDITED_JOB& wh) {CREDITED_JOB::operator=(wh);} 209 }; 210 211 class DB_MSG_FROM_HOST : public DB_BASE, public MSG_FROM_HOST { 212 public: 213 DB_MSG_FROM_HOST(DB_CONN* p=0); 214 DB_ID_TYPE get_id(); 215 void db_print(char*); 216 void db_parse(MYSQL_ROW &row); 217 }; 218 219 class DB_MSG_TO_HOST : public DB_BASE, public MSG_TO_HOST { 220 public: 221 DB_MSG_TO_HOST(DB_CONN* p=0); 222 DB_ID_TYPE get_id(); 223 void db_print(char*); 224 void db_parse(MYSQL_ROW &row); 225 }; 226 227 class DB_ASSIGNMENT : public DB_BASE, public ASSIGNMENT { 228 public: 229 DB_ASSIGNMENT(DB_CONN* p=0); 230 DB_ID_TYPE get_id(); 231 void db_print(char*); 232 void db_parse(MYSQL_ROW& row); 233 }; 234 235 // The transitioner uses this to get (WU, result) pairs efficiently. 236 // Each call to enumerate() returns a list of the pairs for a single WU 237 // 238 class DB_TRANSITIONER_ITEM_SET : public DB_BASE_SPECIAL { 239 public: 240 DB_TRANSITIONER_ITEM_SET(DB_CONN* p=0); 241 TRANSITIONER_ITEM last_item; 242 int nitems_this_query; 243 244 int enumerate( 245 int transition_time, 246 int nresult_limit, 247 int wu_id_modulus, 248 int wu_id_remainder, 249 std::vector<TRANSITIONER_ITEM>& items 250 ); 251 int update_result(TRANSITIONER_ITEM&); 252 int update_workunit(TRANSITIONER_ITEM&, TRANSITIONER_ITEM&); 253 }; 254 255 // The validator uses this to get (WU, result) pairs efficiently. 256 // Each call to enumerate() returns a list of the pairs for a single WU 257 // 258 class DB_VALIDATOR_ITEM_SET : public DB_BASE_SPECIAL { 259 public: 260 DB_VALIDATOR_ITEM_SET(DB_CONN* p=0); 261 VALIDATOR_ITEM last_item; 262 int nitems_this_query; 263 264 int enumerate( 265 DB_ID_TYPE appid, 266 int nresult_limit, 267 int wu_id_modulus, 268 int wu_id_remainder, 269 DB_ID_TYPE wu_id_min, 270 DB_ID_TYPE wu_id_max, 271 std::vector<VALIDATOR_ITEM>& items 272 ); 273 int update_result(RESULT&); 274 int update_workunit(WORKUNIT&); 275 }; 276 277 278 // used by the feeder and scheduler for outgoing work 279 // 280 struct WORK_ITEM { 281 DB_ID_TYPE res_id; 282 int res_priority; 283 int res_server_state; 284 double res_report_deadline; 285 WORKUNIT wu; 286 void parse(MYSQL_ROW& row); 287 }; 288 289 class DB_WORK_ITEM : public WORK_ITEM, public DB_BASE_SPECIAL { 290 DB_ID_TYPE start_id; 291 // when enumerate_all is used, keeps track of which ID to start from 292 public: 293 DB_WORK_ITEM(DB_CONN* p=0); 294 int enumerate( 295 int limit, const char* select_clause, const char* order_clause 296 ); 297 // used by feeder 298 int enumerate_all( 299 int limit, const char* select_clause 300 ); 301 // used by feeder when HR is used. 302 // Successive calls cycle through all results. 303 int read_result(); 304 // used by scheduler to read result server state 305 int update(); 306 // used by scheduler to update WU transition time 307 // and various result fields 308 }; 309 310 // Used by the scheduler to send <result_abort> or <result_abort_if_not_started> 311 // messages if the result is no longer needed. 312 // 313 struct IN_PROGRESS_RESULT { 314 char result_name[256]; 315 int assimilate_state; 316 int error_mask; 317 int server_state; 318 int outcome; 319 void parse(MYSQL_ROW& row); 320 }; 321 322 class DB_IN_PROGRESS_RESULT : public IN_PROGRESS_RESULT, public DB_BASE_SPECIAL { 323 public: 324 DB_IN_PROGRESS_RESULT(DB_CONN* p=0); 325 int enumerate(DB_ID_TYPE hostid, const char* result_names); 326 }; 327 328 // Used by the scheduler to handle results reported by clients 329 // The read and the update of these results are combined 330 // into single SQL queries. 331 332 struct SCHED_RESULT_ITEM { 333 char queried_name[256]; // name as reported by client 334 DB_ID_TYPE id; 335 char name[256]; 336 DB_ID_TYPE workunitid; 337 DB_ID_TYPE appid; 338 int server_state; 339 int client_state; 340 int validate_state; 341 int outcome; 342 DB_ID_TYPE hostid; 343 DB_ID_TYPE userid; 344 DB_ID_TYPE teamid; 345 int sent_time; 346 int received_time; 347 double cpu_time; 348 char xml_doc_out[BLOB_SIZE]; 349 char stderr_out[BLOB_SIZE]; 350 int app_version_num; 351 int exit_status; 352 int file_delete_state; 353 double elapsed_time; 354 DB_ID_TYPE app_version_id; 355 double peak_working_set_size; 356 double peak_swap_size; 357 double peak_disk_usage; 358 359 void clear(); 360 void parse(MYSQL_ROW& row); 361 }; 362 363 class DB_SCHED_RESULT_ITEM_SET : public DB_BASE_SPECIAL { 364 public: 365 DB_SCHED_RESULT_ITEM_SET(DB_CONN* p=0); 366 std::vector<SCHED_RESULT_ITEM> results; 367 368 int add_result(char* result_name); 369 370 int enumerate(); 371 // using a single SQL query, look up all the reported results, 372 // (based on queried_name) 373 // and fill in the rest of the entries in the results vector 374 375 int lookup_result(char* result_name, SCHED_RESULT_ITEM** result); 376 377 int update_result(SCHED_RESULT_ITEM& result); 378 int update_workunits(); 379 }; 380 381 struct FILE_ITEM { 382 DB_ID_TYPE id; 383 char name[254]; 384 char md5sum[34]; 385 double size; 386 387 void clear(); 388 }; 389 390 class DB_FILE : public DB_BASE, public FILE_ITEM { 391 public: 392 DB_FILE(DB_CONN* p=0); 393 DB_ID_TYPE get_id(); 394 void db_print(char*); 395 void db_parse(MYSQL_ROW &row); 396 void operator=(FILE_ITEM& f) {FILE_ITEM::operator=(f);} 397 }; 398 399 struct FILESET_ITEM { 400 DB_ID_TYPE id; 401 char name[254]; 402 403 void clear(); 404 }; 405 406 class DB_FILESET : public DB_BASE, public FILESET_ITEM { 407 public: 408 DB_FILESET(DB_CONN* p=0); 409 DB_ID_TYPE get_id(); 410 void db_print(char*); 411 void db_parse(MYSQL_ROW &row); 412 void operator=(FILESET_ITEM& f) {FILESET_ITEM::operator=(f);} 413 414 // retrieve fileset instance (populate object) 415 int select_by_name(const char* name); 416 }; 417 418 struct FILESET_FILE_ITEM { 419 DB_ID_TYPE fileset_id; 420 DB_ID_TYPE file_id; 421 422 void clear(); 423 }; 424 425 class DB_FILESET_FILE : public DB_BASE, public FILESET_FILE_ITEM { 426 public: 427 DB_FILESET_FILE(DB_CONN* p=0); 428 void db_print(char*); 429 void db_parse(MYSQL_ROW &row); 430 void operator=(FILESET_FILE_ITEM& tf) {FILESET_FILE_ITEM::operator=(tf);} 431 }; 432 433 struct SCHED_TRIGGER_ITEM { 434 DB_ID_TYPE id; 435 DB_ID_TYPE fileset_id; 436 bool need_work; 437 bool work_available; 438 bool no_work_available; 439 bool working_set_removal; 440 441 void clear(); 442 }; 443 444 class DB_SCHED_TRIGGER : public DB_BASE, public SCHED_TRIGGER_ITEM { 445 public: 446 DB_SCHED_TRIGGER(DB_CONN* p=0); 447 DB_ID_TYPE get_id(); 448 void db_print(char*); 449 void db_parse(MYSQL_ROW &row); 450 void operator=(SCHED_TRIGGER_ITEM& t) {SCHED_TRIGGER_ITEM::operator=(t);} 451 452 typedef enum { 453 none = 0, 454 state_need_work = 1, 455 state_work_available = 2, 456 state_no_work_available = 3, 457 state_working_set_removal = 4 458 } STATE; 459 460 // retrieve trigger instance (populate object) 461 int select_unique_by_fileset_name(const char* fileset_name); 462 // set single trigger state 463 int update_single_state(const DB_SCHED_TRIGGER::STATE state, const bool value); 464 }; 465 466 struct FILESET_SCHED_TRIGGER_ITEM { 467 FILESET_ITEM fileset; 468 SCHED_TRIGGER_ITEM trigger; 469 470 void clear(); 471 }; 472 473 class DB_FILESET_SCHED_TRIGGER_ITEM : public DB_BASE_SPECIAL, public FILESET_SCHED_TRIGGER_ITEM { 474 public: 475 DB_FILESET_SCHED_TRIGGER_ITEM(DB_CONN* p=0); 476 void db_parse(MYSQL_ROW &row); 477 void operator=(FILESET_SCHED_TRIGGER_ITEM& fst) {FILESET_SCHED_TRIGGER_ITEM::operator=(fst);} 478 }; 479 480 class DB_FILESET_SCHED_TRIGGER_ITEM_SET : public DB_BASE_SPECIAL { 481 public: 482 DB_FILESET_SCHED_TRIGGER_ITEM_SET(DB_CONN* p=0); 483 484 // select available triggers based on name and/or state 485 // -> name filter optional (set string, default NULL) 486 // -> pattern search optional (set use_regexp to true, default false)) 487 // -> state filter optional (set state, default none) 488 // -> state_value (default true) 489 int select_by_name_state( 490 const char* fileset_name, 491 const bool use_regexp, 492 const DB_SCHED_TRIGGER::STATE state, 493 const bool state_value); 494 495 // check if given trigger (fileset name) is part of set and return position (1-indexed) 496 int contains_trigger(const char* fileset_name); 497 498 // storage vector 499 std::vector<DB_FILESET_SCHED_TRIGGER_ITEM> items; 500 }; 501 502 struct DB_VDA_FILE : public DB_BASE, public VDA_FILE { 503 DB_VDA_FILE(DB_CONN* p=0); 504 DB_ID_TYPE get_id(); 505 void db_print(char*); 506 void db_parse(MYSQL_ROW &row); 507 }; 508 509 struct DB_VDA_CHUNK_HOST : public DB_BASE, public VDA_CHUNK_HOST { 510 DB_VDA_CHUNK_HOST(DB_CONN* p=0); 511 void db_print(char*); 512 void db_parse(MYSQL_ROW &row); 513 }; 514 515 struct DB_BADGE : public DB_BASE, public BADGE { 516 DB_BADGE(DB_CONN* p=0); get_idDB_BADGE517 DB_ID_TYPE get_id() {return id;}; db_printDB_BADGE518 void db_print(char*){}; 519 void db_parse(MYSQL_ROW&); 520 }; 521 522 struct DB_BADGE_USER : public DB_BASE, public BADGE_USER { 523 DB_BADGE_USER(DB_CONN* p=0); db_printDB_BADGE_USER524 void db_print(char*){}; 525 void db_parse(MYSQL_ROW&); 526 }; 527 528 struct DB_BADGE_TEAM : public DB_BASE, public BADGE_TEAM { 529 DB_BADGE_TEAM(DB_CONN* p=0); db_printDB_BADGE_TEAM530 void db_print(char*){}; 531 void db_parse(MYSQL_ROW&); 532 }; 533 534 struct DB_CREDIT_USER : public DB_BASE, public CREDIT_USER { 535 DB_CREDIT_USER(DB_CONN* p=0); 536 void db_print(char*); 537 void db_parse(MYSQL_ROW&); 538 }; 539 540 struct DB_CREDIT_TEAM : public DB_BASE, public CREDIT_TEAM { 541 DB_CREDIT_TEAM(DB_CONN* p=0); 542 void db_print(char*); 543 void db_parse(MYSQL_ROW&); 544 }; 545 546 #endif 547