---
name: detect_cycle
kind: function
lang: go
domain: core
version: "1.0.0"
purity: impure
signature: "func DetectCycle(conn *sql.DB, table, fromCol, toCol, filterCol, fromNode, toNode string) error"
description: "Detecta ciclos en un grafo dirigido almacenado en SQLite usando BFS antes de insertar una arista."
tags: [graph, cycle, bfs, sqlite, validation]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: ["database/sql"]
params:
  - name: conn
    desc: "conexión abierta a base de datos SQLite"
  - name: table
    desc: "nombre de la tabla que almacena el grafo"
  - name: fromCol
    desc: "nombre de la columna que contiene el nodo origen de cada arista"
  - name: toCol
    desc: "nombre de la columna que contiene el nodo destino de cada arista"
  - name: filterCol
    desc: "nombre de columna opcional para filtrar aristas semánticas; si es vacío, se consideran todas las aristas"
  - name: fromNode
    desc: "nodo origen de la nueva arista a validar"
  - name: toNode
    desc: "nodo destino de la nueva arista a validar"
output: "error si agregaría un ciclo; nil si no hay ciclo"
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/detect_cycle.go"
---

## Ejemplo

```go
// Verificar si agregar A -> B crearia un ciclo en la tabla "relations"
err := DetectCycle(db, "relations", "from_entity", "to_entity", "via", "A", "B")
if err != nil {
    // ciclo detectado
}

// Sin filtro — considerar todas las aristas
err = DetectCycle(db, "edges", "source", "target", "", "X", "Y")
```

## Notas

Usa BFS desde toNode siguiendo aristas existentes. Si alcanza fromNode, la nueva arista crearia un ciclo. El parametro filterCol permite ignorar aristas semanticas (no causales) — pasar "" para considerar todas.
