| 2053 | } |
| 2054 | |
| 2055 | static char *handle_query_graph(cbm_mcp_server_t *srv, const char *args) { |
| 2056 | char *query = cbm_mcp_get_string_arg(args, "query"); |
| 2057 | char *project = get_project_arg(args); |
| 2058 | cbm_store_t *store = resolve_store(srv, project); |
| 2059 | int max_rows = cbm_mcp_get_int_arg(args, "max_rows", 0); |
| 2060 | |
| 2061 | if (!query) { |
| 2062 | free(project); |
| 2063 | return cbm_mcp_text_result("query is required", true); |
| 2064 | } |
| 2065 | if (!store) { |
| 2066 | char *_err = build_project_list_error("project not found or not indexed"); |
| 2067 | char *_res = cbm_mcp_text_result(_err, true); |
| 2068 | free(_err); |
| 2069 | free(project); |
| 2070 | free(query); |
| 2071 | return _res; |
| 2072 | } |
| 2073 | |
| 2074 | char *not_indexed = verify_project_indexed(store, project); |
| 2075 | if (not_indexed) { |
| 2076 | free(project); |
| 2077 | free(query); |
| 2078 | return not_indexed; |
| 2079 | } |
| 2080 | |
| 2081 | cbm_cypher_result_t result = {0}; |
| 2082 | int rc = cbm_cypher_execute(store, query, project, max_rows, &result); |
| 2083 | |
| 2084 | if (rc < 0) { |
| 2085 | char *err_msg = result.error ? result.error : "query execution failed"; |
| 2086 | char *resp = cbm_mcp_text_result(err_msg, true); |
| 2087 | cbm_cypher_result_free(&result); |
| 2088 | free(query); |
| 2089 | free(project); |
| 2090 | return resp; |
| 2091 | } |
| 2092 | |
| 2093 | yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL); |
| 2094 | yyjson_mut_val *root = yyjson_mut_obj(doc); |
| 2095 | yyjson_mut_doc_set_root(doc, root); |
| 2096 | |
| 2097 | /* columns */ |
| 2098 | yyjson_mut_val *cols = yyjson_mut_arr(doc); |
| 2099 | for (int i = 0; i < result.col_count; i++) { |
| 2100 | yyjson_mut_arr_add_str(doc, cols, result.columns[i]); |
| 2101 | } |
| 2102 | yyjson_mut_obj_add_val(doc, root, "columns", cols); |
| 2103 | |
| 2104 | /* rows */ |
| 2105 | yyjson_mut_val *rows = yyjson_mut_arr(doc); |
| 2106 | for (int r = 0; r < result.row_count; r++) { |
| 2107 | yyjson_mut_val *row = yyjson_mut_arr(doc); |
| 2108 | for (int c = 0; c < result.col_count; c++) { |
| 2109 | yyjson_mut_arr_add_str(doc, row, result.rows[r][c]); |
| 2110 | } |
| 2111 | yyjson_mut_arr_add_val(rows, row); |
| 2112 | } |
no test coverage detected