sphinx_context sphinx_select(sphinx_config *config, const PString *index, const PString *match, const PString *condition, const PString *order, int offset, int limit, const PString *options, char **error) { StringBuilder *sb; sphinx_context ctx; if (!ensure_sphinx_is_connected(config, error)) return NULL; sb = string_builder_new(); string_builder_append(sb, "SELECT id, weight() AS weight FROM "); string_builder_append(sb, config->prefix); string_builder_append_pstr(sb, index); string_builder_append(sb, " WHERE MATCH('"); string_builder_append_quoted(sb, match); string_builder_append(sb, "')"); if (PSTR_NOT_EMPTY(condition)) { string_builder_append(sb, " AND "); string_builder_append_pstr(sb, condition); } string_builder_append(sb, " GROUP BY id WITHIN GROUP ORDER BY weight DESC "); if (PSTR_NOT_EMPTY(order)) { string_builder_append(sb, " ORDER BY "); string_builder_append_pstr(sb, order); } string_builder_append(sb, " LIMIT "); string_builder_append_int(sb, offset); string_builder_append(sb, ", "); string_builder_append_int(sb, limit); if (PSTR_NOT_EMPTY(options)) { string_builder_append(sb, " OPTION "); string_builder_append_pstr(sb, options); } if (mysql_query(connection, sb->str)) { REPORT(error, "Can't execute select query: ", sb->str, "; ", mysql_error(connection)); string_builder_free(sb); return NULL; } ctx = malloc(sizeof(struct sphinx_context)); ctx->result = mysql_store_result(connection); string_builder_free(sb); return ctx; }
const char *__hastur_format_json(const char *message_type, ...) { /* varargs list for label/type/value triples */ va_list argp; string_builder_t *builder; builder = string_builder_new(buf, BUFLEN); va_start(argp, message_type); string_builder_append(builder, "{\"type\":\""); string_builder_append(builder, message_type); string_builder_append(builder, "\","); format_json_from_va_list(builder, argp); string_builder_append(builder, "}"); va_end(argp); return buf; }
void sphinx_delete(sphinx_config *config, const PString *index, int id, char **error) { StringBuilder *sb; if (!ensure_sphinx_is_connected(config, error)) return; sb = string_builder_new(); string_builder_append(sb, "DELETE FROM "); string_builder_append(sb, config->prefix); string_builder_append_pstr(sb, index); string_builder_append(sb, " WHERE id = "); string_builder_append_int(sb, id); if (mysql_query(connection, sb->str)) REPORT(error, "Can't execute delete query: ", sb->str, "; ", mysql_error(connection)); string_builder_free(sb); }
void sphinx_replace(sphinx_config *config, const PString *index, int id, const PString *columns, const PString *values, size_t count, char **error) { size_t i; StringBuilder *sb; if (!ensure_sphinx_is_connected(config, error)) return; sb = string_builder_new(); string_builder_append(sb, "REPLACE INTO "); string_builder_append(sb, config->prefix); string_builder_append_pstr(sb, index); string_builder_append(sb, " (id"); for (i = 0; i < count; ++i) { string_builder_append(sb, ", `"); string_builder_append_pstr(sb, &columns[i]); string_builder_append(sb, "`"); } string_builder_append(sb, ") VALUES ("); string_builder_append_int(sb, id); for (i = 0; i < count; ++i) { string_builder_append(sb, ", '"); string_builder_append_quoted(sb, &values[i]); string_builder_append(sb, "'"); } string_builder_append(sb, ")"); if (mysql_query(connection, sb->str)) REPORT(error, "Can't execute replace query: ", sb->str, "; ", mysql_error(connection)); string_builder_free(sb); }
const char *__hastur_generate_labels(va_list argp) { string_builder_t *builder; va_list arg_copy; int app_seen = 0; int pid_seen = 0; int tid_seen = 0; int count = 0; /* Copy the arg list so we can see if app, pid or tid is supplied */ va_copy(arg_copy, argp); builder = string_builder_new(label_buf, BUFLEN); string_builder_append_char(builder, '{'); format_json_from_va_list(builder, argp); /* Now iterate through arg_copy and look for labels */ while(1) { const char *label; int value_type; label = va_arg(arg_copy, const char *); if(!label) break; count++; /* Update total count of labels */ if(!strncmp("app", label, 4)) { app_seen = 1; } else if(!strncmp("pid", label, 4)) { pid_seen = 1; } else if(!strncmp("tid", label, 4)) { tid_seen = 1; } value_type = va_arg(arg_copy, int); switch(value_type) { case HASTUR_INT: va_arg(arg_copy, int); break; case HASTUR_STR: case HASTUR_COMMA_SEPARATED_ARRAY: case HASTUR_BARE: va_arg(arg_copy, const char *); break; case HASTUR_LONG: va_arg(arg_copy, long); break; case HASTUR_DOUBLE: va_arg(arg_copy, double); break; default: fprintf(stderr, "Unrecognized Hastur type %d!\n", value_type); } } va_end(arg_copy); /* Now append any label(s) we haven't already seen */ if(!app_seen) { if(count != 0) { string_builder_append_char(builder, ','); } string_builder_append(builder, "\"app\":\""); string_builder_append(builder, hastur_get_app_name()); string_builder_append_char(builder, '\"'); } if(!pid_seen) { string_builder_append(builder, ",\"pid\":"); string_builder_append(builder, get_pid()); } if(!tid_seen) { string_builder_append(builder, ",\"tid\":\""); string_builder_append(builder, get_tid()); string_builder_append_char(builder, '\"'); } string_builder_append_char(builder, '}'); return label_buf; }
static void format_json_from_va_list(string_builder_t *builder, va_list argp) { int first = 1; const char *label; int value_type; const char *value_str; int value_int; long value_long; double value_double; while(1) { label = va_arg(argp, const char *); if(!label) break; /* When we hit a NULL, stop. */ if(first) { first = 0; /* not first any more */ } else { string_builder_append_char(builder, ','); } string_builder_append_char(builder, '\"'); string_builder_append(builder, label); string_builder_append(builder, "\":"); value_type = va_arg(argp, int); switch(value_type) { case HASTUR_STRING: value_str = va_arg(argp, const char *); string_builder_append(builder, "\""); string_builder_append(builder, value_str); /* TODO: escape string */ string_builder_append(builder, "\""); break; case HASTUR_NAME: value_str = va_arg(argp, const char *); string_builder_append(builder, "\""); string_builder_append(builder, hastur_get_message_name_prefix()); string_builder_append(builder, value_str); /* TODO: escape string */ string_builder_append(builder, "\""); break; case HASTUR_BARE: value_str = va_arg(argp, const char *); string_builder_append(builder, value_str); break; case HASTUR_INT: value_int = va_arg(argp, int); sprintf(sub_buf, "%d", value_int); string_builder_append(builder, sub_buf); break; case HASTUR_LONG: value_long = va_arg(argp, long); sprintf(sub_buf, "%ld", value_long); string_builder_append(builder, sub_buf); break; case HASTUR_DOUBLE: value_double = va_arg(argp, double); sprintf(sub_buf, "%g", value_double); string_builder_append(builder, sub_buf); break; case HASTUR_COMMA_SEPARATED_ARRAY: { const char *index; const char *end_ptr; int first = 1; value_str = va_arg(argp, const char *); index = value_str; end_ptr = value_str + strlen(value_str); string_builder_append_char(builder, '['); /* Convert from CSV to array */ while(index < end_ptr) { const char *word = index; if(first) { first = 0; } else { string_builder_append_char(builder, ','); } index = strchr(index, ','); if(!index) { /* Append final word */ string_builder_append_char(builder, '\"'); string_builder_append(builder, word); string_builder_append_char(builder, '\"'); break; } string_builder_append_char(builder, '\"'); string_builder_append_chars(builder, word, (index - word)); string_builder_append_char(builder, '\"'); index++; /* Advance past the comma */ } string_builder_append_char(builder, ']'); break; } default: fprintf(stderr, "Unrecognized value type %d!\n", value_type); /* And continue... */ } } }
void sphinx_snippet_options(sphinx_config *config, const PString *index, const PString *match, const PString *data, const PString *options, return_data_callback callback, void *user_data, char **error) { StringBuilder *sb; MYSQL_RES *query_result; MYSQL_ROW row; unsigned long *lengths; if (!callback) return; if (!ensure_sphinx_is_connected(config, error)) return; sb = string_builder_new(); string_builder_append(sb, "CALL SNIPPETS('"); string_builder_append_quoted(sb, data); string_builder_append(sb, "', '"); string_builder_append(sb, config->prefix); string_builder_append_pstr(sb, index); string_builder_append(sb, "', '"); string_builder_append_quoted(sb, match); string_builder_append(sb, "'"); if (PSTR_NOT_EMPTY(options)) { string_builder_append(sb, ","); string_builder_append_pstr(sb, options); } string_builder_append(sb, ")"); if (mysql_query(connection, sb->str)) { REPORT(error, "Can't execute snippet query: ", sb->str, "; ", mysql_error(connection)); string_builder_free(sb); return; } query_result = mysql_store_result(connection); if (!query_result) { REPORT(error, "Can't store result of snippet query: ", sb->str, "; ", mysql_error(connection)); string_builder_free(sb); return; } row = mysql_fetch_row(query_result); if (!row) { REPORT(error, "Can't fetch result of snippet query: ", sb->str, "; ", mysql_error(connection)); string_builder_free(sb); mysql_free_result(query_result); return; } lengths = mysql_fetch_lengths(query_result); callback(row[0], lengths[0], user_data); string_builder_free(sb); mysql_free_result(query_result); }