-
Notifications
You must be signed in to change notification settings - Fork 1
/
psql.go
131 lines (108 loc) · 2.86 KB
/
psql.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package storage
import (
"context"
"errors"
"fmt"
db "github.com/go-ozzo/ozzo-dbx"
_ "github.com/lib/pq"
"github.com/webtech-fmi/phonebook/backend/go/infrastructure/log"
)
// psqlConfiguration for creating a database storage
type psqlConfiguration struct {
Host string
Port int
DBName string `mapsstructure:"dbname"`
Username string
Password string
Schema string
MaxIdle int `mapstructure:"max_idle"`
MaxOpen int `mapstructure:"max_open"`
SSLmode string `mapstructure:"sslmode"`
Debug bool
}
func loadDBConfiguration(options map[string]interface{}) (*psqlConfiguration, error) {
host, ok := options["host"].(string)
if !ok {
return nil, errors.New("invalid type for DB host")
}
port, ok := options["port"].(int)
if !ok {
return nil, errors.New("invalid type for DB port")
}
dbName, ok := options["dbname"].(string)
if !ok {
return nil, errors.New("invalid type for DB name")
}
username, ok := options["username"].(string)
if !ok {
return nil, errors.New("invalid type for DB username")
}
password, ok := options["password"].(string)
if !ok {
return nil, errors.New("invalid type for DB password")
}
maxIdle, ok := options["max_idle"].(int)
if !ok {
return nil, errors.New("invalid type for DB max_idle")
}
maxOpen, ok := options["max_open"].(int)
if !ok {
return nil, errors.New("invalid type for DB max_open")
}
debug, ok := options["debug"].(bool)
if !ok {
return nil, errors.New("invalid type for DB debug")
}
ssl, ok := options["sslmode"].(string)
if !ok {
return nil, errors.New("invalid type for DB sslmode")
}
return &psqlConfiguration{
Host: host,
Port: port,
DBName: dbName,
Username: username,
Password: password,
MaxIdle: maxIdle,
MaxOpen: maxOpen,
Debug: debug,
SSLmode: ssl,
}, nil
}
// Connection pool + logger
type PSQL struct {
DB *db.DB
Logger *log.Logger
}
func NewPSQL(ctx context.Context, options map[string]interface{}, logger *log.Logger) (*PSQL, error) {
dbConfig, err := loadDBConfiguration(options)
if err != nil {
return nil, fmt.Errorf("could not initialize DB storage with error: [%s]", err)
}
settings := fmt.Sprintf(
"user=%s password=%s host=%s port=%d dbname=%s sslmode=%s",
dbConfig.Username,
dbConfig.Password,
dbConfig.Host,
dbConfig.Port,
dbConfig.DBName,
dbConfig.SSLmode,
)
cp, err := db.Open("postgres", settings)
if err != nil {
logger.Fatal().Err(err).Msg("Could not instantiate the database connection pool")
}
err = cp.DB().Ping()
if err != nil {
logger.Fatal().Err(err).Msg("Database unreachable")
}
go func() error {
logger.Info().Msg("[PSQL] Starting cleanup database hook...")
<-ctx.Done()
logger.Info().Msg("[PSQL] Cleaning up the database...")
return cp.Close()
}()
cp.DB().SetMaxOpenConns(dbConfig.MaxOpen)
cp.DB().SetMaxIdleConns(dbConfig.MaxIdle)
return &PSQL{DB: cp, Logger: logger}, nil
}