/** * Builds REPLACE statement where cmd->values specify column names. * @param sql_cmd SQL statement as a result of this function * @param cmd input for statement creation */ static int build_replace_cmd(str* sql_cmd, db_cmd_t* cmd) { db_fld_t* fld; int i; char* p; sql_cmd->len = strings[STR_REPLACE].len; sql_cmd->len += cmd->table.len; sql_cmd->len += 2; /* " (" */ for(i = 0, fld = cmd->vals; !DB_FLD_LAST(fld[i]); i++) { sql_cmd->len += strlen(fld[i].name); sql_cmd->len += strings[STR_ESC].len; if (!DB_FLD_LAST(fld[i + 1])) sql_cmd->len += 2; /* , twice */ } sql_cmd->len += strings[STR_VALUES].len; sql_cmd->len += 1; /* ) */ sql_cmd->s = pkg_malloc(sql_cmd->len + 1); if (sql_cmd->s == NULL) { ERR("mysql: No memory left\n"); return -1; } p = sql_cmd->s; APPEND_STR(p, strings[STR_REPLACE]); APPEND_STR(p, cmd->table); *p++ = ' '; *p++ = '('; for(i = 0, fld = cmd->vals; !DB_FLD_LAST(fld[i]); i++) { APPEND_CSTR(p, fld[i].name); if (!DB_FLD_LAST(fld[i + 1])) *p++ = ','; } APPEND_STR(p, strings[STR_VALUES]); for(i = 0, fld = cmd->vals; !DB_FLD_LAST(fld[i]); i++) { APPEND_STR(p, strings[STR_ESC]); if (!DB_FLD_LAST(fld[i + 1])) *p++ = ','; } *p++ = ')'; *p = '\0'; return 0; }
int bgpstream_broker_datasource_update_input_queue( bgpstream_broker_datasource_t *broker_ds, bgpstream_input_mgr_t *input_mgr) { // we need to set two parameters: // - dataAddedSince ("time" from last response we got) // - minInitialTime (max("initialTime"+"duration") of any file we've ever seen) #define BUFLEN 20 char buf[BUFLEN]; io_t *jsonfile = NULL; ; int num_results; int attempts = 0; int wait_time = 1; int success = 0; if (broker_ds->last_response_time > 0) { // need to add dataAddedSince if (snprintf(buf, BUFLEN, "%" PRIu32, broker_ds->last_response_time) >= BUFLEN) { fprintf(stderr, "ERROR: Could not build dataAddedSince param string\n"); goto err; } AMPORQ; APPEND_STR("dataAddedSince="); APPEND_STR(buf); } if (broker_ds->current_window_end > 0) { // need to add minInitialTime if (snprintf(buf, BUFLEN, "%" PRIu32, broker_ds->current_window_end) >= BUFLEN) { fprintf(stderr, "ERROR: Could not build minInitialTime param string\n"); goto err; } AMPORQ; APPEND_STR("minInitialTime="); APPEND_STR(buf); } do { if (attempts > 0) { fprintf(stderr, "WARN: Broker request failed, waiting %ds before retry\n", wait_time); sleep(wait_time); if (wait_time < MAX_WAIT_TIME) { wait_time *= 2; } } attempts++; #ifdef WITH_BROKER_DEBUG fprintf(stderr, "\nQuery URL: \"%s\"\n", broker_ds->query_url_buf); #endif if ((jsonfile = wandio_create(broker_ds->query_url_buf)) == NULL) { fprintf(stderr, "ERROR: Could not open %s for reading\n", broker_ds->query_url_buf); goto retry; } if ((num_results = read_json(broker_ds, input_mgr, jsonfile)) == ERR_FATAL) { fprintf(stderr, "ERROR: Received fatal error code from read_json\n"); goto err; } else if (num_results == ERR_RETRY) { goto retry; } else { // success! success = 1; } retry: if (jsonfile != NULL) { wandio_destroy(jsonfile); jsonfile = NULL; } } while (success == 0); // reset the variable params *broker_ds->query_url_end = '\0'; broker_ds->query_url_remaining = URL_BUFLEN - strlen(broker_ds->query_url_end); return num_results; err: fprintf(stderr, "ERROR: Fatal error in broker data source\n"); if (jsonfile != NULL) { wandio_destroy(jsonfile); } return -1; }
/** * Builds SELECT statement where cmd->values specify column names * and cmd->match specify WHERE clause. * @param sql_cmd SQL statement as a result of this function * @param cmd input for statement creation */ static int build_select_cmd(str* sql_cmd, db_cmd_t* cmd) { db_fld_t* fld; int i; char* p; sql_cmd->len = strings[STR_SELECT].len; if (DB_FLD_EMPTY(cmd->result)) { sql_cmd->len += 1; /* "*" */ } else { for(i = 0, fld = cmd->result; !DB_FLD_LAST(fld[i]); i++) { sql_cmd->len += strlen(fld[i].name); if (!DB_FLD_LAST(fld[i + 1])) sql_cmd->len += 1; /* , */ } } sql_cmd->len += strings[STR_FROM].len; sql_cmd->len += cmd->table.len; if (!DB_FLD_EMPTY(cmd->match)) { sql_cmd->len += strings[STR_WHERE].len; for(i = 0, fld = cmd->match; !DB_FLD_LAST(fld[i]); i++) { sql_cmd->len += strlen(fld[i].name); switch(fld[i].op) { case DB_EQ: sql_cmd->len += strings[STR_OP_EQ].len; break; case DB_NE: sql_cmd->len += strings[STR_OP_NE].len; break; case DB_LT: sql_cmd->len += strings[STR_OP_LT].len; break; case DB_GT: sql_cmd->len += strings[STR_OP_GT].len; break; case DB_LEQ: sql_cmd->len += strings[STR_OP_LEQ].len; break; case DB_GEQ: sql_cmd->len += strings[STR_OP_GEQ].len; break; default: ERR("mysql: Unsupported db_fld operator %d\n", fld[i].op); return -1; } sql_cmd->len += strings[STR_ESC].len; if (!DB_FLD_LAST(fld[i + 1])) sql_cmd->len += strings[STR_AND].len; } } sql_cmd->s = pkg_malloc(sql_cmd->len + 1); if (sql_cmd->s == NULL) { ERR("mysql: No memory left\n"); return -1; } p = sql_cmd->s; APPEND_STR(p, strings[STR_SELECT]); if (DB_FLD_EMPTY(cmd->result)) { *p++ = '*'; } else { for(i = 0, fld = cmd->result; !DB_FLD_LAST(fld[i]); i++) { APPEND_CSTR(p, fld[i].name); if (!DB_FLD_LAST(fld[i + 1])) *p++ = ','; } } APPEND_STR(p, strings[STR_FROM]); APPEND_STR(p, cmd->table); if (!DB_FLD_EMPTY(cmd->match)) { APPEND_STR(p, strings[STR_WHERE]); for(i = 0, fld = cmd->match; !DB_FLD_LAST(fld[i]); i++) { APPEND_CSTR(p, fld[i].name); switch(fld[i].op) { case DB_EQ: APPEND_STR(p, strings[STR_OP_EQ]); break; case DB_NE: APPEND_STR(p, strings[STR_OP_NE]); break; case DB_LT: APPEND_STR(p, strings[STR_OP_LT]); break; case DB_GT: APPEND_STR(p, strings[STR_OP_GT]); break; case DB_LEQ: APPEND_STR(p, strings[STR_OP_LEQ]); break; case DB_GEQ: APPEND_STR(p, strings[STR_OP_GEQ]); break; } APPEND_STR(p, strings[STR_ESC]); if (!DB_FLD_LAST(fld[i + 1])) APPEND_STR(p, strings[STR_AND]); } } *p = '\0'; return 0; }
bgpstream_broker_datasource_t * bgpstream_broker_datasource_create(bgpstream_filter_mgr_t *filter_mgr, char *broker_url, char **params, int params_cnt) { int i; bgpstream_debug("\t\tBSDS_BROKER: create broker_ds start"); bgpstream_broker_datasource_t *broker_ds; if ((broker_ds = malloc_zero(sizeof(bgpstream_broker_datasource_t))) == NULL) { bgpstream_log_err( "\t\tBSDS_BROKER: create broker_ds can't allocate memory"); goto err; } if (broker_url == NULL) { bgpstream_log_err("\t\tBSDS_BROKER: create broker_ds no file provided"); goto err; } broker_ds->filter_mgr = filter_mgr; broker_ds->first_param = 1; broker_ds->query_url_remaining = URL_BUFLEN; broker_ds->query_url_buf[0] = '\0'; // http://bgpstream.caida.org/broker (e.g.) APPEND_STR(broker_url); // http://bgpstream.caida.org/broker/data? APPEND_STR("/data"); // projects, collectors, bgp_types, and time_intervals are used as filters // only if they are provided by the user bgpstream_interval_filter_t *tif; // projects char *f; if (filter_mgr->projects != NULL) { bgpstream_str_set_rewind(filter_mgr->projects); while ((f = bgpstream_str_set_next(filter_mgr->projects)) != NULL) { AMPORQ; APPEND_STR("projects[]="); APPEND_STR(f); } } // collectors if (filter_mgr->collectors != NULL) { bgpstream_str_set_rewind(filter_mgr->collectors); while ((f = bgpstream_str_set_next(filter_mgr->collectors)) != NULL) { AMPORQ; APPEND_STR("collectors[]="); APPEND_STR(f); } } // bgp_types if (filter_mgr->bgp_types != NULL) { bgpstream_str_set_rewind(filter_mgr->bgp_types); while ((f = bgpstream_str_set_next(filter_mgr->bgp_types)) != NULL) { AMPORQ; APPEND_STR("types[]="); APPEND_STR(f); } } // user-provided params for (i = 0; i < params_cnt; i++) { assert(params[i] != NULL); AMPORQ; APPEND_STR(params[i]); } // time_intervals #define BUFLEN 20 char int_buf[BUFLEN]; if (filter_mgr->time_intervals != NULL) { tif = filter_mgr->time_intervals; while (tif != NULL) { AMPORQ; APPEND_STR("intervals[]="); // BEGIN TIME if (snprintf(int_buf, BUFLEN, "%" PRIu32, tif->begin_time) >= BUFLEN) { goto err; } APPEND_STR(int_buf); APPEND_STR(","); // END TIME if (snprintf(int_buf, BUFLEN, "%" PRIu32, tif->end_time) >= BUFLEN) { goto err; } APPEND_STR(int_buf); tif = tif->next; } } // grab pointer to the end of the current string to simplify modifying the // query later broker_ds->query_url_end = broker_ds->query_url_buf + strlen(broker_ds->query_url_buf); assert((*broker_ds->query_url_end) == '\0'); bgpstream_debug("\t\tBSDS_BROKER: create broker_ds end"); return broker_ds; err: bgpstream_broker_datasource_destroy(broker_ds); return NULL; }