#pragma once #include #include #include #include // Vista tabular respaldada por DuckDB (issue 0010). Cada nodo `Table` del // grafo apunta via metadata a un archivo `.duckdb` y a una tabla dentro // de el. Las filas viven en DuckDB; el grafo solo materializa las que // se "promueven" a entidades (issue 0011). // // Convencion de paths: `metadata.duckdb_path` es relativo al directorio del // proyecto (la raiz donde vive operations.db). El caller resuelve a path // absoluto antes de pasar a estas funciones. namespace ge { struct TablePageRow { std::string id; // valor del id_column en duckdb (key natural) std::vector values; // un valor por columna en `columns[]` std::string promoted_entity_id; // "" si la fila no esta promovida; sino, ops.entities.id }; // Crea o sobrescribe el nodo Table. Inserta una fila en operations.db con // type_ref='Table' y metadata apuntando al duckdb_path/table_name. Genera // un id propio. Devuelve false si SQLite falla o si los argumentos basicos // estan vacios. bool tableview_create(const char* ops_db, const char* name, const char* duckdb_path, const char* duck_table, const char* row_type, char* out_id, std::size_t out_id_n); // Cuenta las filas de duckdb_path/duck_table aplicando opcionalmente // `sql_filter` (clausula WHERE sin la palabra WHERE — vacio = sin filtro). // Devuelve false en error de IO/parse. bool tableview_count(const char* duckdb_path, const char* duck_table, const char* sql_filter, int64_t* out); // Devuelve una pagina ordenada por `id_column` ASC. Cada fila incluye los // valores de `columns` resueltos a string + el flag `promoted_entity_id` // computado via LEFT JOIN contra ops.entities (DuckDB attach a SQLite). // limit clampeado en [1,5000]. bool tableview_page(const char* duckdb_path, const char* duck_table, const char* id_column, const std::vector& columns, const char* sql_filter, const char* ops_db, // para LEFT JOIN de promovidas const char* row_type, // discriminante en ops.entities int64_t offset, int64_t limit, std::vector* out); // Smoke test: abre el .duckdb, corre `SELECT 42 AS x` y verifica que // devuelve la fila esperada. Devuelve true si todo OK. bool tableview_smoke_test(const char* duckdb_path); // Resuelve un path posiblemente relativo a la ubicacion de operations.db. // Si es absoluto (empieza por '/' o ':' en Windows), se devuelve // tal cual. std::string tableview_resolve_path(const char* ops_db, const char* maybe_rel); // Refresca el cache de conteos de filas por nodo Table. Lee // type_ref='Table' de operations.db, extrae metadata.duckdb_path/table_name, // llama a tableview_count y guarda el resultado indexado por // fnv1a64(entity_id) — la misma key que usa graph_sources al setear // node.user_data, asi que el render puede mirar directo por user_data. // Si una tabla falla, su entrada NO se inserta y se imprime un warning. struct TableCounts { // user_data hash (fnv1a64 del entity id) -> total filas tras filter_sql. // -1 indica error/ausencia. }; bool tableview_refresh_counts(const char* ops_db, std::unordered_map* out); } // namespace ge