| 7240 | } |
| 7241 | |
| 7242 | static int arch_clusters(cbm_store_t *s, const char *project, const char *path, |
| 7243 | cbm_architecture_info_t *out) { |
| 7244 | char norm[CBM_SZ_512]; |
| 7245 | char like[CBM_SZ_512]; |
| 7246 | bool scoped = arch_path_prepare(path, norm, sizeof(norm), like, sizeof(like)); |
| 7247 | char nsqlbuf[ST_SQL_BUF]; |
| 7248 | const char *nbase = "SELECT id, name, qualified_name, file_path FROM nodes " |
| 7249 | "WHERE project=?1 AND label IN (" CBM_SQL_CALLABLE_OR_TYPE_LABELS ")"; |
| 7250 | if (scoped) { |
| 7251 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s%s ORDER BY id LIMIT ?4", nbase, |
| 7252 | arch_path_scope_sql()); |
| 7253 | } else { |
| 7254 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s ORDER BY id LIMIT ?2", nbase); |
| 7255 | } |
| 7256 | sqlite3_stmt *st = NULL; |
| 7257 | if (sqlite3_prepare_v2(s->db, nsqlbuf, CBM_NOT_FOUND, &st, NULL) != SQLITE_OK) { |
| 7258 | return CBM_STORE_OK; /* clusters are best-effort */ |
| 7259 | } |
| 7260 | bind_text(st, SKIP_ONE, project); |
| 7261 | if (scoped) { |
| 7262 | arch_bind_path_scope(st, ST_COL_2, ST_COL_3, norm, like); |
| 7263 | sqlite3_bind_int(st, ST_COL_4, CBM_CLUSTER_NODE_CAP); |
| 7264 | } else { |
| 7265 | sqlite3_bind_int(st, CBM_SZ_2, CBM_CLUSTER_NODE_CAP); |
| 7266 | } |
| 7267 | int cap = ST_INIT_CAP_8; |
| 7268 | int n = 0; |
| 7269 | int64_t *ids = malloc((size_t)cap * sizeof(int64_t)); |
| 7270 | const char **names = malloc((size_t)cap * sizeof(char *)); |
| 7271 | const char **qns = malloc((size_t)cap * sizeof(char *)); |
| 7272 | int scan_rc29; |
| 7273 | while ((scan_rc29 = sqlite3_step(st)) == SQLITE_ROW) { |
| 7274 | if (n >= cap) { |
| 7275 | cap *= ST_GROWTH; |
| 7276 | ids = safe_realloc(ids, (size_t)cap * sizeof(int64_t)); |
| 7277 | names = safe_realloc(names, (size_t)cap * sizeof(char *)); |
| 7278 | qns = safe_realloc(qns, (size_t)cap * sizeof(char *)); |
| 7279 | } |
| 7280 | ids[n] = sqlite3_column_int64(st, 0); |
| 7281 | names[n] = heap_strdup((const char *)sqlite3_column_text(st, SKIP_ONE)); |
| 7282 | qns[n] = heap_strdup((const char *)sqlite3_column_text(st, CBM_SZ_2)); |
| 7283 | n++; |
| 7284 | } |
| 7285 | if (scan_rc29 != SQLITE_DONE) { /* SCANCHK:29:st */ |
| 7286 | store_set_error_sqlite(s, "row scan aborted"); |
| 7287 | sqlite3_finalize(st); |
| 7288 | for (int ci = 0; ci < n; ci++) { |
| 7289 | safe_str_free(&names[ci]); |
| 7290 | safe_str_free(&qns[ci]); |
| 7291 | } |
| 7292 | free(ids); |
| 7293 | free((void *)names); |
| 7294 | free((void *)qns); |
| 7295 | return CBM_STORE_ERR; |
| 7296 | } |
| 7297 | sqlite3_finalize(st); |
| 7298 | if (n < CBM_CLUSTER_MIN_MEMBERS) { |
| 7299 | for (int i = 0; i < n; i++) { |
no test coverage detected