// pgConnect: Open the Postgres database. Returns any error // encountered during the open. func pgConnect() (string, error) { cfg, err := pgx.ParseURI(pgUrl) if err != nil { err = fmt.Errorf("Parse failure on Postgres URI %q: %v", pgUrl, err) return "", err } conn, err := pgx.Connect(cfg) if err != nil { err = fmt.Errorf("Couldn't connect to db at %q: %v", pgUrl, err) return "", err } pgConn = conn return pgUrl, nil }
// apply dataFunctions to the database. Each is applied in a // separate transaction, so later ones can rely on the effect of // earlier ones having been committed. func applyFunctions(fns []dataFunction) error { url := os.Getenv("DATABASE_URL") if url == "" { url = "postgres://localhost/susen?sslmode=disable" } // open the database, defer the close cfg, err := pgx.ParseURI(url) if err != nil { return err } conn, err := pgx.Connect(cfg) if err != nil { return err } defer conn.Close() // helper that runs each function inside a transaction, and // ensures that any problems are rolled back. runFunc := func(fn dataFunction) error { tx, err := conn.Begin() if err != nil { return err } defer func() { if e := recover(); e != nil { tx.Rollback() panic(e) } }() if err := fn(tx); err != nil { tx.Rollback() return err } return tx.Commit() } // run the functions for _, fn := range fns { if err := runFunc(fn); err != nil { return fmt.Errorf("%v failed: %v", fn, err) } } return nil }