gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }