Generic: find multiple nodes by a single-column filter. */
| 1966 | |
| 1967 | /* Generic: find multiple nodes by a single-column filter. */ |
| 1968 | static int find_nodes_generic(cbm_store_t *s, sqlite3_stmt **slot, const char *sql, |
| 1969 | const char *project, const char *val, cbm_node_t **out, int *count) { |
| 1970 | if (!s || !s->db) { |
| 1971 | *out = NULL; |
| 1972 | *count = 0; |
| 1973 | return CBM_STORE_ERR; |
| 1974 | } |
| 1975 | sqlite3_stmt *stmt = prepare_cached(s, slot, sql); |
| 1976 | if (!stmt) { |
| 1977 | return CBM_STORE_ERR; |
| 1978 | } |
| 1979 | |
| 1980 | bind_text(stmt, SKIP_ONE, project); |
| 1981 | bind_text(stmt, ST_COL_2, val); |
| 1982 | |
| 1983 | int cap = ST_INIT_CAP_16; |
| 1984 | int n = 0; |
| 1985 | cbm_node_t *arr = malloc(cap * sizeof(cbm_node_t)); |
| 1986 | |
| 1987 | int scan_rc3; |
| 1988 | while ((scan_rc3 = sqlite3_step(stmt)) == SQLITE_ROW) { |
| 1989 | if (n >= cap) { |
| 1990 | cap *= ST_GROWTH; |
| 1991 | arr = safe_realloc(arr, cap * sizeof(cbm_node_t)); |
| 1992 | } |
| 1993 | scan_node(stmt, &arr[n]); |
| 1994 | n++; |
| 1995 | } |
| 1996 | if (scan_rc3 != SQLITE_DONE) { /* SCANCHK:3:stmt */ |
| 1997 | store_set_error_sqlite(s, "row scan aborted"); |
| 1998 | cbm_store_free_nodes(arr, n); |
| 1999 | *out = NULL; |
| 2000 | *count = 0; |
| 2001 | return CBM_STORE_ERR; |
| 2002 | } |
| 2003 | |
| 2004 | *out = arr; |
| 2005 | *count = n; |
| 2006 | return CBM_STORE_OK; |
| 2007 | } |
| 2008 | |
| 2009 | int cbm_store_find_nodes_by_name(cbm_store_t *s, const char *project, const char *name, |
| 2010 | cbm_node_t **out, int *count) { |
no test coverage detected