package graph import ( "context" "fmt" "time" "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) // SessionManager manages Neo4j sessions with proper lifecycle management type SessionManager struct { driver neo4j.DriverWithContext database string config *Config } // NewSessionManager creates a new session manager func NewSessionManager(driver neo4j.DriverWithContext, database string, config *Config) *SessionManager { return &SessionManager{ driver: driver, database: database, config: config, } } // ExecuteRead executes a read transaction with proper error handling func (sm *SessionManager) ExecuteRead(ctx context.Context, fn func(neo4j.ManagedTransaction) (interface{}, error)) (interface{}, error) { // Create context with timeout queryCtx, cancel := context.WithTimeout(ctx, time.Duration(sm.config.QueryTimeoutSeconds)*time.Second) defer cancel() session := sm.driver.NewSession(queryCtx, neo4j.SessionConfig{ AccessMode: neo4j.AccessModeRead, DatabaseName: sm.database, }) defer session.Close(queryCtx) result, err := session.ExecuteRead(queryCtx, func(tx neo4j.ManagedTransaction) (interface{}, error) { return fn(tx) }) if err != nil { return nil, fmt.Errorf("read transaction failed: %w", err) } return result, nil } // ExecuteWrite executes a write transaction with proper error handling func (sm *SessionManager) ExecuteWrite(ctx context.Context, fn func(neo4j.ManagedTransaction) (interface{}, error)) (interface{}, error) { // Create context with timeout queryCtx, cancel := context.WithTimeout(ctx, time.Duration(sm.config.QueryTimeoutSeconds)*time.Second) defer cancel() session := sm.driver.NewSession(queryCtx, neo4j.SessionConfig{ AccessMode: neo4j.AccessModeWrite, DatabaseName: sm.database, }) defer session.Close(queryCtx) result, err := session.ExecuteWrite(queryCtx, func(tx neo4j.ManagedTransaction) (interface{}, error) { return fn(tx) }) if err != nil { return nil, fmt.Errorf("write transaction failed: %w", err) } return result, nil } // GetSession creates a new session (for advanced use cases) func (sm *SessionManager) GetSession(ctx context.Context, accessMode neo4j.AccessMode) neo4j.SessionWithContext { return sm.driver.NewSession(ctx, neo4j.SessionConfig{ AccessMode: accessMode, DatabaseName: sm.database, }) }