pgservicefile.go (1936B)
1 // Package pgservicefile is a parser for PostgreSQL service files (e.g. .pg_service.conf). 2 package pgservicefile 3 4 import ( 5 "bufio" 6 "errors" 7 "fmt" 8 "io" 9 "os" 10 "strings" 11 ) 12 13 type Service struct { 14 Name string 15 Settings map[string]string 16 } 17 18 type Servicefile struct { 19 Services []*Service 20 servicesByName map[string]*Service 21 } 22 23 // GetService returns the named service. 24 func (sf *Servicefile) GetService(name string) (*Service, error) { 25 service, present := sf.servicesByName[name] 26 if !present { 27 return nil, errors.New("not found") 28 } 29 return service, nil 30 } 31 32 // ReadServicefile reads the file at path and parses it into a Servicefile. 33 func ReadServicefile(path string) (*Servicefile, error) { 34 f, err := os.Open(path) 35 if err != nil { 36 return nil, err 37 } 38 defer f.Close() 39 40 return ParseServicefile(f) 41 } 42 43 // ParseServicefile reads r and parses it into a Servicefile. 44 func ParseServicefile(r io.Reader) (*Servicefile, error) { 45 servicefile := &Servicefile{} 46 47 var service *Service 48 scanner := bufio.NewScanner(r) 49 lineNum := 0 50 for scanner.Scan() { 51 lineNum += 1 52 line := scanner.Text() 53 line = strings.TrimSpace(line) 54 55 if line == "" || strings.HasPrefix(line, "#") { 56 // ignore comments and empty lines 57 } else if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { 58 service = &Service{Name: line[1 : len(line)-1], Settings: make(map[string]string)} 59 servicefile.Services = append(servicefile.Services, service) 60 } else { 61 parts := strings.SplitN(line, "=", 2) 62 if len(parts) != 2 { 63 return nil, fmt.Errorf("unable to parse line %d", lineNum) 64 } 65 66 key := strings.TrimSpace(parts[0]) 67 value := strings.TrimSpace(parts[1]) 68 69 service.Settings[key] = value 70 } 71 } 72 73 servicefile.servicesByName = make(map[string]*Service, len(servicefile.Services)) 74 for _, service := range servicefile.Services { 75 servicefile.servicesByName[service.Name] = service 76 } 77 78 return servicefile, scanner.Err() 79 }