package main import ( "flag" "fmt" "log" "os" "os/signal" "sync" "syscall" "gopkg.in/ini.v1" "gordenko.dev/dima/diploma/database" ) func main() { var ( logfile = os.Stdout iniFileName string ) flag.Usage = func() { fmt.Fprint(flag.CommandLine.Output(), helpMessage) fmt.Fprint(flag.CommandLine.Output(), configExample) fmt.Fprintf(flag.CommandLine.Output(), mainUsage, os.Args[0]) flag.PrintDefaults() } flag.StringVar(&iniFileName, "c", "database.ini", "path to *.ini config file") flag.Parse() config, err := loadConfig(iniFileName) if err != nil { log.Fatalln(err) } var ( exitCh = make(chan struct{}) wg = new(sync.WaitGroup) ) db, err := database.New(database.Options{ TCPPort: config.TcpPort, Dir: config.Dir, DatabaseName: config.DatabaseName, RedoDir: config.REDODir, Logfile: logfile, ExitCh: exitCh, WaitGroup: wg, }) if err != nil { log.Fatalf("database.New: %s\n", err) } go func() { err = db.ListenAndServe() if err != nil { log.Fatalln(err) } }() wg.Add(1) fmt.Fprintf(logfile, "database %q started on port %d.\n", config.DatabaseName, config.TcpPort) fmt.Fprintln(logfile, config) sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) <-sigs close(exitCh) wg.Wait() fmt.Fprintln(logfile, "database stopped.") } // config file const mainUsage = `Usage: %s -c path/to/config.ini ` const helpMessage = `Diploma project. Database. Version: 1.0 created by Dmytro Gordenko, 1.e4.kc6@gmail.com ` const configExample = ` database.ini example: tcpPort = 12345 dir = ../../datadir redoDir = ../../datadir databaseName = test ` type Config struct { TcpPort int Dir string REDODir string DatabaseName string } func (s Config) String() string { return fmt.Sprintf(`starting options: tcpPort = %d dir = %s redoDir = %s databaseName = %s `, s.TcpPort, s.Dir, s.REDODir, s.DatabaseName) } func loadConfig(iniFileName string) (_ Config, err error) { file, err := ini.Load(iniFileName) if err != nil { return } conf := Config{} top := file.Section("") conf.TcpPort, err = top.Key("tcpPort").Int() if err != nil { err = fmt.Errorf("'tcpPort' option is required in config file") return } conf.Dir = top.Key("dir").String() conf.REDODir = top.Key("redoDir").String() conf.DatabaseName = top.Key("databaseName").String() return conf, nil }