pgservice.go (1590B)
1 package pgservice 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 "strings" 8 9 "github.com/lib/pq/internal/pqutil" 10 ) 11 12 func FindService(path string, service string) (map[string]string, error) { 13 fp, err := os.Open(path) 14 if err != nil { 15 if pqutil.ErrNotExists(err) { 16 // libpq just returns "definition of service not found" if the 17 // default file doesn't exist, but IMO that's confusing. 18 return nil, fmt.Errorf("service file %q not found", path) 19 } 20 return nil, err 21 } 22 defer fp.Close() 23 24 var ( 25 scan = bufio.NewScanner(fp) 26 i int 27 ) 28 for scan.Scan() { 29 i++ 30 line := strings.TrimSpace(scan.Text()) 31 if line == "" || line[0] == '#' { 32 continue 33 } 34 35 // [service] header that we want. 36 if line[0] == '[' && line[len(line)-1] == ']' && strings.TrimSpace(line[1:len(line)-1]) == service { 37 opts := make(map[string]string) 38 for scan.Scan() { 39 i++ 40 line := strings.TrimSpace(scan.Text()) 41 if line == "" || line[0] == '#' { 42 continue 43 } 44 // Next header: our work here is done. 45 if line[0] == '[' && line[len(line)-1] == ']' { 46 return opts, nil 47 } 48 49 k, v, ok := strings.Cut(line, "=") 50 if !ok { 51 return nil, fmt.Errorf("line %d: missing '=' in %q", i, line) 52 } 53 k, v = strings.TrimSpace(k), strings.TrimSpace(v) 54 if k == "" { 55 return nil, fmt.Errorf("line %d: no value before '=' in %q", i, line) 56 } 57 opts[k] = v 58 } 59 if scan.Err() != nil { 60 return nil, scan.Err() 61 } 62 return opts, nil 63 } 64 } 65 if scan.Err() != nil { 66 return nil, scan.Err() 67 } 68 69 return nil, fmt.Errorf("definition of service %q not found", service) 70 }