| 4151 | } |
| 4152 | |
| 4153 | static int arch_packages(cbm_store_t *s, const char *project, const char *path, |
| 4154 | cbm_architecture_info_t *out) { |
| 4155 | char norm[CBM_SZ_512]; |
| 4156 | char like[CBM_SZ_512]; |
| 4157 | bool scoped = arch_path_prepare(path, norm, sizeof(norm), like, sizeof(like)); |
| 4158 | char sqlbuf[ST_SQL_BUF]; |
| 4159 | const char *base = "SELECT n.name, COUNT(*) as cnt FROM nodes n " |
| 4160 | "WHERE n.project=?1 AND n.label='Package'"; |
| 4161 | if (scoped) { |
| 4162 | snprintf(sqlbuf, sizeof(sqlbuf), |
| 4163 | "%s AND (n.file_path = ?2 OR n.file_path LIKE ?3) " |
| 4164 | "GROUP BY n.name ORDER BY cnt DESC LIMIT 15", |
| 4165 | base); |
| 4166 | } else { |
| 4167 | snprintf(sqlbuf, sizeof(sqlbuf), "%s GROUP BY n.name ORDER BY cnt DESC LIMIT 15", base); |
| 4168 | } |
| 4169 | sqlite3_stmt *stmt = NULL; |
| 4170 | if (sqlite3_prepare_v2(s->db, sqlbuf, CBM_NOT_FOUND, &stmt, NULL) != SQLITE_OK) { |
| 4171 | store_set_error_sqlite(s, "arch_packages"); |
| 4172 | return CBM_STORE_ERR; |
| 4173 | } |
| 4174 | bind_text(stmt, SKIP_ONE, project); |
| 4175 | if (scoped) { |
| 4176 | arch_bind_path_scope(stmt, ST_COL_2, ST_COL_3, norm, like); |
| 4177 | } |
| 4178 | |
| 4179 | int cap = ST_INIT_CAP_16; |
| 4180 | int n = 0; |
| 4181 | cbm_package_summary_t *arr = calloc(cap, sizeof(cbm_package_summary_t)); |
| 4182 | while (sqlite3_step(stmt) == SQLITE_ROW) { |
| 4183 | if (n >= cap) { |
| 4184 | cap *= ST_GROWTH; |
| 4185 | arr = safe_realloc(arr, cap * sizeof(cbm_package_summary_t)); |
| 4186 | } |
| 4187 | arr[n].name = heap_strdup((const char *)sqlite3_column_text(stmt, 0)); |
| 4188 | arr[n].node_count = sqlite3_column_int(stmt, SKIP_ONE); |
| 4189 | n++; |
| 4190 | } |
| 4191 | sqlite3_finalize(stmt); |
| 4192 | |
| 4193 | /* Fallback: group by QN segment if no Package nodes */ |
| 4194 | if (n == 0) { |
| 4195 | free(arr); |
| 4196 | int rc = arch_packages_from_qn(s, project, path, &arr, &n); |
| 4197 | if (rc != CBM_STORE_OK) { |
| 4198 | return rc; |
| 4199 | } |
| 4200 | } |
| 4201 | |
| 4202 | out->packages = arr; |
| 4203 | out->package_count = n; |
| 4204 | return CBM_STORE_OK; |
| 4205 | } |
| 4206 | |
| 4207 | static void classify_layer(const char *pkg, int in, int out_deg, bool has_routes, |
| 4208 | bool has_entry_points, const char **layer, const char **reason) { |
no test coverage detected