| 7341 | } |
| 7342 | |
| 7343 | static int arch_clusters(cbm_store_t *s, const char *project, const char *path, |
| 7344 | cbm_architecture_info_t *out) { |
| 7345 | char norm[CBM_SZ_512]; |
| 7346 | char like[CBM_SZ_512]; |
| 7347 | bool scoped = arch_path_prepare(path, norm, sizeof(norm), like, sizeof(like)); |
| 7348 | char nsqlbuf[ST_SQL_BUF]; |
| 7349 | const char *nbase = "SELECT id, name, qualified_name, file_path FROM nodes " |
| 7350 | "WHERE project=?1 AND label IN (" CBM_SQL_CALLABLE_OR_TYPE_LABELS ")"; |
| 7351 | if (scoped) { |
| 7352 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s%s ORDER BY id LIMIT ?4", nbase, |
| 7353 | arch_path_scope_sql()); |
| 7354 | } else { |
| 7355 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s ORDER BY id LIMIT ?2", nbase); |
| 7356 | } |
| 7357 | sqlite3_stmt *st = NULL; |
| 7358 | if (sqlite3_prepare_v2(s->db, nsqlbuf, CBM_NOT_FOUND, &st, NULL) != SQLITE_OK) { |
| 7359 | return CBM_STORE_OK; /* clusters are best-effort */ |
| 7360 | } |
| 7361 | bind_text(st, SKIP_ONE, project); |
| 7362 | if (scoped) { |
| 7363 | arch_bind_path_scope(st, ST_COL_2, ST_COL_3, norm, like); |
| 7364 | sqlite3_bind_int(st, ST_COL_4, CBM_CLUSTER_NODE_CAP); |
| 7365 | } else { |
| 7366 | sqlite3_bind_int(st, CBM_SZ_2, CBM_CLUSTER_NODE_CAP); |
| 7367 | } |
| 7368 | int cap = ST_INIT_CAP_8; |
| 7369 | int n = 0; |
| 7370 | int64_t *ids = malloc((size_t)cap * sizeof(int64_t)); |
| 7371 | const char **names = malloc((size_t)cap * sizeof(char *)); |
| 7372 | const char **qns = malloc((size_t)cap * sizeof(char *)); |
| 7373 | int scan_rc29; |
| 7374 | while ((scan_rc29 = sqlite3_step(st)) == SQLITE_ROW) { |
| 7375 | if (n >= cap) { |
| 7376 | cap *= ST_GROWTH; |
| 7377 | ids = safe_realloc(ids, (size_t)cap * sizeof(int64_t)); |
| 7378 | names = safe_realloc(names, (size_t)cap * sizeof(char *)); |
| 7379 | qns = safe_realloc(qns, (size_t)cap * sizeof(char *)); |
| 7380 | } |
| 7381 | ids[n] = sqlite3_column_int64(st, 0); |
| 7382 | names[n] = heap_strdup((const char *)sqlite3_column_text(st, SKIP_ONE)); |
| 7383 | qns[n] = heap_strdup((const char *)sqlite3_column_text(st, CBM_SZ_2)); |
| 7384 | n++; |
| 7385 | } |
| 7386 | if (scan_rc29 != SQLITE_DONE) { /* SCANCHK:29:st */ |
| 7387 | store_set_error_sqlite(s, "row scan aborted"); |
| 7388 | sqlite3_finalize(st); |
| 7389 | for (int ci = 0; ci < n; ci++) { |
| 7390 | safe_str_free(&names[ci]); |
| 7391 | safe_str_free(&qns[ci]); |
| 7392 | } |
| 7393 | free(ids); |
| 7394 | free((void *)names); |
| 7395 | free((void *)qns); |
| 7396 | return CBM_STORE_ERR; |
| 7397 | } |
| 7398 | sqlite3_finalize(st); |
| 7399 | if (n < CBM_CLUSTER_MIN_MEMBERS) { |
| 7400 | for (int i = 0; i < n; i++) { |
no test coverage detected