Skip to content

Instantly share code, notes, and snippets.

@kohenkatz
Last active January 3, 2021 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kohenkatz/9b4ac74dc7fb10fb4384bf2cb84845f0 to your computer and use it in GitHub Desktop.
Save kohenkatz/9b4ac74dc7fb10fb4384bf2cb84845f0 to your computer and use it in GitHub Desktop.
Using jackc/pgx to automatically send queries to the primary server
DATABASE_URL="host=db001,db002 port=5432 database=mydatabase user=myuser password=mypassword"
# The two `host` entries above are a primary and a replica in a cluster
# Change the order of the `host` entries and you will see that it always uses the primary
package main
import (
"context"
"errors"
"fmt"
"os"
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4/pgxpool"
_ "github.com/joho/godotenv/autoload"
)
func main() {
dbConfig, err := pgxpool.ParseConfig(os.Getenv("DATABASE_URL"))
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to parse DATABASE_URL: %v\n", err)
os.Exit(1)
}
dbConfig.ConnConfig.Config.ValidateConnect = func(ctx context.Context, pgconn *pgconn.PgConn) error {
query := pgconn.Exec(context.Background(), "SELECT pg_is_in_recovery()")
result, err := query.ReadAll()
if err != nil {
return err
}
row := result[0].Rows[0]
field := row[0]
if rune(field[0]) == 't' {
return errors.New("Server is in recovery mode")
}
return nil
}
dbPool, err := pgxpool.ConnectConfig(context.Background(), dbConfig)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
os.Exit(1)
}
defer dbPool.Close()
var status string
err = dbPool.QueryRow(context.Background(), `select 'this server is ' || (CASE pg_is_in_recovery() WHEN TRUE THEN 'replica' ELSE 'primary' END)`).Scan(&status)
if err != nil {
fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
os.Exit(1)
}
fmt.Println(status)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment