package store import ( "database/sql" ) // Route is one "_url" line attached to a sandbox. The agent // pushes the whole set to the gateway by replacing any matching lines // in the gateway's config.php. type Route struct { ID string `json:"id"` SandboxID string `json:"sandboxId"` Key string `json:"key"` Value string `json:"value"` TargetOCP bool `json:"targetOcp"` } // SetRoutes atomically replaces the routing table for a sandbox. The // gateway agent's "push" frame is the whole set. func (s *Store) SetRoutes(sandboxID string, routes []Route) error { tx, err := s.db.Begin() if err != nil { return err } defer tx.Rollback() if _, err := tx.Exec(`DELETE FROM routes WHERE sandbox_id=?`, sandboxID); err != nil { return err } for i := range routes { r := routes[i] r.SandboxID = sandboxID if r.ID == "" { r.ID = sandboxID + "-" + r.Key } if _, err := tx.Exec( `INSERT INTO routes(id, sandbox_id, key, value, target_ocp) VALUES(?,?,?,?,?)`, r.ID, r.SandboxID, r.Key, r.Value, boolInt(r.TargetOCP)); err != nil { return err } } return tx.Commit() } // ListRoutes returns the routes for one sandbox. func (s *Store) ListRoutes(sandboxID string) ([]Route, error) { rows, err := s.db.Query( `SELECT id, sandbox_id, key, COALESCE(value,''), target_ocp FROM routes WHERE sandbox_id=? ORDER BY key`, sandboxID) if err != nil { return nil, err } defer rows.Close() var out []Route for rows.Next() { var r Route var targetOCP int if err := rows.Scan(&r.ID, &r.SandboxID, &r.Key, &r.Value, &targetOCP); err != nil { return nil, err } r.TargetOCP = targetOCP == 1 out = append(out, r) } return out, rows.Err() } // GetRoute returns one route by sandbox+key, or ErrNotFound. func (s *Store) GetRoute(sandboxID, key string) (*Route, error) { row := s.db.QueryRow( `SELECT id, sandbox_id, key, COALESCE(value,''), target_ocp FROM routes WHERE sandbox_id=? AND key=?`, sandboxID, key) var r Route var targetOCP int err := row.Scan(&r.ID, &r.SandboxID, &r.Key, &r.Value, &targetOCP) if err == sql.ErrNoRows { return nil, ErrNotFound } if err != nil { return nil, err } r.TargetOCP = targetOCP == 1 return &r, nil }