package lib import ( "database/sql" "errors" "fmt" _ "github.com/mattn/go-sqlite3" ) const tokenMapSchema = ` CREATE TABLE IF NOT EXISTS token_map ( token TEXT PRIMARY KEY, vault_id INTEGER NOT NULL ); ` // TokenMap wraps node.db for token→vault_id lookups. type TokenMap struct { db *sql.DB } // OpenTokenMap opens (or creates) the node.db token registry. func OpenTokenMap(dbPath string) (*TokenMap, error) { conn, err := sql.Open("sqlite3", dbPath+"?_journal_mode=WAL&_busy_timeout=5000") if err != nil { return nil, fmt.Errorf("open token map: %w", err) } if _, err := conn.Exec(tokenMapSchema); err != nil { conn.Close() return nil, fmt.Errorf("migrate token map: %w", err) } return &TokenMap{db: conn}, nil } // Close closes the token map database. func (tm *TokenMap) Close() error { return tm.db.Close() } // Register adds a token→vault_id mapping. func (tm *TokenMap) Register(token string, vaultID int64) error { _, err := tm.db.Exec( `INSERT OR REPLACE INTO token_map (token, vault_id) VALUES (?, ?)`, token, vaultID, ) return err } // Lookup resolves a token to a vault_id. Returns 0, nil if not found. func (tm *TokenMap) Lookup(token string) (int64, error) { var vaultID int64 err := tm.db.QueryRow(`SELECT vault_id FROM token_map WHERE token = ?`, token).Scan(&vaultID) if errors.Is(err, sql.ErrNoRows) { return 0, nil } return vaultID, err } // Remove deletes a token mapping. func (tm *TokenMap) Remove(token string) error { _, err := tm.db.Exec(`DELETE FROM token_map WHERE token = ?`, token) return err } // RemoveAllForVault removes all tokens for a vault. func (tm *TokenMap) RemoveAllForVault(vaultID int64) error { _, err := tm.db.Exec(`DELETE FROM token_map WHERE vault_id = ?`, vaultID) return err }