package main import ( "context" "database/sql" "flag" "os" "time" ) type Config struct { Port int Root string DB struct { Scheme string Conn string } } func NewConfig() (Config, error) { var c Config fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError) fs.IntVar(&c.Port, "p", 8080, "port") fs.StringVar(&c.Root, "r", "/tmp/", "static file root") fs.StringVar(&c.DB.Scheme, "db-scheme", "sqlite", "sql scheme") fs.StringVar(&c.DB.Conn, "db-conn", "/tmp/out.sql", "sql conn string") err := fs.Parse(os.Args[1:]) return c, err } type DB struct { scheme string conn string } func NewDB(ctx context.Context, scheme, conn string) (DB, error) { ctx, can := context.WithTimeout(ctx, time.Second*10) defer can() db := DB{ scheme: scheme, conn: conn, } sql, err := db.dial(ctx) if sql != nil { sql.Close() } return db, err } func (db DB) dial(ctx context.Context) (*sql.DB, error) { c, err := sql.Open(db.scheme, db.conn) if err != nil { return nil, err } if err := c.PingContext(ctx); err != nil { return nil, err } return c, nil }