/* * PSEUDO CODE: * * EXTRACT INFO FROM XML NODE * RETRIEVE PROBE DEFINITION RECORD FROM DATABASE * RETRIEVE PRECEDING RAW RECORD FROM DATABASE * STORE RAW RESULTS * IF THIS IS THE FIRST RESULT EVER FOR THIS PROBE * CREATE PR_STATUS RECORD * ELSE * IF WE HAVEN'T PROCESSED THIS RECORD BEFORE * IF COLOR DIFFERS FROM PRECEDING RAW RECORD * CREATE PR_HIST * RETRIEVE FOLLOWING RAW RECORD * IF FOUND AND COLOR OF FOLLOWING IS THE SAME AS CURRENT * DELETE POSSIBLE HISTORY RECORDS FOR FOLLOWING RECORD * ENDIF * IF THIS RAW RECORD IS THE MOST RECENT EVER RECEIVED * WRITE NEW RECENT TIME INTO PROBE DEFINITION RECORD * UPDATE PR_STATUS * UPDATE SERVER COLOR * ENDIF * ELSE * IF THIS RAW RECORD IS THE MOST RECENT EVER RECEIVED * WRITE NEW RECENT TIME INTO PROBE DEFINITION RECORD * ENDIF * ENDIF * IF CURRENT RAW RECORD IS THE MOST RECENT * FOR EACH PERIOD * IF WE ENTERED A NEW SLOT * SUMMARIZE PREVIOUS SLOT * ENDIF * ENDFOR * ELSE * FOR EACH PERIOD * IF THE LAST RECORD FOR THIS SLOT HAS BEEN SEEN * RE-SUMMARIZE CURRENT SLOT * ENDIF * ENDFOR * ENDIF * ENDIF * ENDIF * * returns: * 1 in case of success * 0 in case of database failure where trying again later might help * -1 in case of malformed input, never try again * -2 in case of a fatal error, just skip this batch */ int process(trx *t) { int must_update_def=0; struct probe_result *prv=NULL; int err = 1; /* default ok */ if (!realm_exists(t->res->realm)) { return -1; } if (t->res->realm && t->res->realm[0]) { t->probe->db = open_realm(t->res->realm); } else { if (t->probe->find_realm) { t->probe->find_realm(t); } else { t->probe->db = open_realm(NULL); } } if (!t->probe->db) return -2; if (t->probe->resultcount % 400 == 0) { update_last_seen(t->probe); } if (debug > 3) fprintf(stderr, "accept_result\n"); if (t->probe->accept_result) { t->probe->accept_result(t); // do some final calculations on the result } if (debug > 3) fprintf(stderr, "get_def\n"); if (t->probe->get_def) { if (debug > 3) fprintf(stderr, "RETRIEVE PROBE DEFINITION RECORD FROM DATABASE\n"); t->def = t->probe->get_def(t, trust(t->res->name)); // RETRIEVE PROBE DEFINITION RECORD FROM DATABASE } else { t->def = get_def(t, trust(t->res->name)); } if (!t->def) { // Oops, def record not found. Skip this probe if (debug > 3) fprintf(stderr, "def NOT found\n"); err = -1; /* malformed input FIXME should make distinction between db errors and def not found */ goto exit_with_res; } if (t->probe->adjust_result) { t->probe->adjust_result(t); } if (debug > 3) fprintf(stderr, "STORE RAW RESULTS\n"); if (t->probe->store_results) { int ret = t->probe->store_results(t); // STORE RAW RESULTS if (!ret) { /* error return? */ if (debug > 3) fprintf(stderr, "error in store_results\n"); err = -2; /* database fatal error - try again later */ goto exit_with_res; } } else { t->seen_before = FALSE; } if (t->res->stattime > t->def->newest) { // IF CURRENT RAW RECORD IS THE MOST RECENT if (debug > 3) fprintf(stderr, "CURRENT RAW RECORD IS THE MOST RECENT\n"); prv = g_malloc0(sizeof(struct probe_result)); prv->color = t->def->color; // USE PREVIOUS COLOR FROM DEF RECORD prv->stattime = t->def->newest; } else { if (debug > 3) fprintf(stderr, "RETRIEVE PRECEDING RAW RECORD FROM DATABASE\n"); prv = get_previous_record(t); // RETRIEVE PRECEDING RAW RECORD FROM DATABASE } set_result_prev_color(t, prv); // indicate previous color in result set if (t->def->email[0]) { // and if email address given, add simple notification record xmlNodePtr notify; notify = xmlNewChild(t->cur, NULL, "notify", NULL); xmlSetProp(notify, "proto", "smtp"); xmlSetProp(notify, "target", t->def->email); } if (t->def->newest == 0) { // IF THIS IS THE FIRST RESULT EVER FOR THIS PROBE if (debug > 3) fprintf(stderr, "THIS IS THE FIRST RESULT EVER FOR THIS PROBE\n"); insert_pr_status(t); must_update_def = TRUE; goto finish; } if (t->seen_before) { goto finish; } // Extra debugging, be sure what colors are processed here if ( debug > 3 ) fprintf(stderr, "PREVIOUS COLOR %d - NEW COLOR %d\n", prv->color, t->res->color); // IF COLOR DIFFERS FROM PRECEDING RAW RECORD if (t->res->color != prv->color) { struct probe_result *nxt; if (t->probe->fuse) { if (t->res->color > prv->color || prv->color == STAT_PURPLE) { if (debug > 3) fprintf(stderr, "FUSE WITH HIGHER COLOR - CREATE PR_HIST\n"); create_pr_hist(t, prv); // CREATE PR_HIST } } else { if (debug > 3) fprintf(stderr, "COLOR DIFFERS FROM PRECEDING RAW RECORD - CREATE PR_HIST\n"); create_pr_hist(t, prv); // CREATE PR_HIST } if (t->res->stattime > t->def->newest) { // IF THIS RAW RECORD IS THE MOST RECENT EVER RECEIVED dbi_result result; if (debug > 3) fprintf(stderr, "THIS RAW RECORD IS THE MOST RECENT EVER RECEIVED - UPDATE PR_STATUS\n"); result = update_pr_status(t, prv); // UPDATE PR_STATUS if (dbi_result_get_numrows_affected(result) == 0) { // nothing was actually updated, need to insert new insert_pr_status(t); } dbi_result_free(result); if (debug > 3) fprintf(stderr, "UPDATE SERVER COLOR\n"); update_server_color(t, prv); // UPDATE SERVER COLOR must_update_def = TRUE; } else { if (debug > 3) fprintf(stderr, "RETRIEVE FOLLOWING RAW RECORD\n"); nxt = get_following_record(t); // RETRIEVE FOLLOWING RAW RECORD if (nxt && nxt->color) { // IF FOUND if (debug > 3) fprintf(stderr, "FOLLOWING RECORD IS FOUND\n"); if (nxt->color == t->res->color) { // IF COLOR OF FOLLOWING IS THE SAME AS CURRENT if (debug > 3) fprintf(stderr, "SAME COLOR: DELETE POSSIBLE HISTORY RECORDS\n"); delete_history(t, nxt); // DELETE POSSIBLE HISTORY RECORDS FOR FOLLOWING RECORD } g_free(nxt); } } } else { if (debug > 3) fprintf(stderr, "COLOR SAME AS PRECEDING RAW RECORD\n"); if (t->res->stattime > t->def->newest) { // IF THIS RAW RECORD IS THE MOST RECENT EVER RECEIVED dbi_result result; if (debug > 3) fprintf(stderr, "THIS RAW RECORD IS THE MOST RECENT EVER RECEIVED - UPDATE PR_STATUS\n"); result = update_pr_status(t, prv); // UPDATE PR_STATUS (not for the color, but for the expiry time) if (dbi_result_get_numrows_affected(result) == 0) { // nothing was actually updated, need to insert new insert_pr_status(t); } dbi_result_free(result); must_update_def = TRUE; } } if (t->def->email[0] || t->def->sms[0]) { // if we have an address // RETRIEVE LAST HIST ENTRY FOR THIS PROBE get_previous_pr_hist(t); // notify if needed if (strcmp(t->res->notified, "yes")) { // not already notified if (notify(t)) { set_pr_hist_notified(t); } } } if (t->probe->summarize && t->res->color != STAT_PURPLE) { if (t->res->stattime > t->def->newest) { // IF CURRENT RAW RECORD IS THE MOST RECENT guint cur_slot, prev_slot; gulong slotlow, slothigh; gulong dummy_low, dummy_high; gint i; if (debug > 3) fprintf(stderr, "SUMMARIZING. CURRENT RAW RECORD IS THE MOST RECENT\n"); for (i=0; summ_info[i].period != -1; i++) { // FOR EACH PERIOD prev_slot = uw_slot(summ_info[i].period, prv->stattime, &slotlow, &slothigh); cur_slot = uw_slot(summ_info[i].period, t->res->stattime, &dummy_low, &dummy_high); if (cur_slot != prev_slot) { // IF WE ENTERED A NEW SLOT, SUMMARIZE PREVIOUS SLOT if (debug > 3) fprintf(stderr, "cur(%u for %u) != prv(%u for %u), summarizing %s from %lu to %lu", cur_slot, t->res->stattime, prev_slot, prv->stattime, summ_info[i].from, slotlow, slothigh); t->probe->summarize(t, summ_info[i].from, summ_info[i].to, cur_slot, slotlow, slothigh, 0); } } } else { guint cur_slot; gulong slotlow, slothigh; gulong not_later_then = UINT_MAX; gint i; if (debug > 3) { fprintf(stderr, "SUMMARIZING. CURRENT RAW RECORD IS AN OLD ONE\n"); LOG(LOG_DEBUG, "stattime = %u, newest = %u for %s %u", t->res->stattime, t->def->newest, t->res->name, t->def->probeid); } for (i=0; summ_info[i].period != -1; i++) { // FOR EACH PERIOD cur_slot = uw_slot(summ_info[i].period, t->res->stattime, &slotlow, &slothigh); if (slothigh > not_later_then) continue; // we already know there are none later then this // IF THIS SLOT IS COMPLETE if (slot_is_complete(t, i, slotlow, slothigh)) { // RE-SUMMARIZE CURRENT SLOT if (debug > 3) fprintf(stderr, "SLOT IS COMPLETE - RE-SUMMARIZE CURRENT SLOT\n"); t->probe->summarize(t, summ_info[i].from, summ_info[i].to, cur_slot, slotlow, slothigh, 0); } else { not_later_then = slothigh; } } } } finish: if (must_update_def) { t->def->newest = t->res->stattime; t->def->color = t->res->color; } g_free(prv); exit_with_res: if (t->probe->end_result) { t->probe->end_result(t); } // free the result block if (t->res) { if (t->probe->free_res) { t->probe->free_res(t->res); // the probe specific part... } free_res(t->res); // .. and the generic part } // note we don't free the *t->def here, because that structure is owned by the hashtable // except if the module does not use caching, we try to free it ourselves if (!t->probe->needs_cache) { if (t->probe->free_def) { t->probe->free_def(t->def); } else { free(t->def); } } return err; }
unsigned long SMSDDBI_AffectedRows(GSM_SMSDConfig * Config, SQL_result *res) { return dbi_result_get_numrows_affected(res->dbi); }