Adding 'github.com/lib/pq' library to use our PostgreSQL database. Updating our main.go file to establish a connection with the database pool.
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 53s

This commit is contained in:
Maxime Delporte
2025-10-28 17:02:36 +01:00
parent 84741de60e
commit 8cdf3c7ada
3 changed files with 58 additions and 2 deletions

View File

@@ -1,12 +1,17 @@
package main package main
import ( import (
"context"
"database/sql"
"flag" "flag"
"fmt" "fmt"
"log/slog" "log/slog"
"net/http" "net/http"
"os" "os"
"time" "time"
// Import the pq driver so that it can register itself with the database/sql package. Note that we alias this import to the blank identifier, to stop the Go compiler complaining that the package isn't being used.
_ "github.com/lib/pq"
) )
/* /*
@@ -22,9 +27,13 @@ For now, the only configuration settings will be the network port that we want t
and the name of the current operating environment for the application (development, staging, production, etc.) and the name of the current operating environment for the application (development, staging, production, etc.)
We'll read in the configuration settings from command-line flags when the application starts. We'll read in the configuration settings from command-line flags when the application starts.
*/ */
// Add a db struct field to hold the configuration settings for our database connection pool. For now, this only holds the DSN, which we will read in from a command-line flag.
type config struct { type config struct {
port int port int
env string env string
db struct {
dsn string
}
} }
/* /*
@@ -46,11 +55,29 @@ func main() {
*/ */
flag.IntVar(&cfg.port, "port", 4000, "API server port") flag.IntVar(&cfg.port, "port", 4000, "API server port")
flag.StringVar(&cfg.env, "env", "development", "Environment (development|staging|production") flag.StringVar(&cfg.env, "env", "development", "Environment (development|staging|production")
// Read the DSN value from the db-dsn command-line flag into the config struct. We default to using our development DSN if no flag is provided.
// Use the value of the GREENLIGHT_DB_DSN environment variable as the default value for our db-dsn command-line flag.
flag.StringVar(&cfg.db.dsn, "db-dsn", os.Getenv("GREENLIGHT_DB_DSN"), "PostgreSQL DSN")
flag.Parse() flag.Parse()
// Initialize a new structured logger which writes log entries to standard out stream. // Initialize a new structured logger which writes log entries to standard out stream.
logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
// Call the openDB() helper function to create the connection pool, passing in the config struct. If this returns an error, we log it and exit the application immediately.
db, err := openDB(cfg)
if err != nil {
logger.Error(err.Error())
os.Exit(1)
}
// Defer a call to db.Close() so that the connection pool is closed before the main() function exists
defer db.Close()
// Also log a message to say that the connection pool has been successfully established.
logger.Info("database connection pool established")
// Declare an instance of the application struct, containing the config struct and the logger. // Declare an instance of the application struct, containing the config struct and the logger.
app := &application{ app := &application{
config: cfg, config: cfg,
@@ -74,9 +101,33 @@ func main() {
// Start the HTTP server. // Start the HTTP server.
logger.Info("starting server", "addr", srv.Addr, "env", cfg.env) logger.Info("starting server", "addr", srv.Addr, "env", cfg.env)
err := srv.ListenAndServe() // Because the err variable is now already declared in the code above, we need to user = operator here, instead of the := operator.
err = srv.ListenAndServe()
if err != nil { if err != nil {
logger.Error(err.Error()) logger.Error(err.Error())
os.Exit(1) os.Exit(1)
} }
} }
// openDB() function returns a sql.DB connection pool.
func openDB(cfg config) (*sql.DB, error) {
// Use sql.Open() to create an empty connection pool, using the DSN from the config struct.
db, err := sql.Open("postgres", cfg.db.dsn)
if err != nil {
return nil, err
}
// Create a context with a 5-second timeout deadline.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Use PingContext() to establish a new connection to the database, passing in the context we created above as parameter. If the connection couldn't be established successfully within the 5-second deadline, then this will return an error. If we get this error, or any other, we close the connection pool and return the error.
err = db.PingContext(ctx)
if err != nil {
db.Close()
return nil, err
}
// Return the sql.DB connection pool.
return db, nil
}

5
go.mod
View File

@@ -2,4 +2,7 @@ module greenlight.craftr.fr
go 1.25.1 go 1.25.1
require github.com/julienschmidt/httprouter v1.3.0 // indirect require (
github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/lib/pq v1.10.9 // indirect
)

2
go.sum
View File

@@ -1,2 +1,4 @@
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=