@@ -17,6 +17,7 @@ import (
1717)
1818
1919type migrationStatus = string
20+ type SslMode = string
2021
2122const (
2223 EnvDatabaseAddress = "DB_ADDRESS"
@@ -31,7 +32,26 @@ const (
3132 EnvDatabaseName = "DB_NAME"
3233 EnvDatabaseNameDefault = "postgres"
3334
34- EnvMigrationsEnabled = "DB_MIGRATIONS_ENABLED"
35+ EnvDatabaseSchema = "DB_SCHEMA"
36+ EnvDatabaseSchemaDefault = ""
37+
38+ EnvDatabaseMigrationSchema = "DB_MIGRATION_SCHEMA"
39+ EnvDatabaseMigrationSchemaDefault = ""
40+
41+ EnvDatabaseSslMode = "DB_SSL_MODE"
42+ EnvDatabaseSslModeDefault = SslModeDisable
43+
44+ EnvDatabaseSslRootCert = "DB_SSL_ROOT_CERT"
45+ EnvDatabaseSslRootCertDefault = ""
46+
47+ EnvDatabaseSslCert = "DB_SSL_CERT"
48+ EnvDatabaseSslCertDefault = ""
49+
50+ EnvDatabaseSslKey = "DB_SSL_KEY"
51+ EnvDatabaseSslKeyDefault = ""
52+
53+ EnvMigrationsEnabled = "DB_MIGRATIONS_ENABLED"
54+ EnvMigrationsEnabledDefault = true
3555
3656 EnvChangelogSchema = "DB_CHANGELOG_SCHEMA"
3757 EnvChangelogSchemaDefault = "public"
@@ -45,13 +65,26 @@ const (
4565 statusCompleted migrationStatus = "COMPLETED"
4666 statusError migrationStatus = "ERROR"
4767 statusNew migrationStatus = "NEW"
68+
69+ SslModeDisable SslMode = "disable"
70+ SslModeRequire SslMode = "require"
71+ SslModeVerifyFull SslMode = "verify-full"
72+ SslModeVerifyCA SslMode = "verify-ca"
73+ SslModePrefer SslMode = "prefer"
74+ SslModeAllow SslMode = "allow"
4875)
4976
5077type Configuration struct {
51- Address string
52- Username string
53- Password string
54- Name string
78+ Address string
79+ Username string
80+ Password string
81+ Name string
82+ Schema string
83+ MigrationSchema string
84+ SslMode SslMode
85+ SslRootCert string
86+ SslCert string
87+ SslKey string
5588
5689 MigrationsEnabled bool
5790 ChangelogSchema string
@@ -76,10 +109,34 @@ func CreateConfigurationFromEnv() Configuration {
76109 if name == "" {
77110 name = EnvDatabaseNameDefault
78111 }
112+ schema := os .Getenv (EnvDatabaseSchema )
113+ if schema == "" {
114+ schema = EnvDatabaseSchemaDefault
115+ }
116+ migrationSchema := os .Getenv (EnvDatabaseMigrationSchema )
117+ if migrationSchema == "" {
118+ migrationSchema = EnvDatabaseMigrationSchemaDefault
119+ }
120+ sslMode := os .Getenv (EnvDatabaseSslMode )
121+ if sslMode == "" {
122+ sslMode = EnvDatabaseSslModeDefault
123+ }
124+ sslRootCert := os .Getenv (EnvDatabaseSslRootCert )
125+ if sslRootCert == "" {
126+ sslRootCert = EnvDatabaseSslRootCertDefault
127+ }
128+ sslCert := os .Getenv (EnvDatabaseSslCert )
129+ if sslCert == "" {
130+ sslCert = EnvDatabaseSslCertDefault
131+ }
132+ sslKey := os .Getenv (EnvDatabaseSslKey )
133+ if sslKey == "" {
134+ sslKey = EnvDatabaseSslKeyDefault
135+ }
79136
80137 migrationsEnabled , err := strconv .ParseBool (os .Getenv (EnvMigrationsEnabled ))
81138 if err != nil {
82- migrationsEnabled = false
139+ migrationsEnabled = EnvMigrationsEnabledDefault
83140 }
84141
85142 changelogSchema := os .Getenv (EnvChangelogSchema )
@@ -99,6 +156,12 @@ func CreateConfigurationFromEnv() Configuration {
99156 Username : username ,
100157 Password : password ,
101158 Name : name ,
159+ Schema : schema ,
160+ MigrationSchema : migrationSchema ,
161+ SslMode : sslMode ,
162+ SslRootCert : sslRootCert ,
163+ SslCert : sslCert ,
164+ SslKey : sslKey ,
102165 MigrationsEnabled : migrationsEnabled ,
103166 ChangelogSchema : changelogSchema ,
104167 ChangelogTable : changelogTable ,
@@ -107,6 +170,9 @@ func CreateConfigurationFromEnv() Configuration {
107170}
108171
109172func (c Configuration ) schemaTable () string {
173+ if c .ChangelogSchema == "" {
174+ return c .ChangelogTable
175+ }
110176 return c .ChangelogSchema + "." + c .ChangelogTable
111177}
112178
@@ -116,7 +182,16 @@ func Connect() (*pgxpool.Pool, error) {
116182}
117183
118184func ConnectWithConfig (c Configuration ) (* pgxpool.Pool , error ) {
119- url := fmt .Sprintf ("postgres://%s:%s@%s/%s?sslmode=disable" , c .Username , c .Password , c .Address , c .Name )
185+ url := fmt .Sprintf ("postgres://%s:%s@%s/%s?sslmode=%s" , c .Username , c .Password , c .Address , c .Name , c .SslMode )
186+ if c .SslRootCert != "" {
187+ url += "&sslrootcert=" + c .SslRootCert
188+ }
189+ if c .SslCert != "" {
190+ url += "&sslcert=" + c .SslCert
191+ }
192+ if c .SslKey != "" {
193+ url += "&sslkey=" + c .SslKey
194+ }
120195 config , err := pgxpool .ParseConfig (url )
121196 if err != nil {
122197 return nil , err
@@ -132,6 +207,12 @@ func ConnectWithConfig(c Configuration) (*pgxpool.Pool, error) {
132207 return nil , err
133208 }
134209 }
210+ if c .Schema != "" {
211+ _ , err := pool .Exec (context .Background (), "SET search_path TO " + c .Schema )
212+ if err != nil {
213+ return nil , err
214+ }
215+ }
135216 return pool , nil
136217}
137218
@@ -176,6 +257,22 @@ func (dbm *databaseMigrator) Migrate() error {
176257 if err != nil {
177258 return err
178259 }
260+ if dbm .Configuration .MigrationSchema != "" {
261+ exists , err := dbm .schemaExists (dbm .Configuration .MigrationSchema )
262+ if err != nil {
263+ return err
264+ }
265+ if ! exists {
266+ err = dbm .createSchema (dbm .Configuration .MigrationSchema )
267+ if err != nil {
268+ return err
269+ }
270+ }
271+ _ , err = tx .Exec (context .Background (), "SET search_path TO " + dbm .Configuration .MigrationSchema )
272+ if err != nil {
273+ return err
274+ }
275+ }
179276 for _ , migration := range migrations {
180277 err = dbm .applyMigration (migration , tx )
181278 if err != nil {
@@ -336,6 +433,17 @@ func (dbm *databaseMigrator) initChangelogTable() error {
336433 return nil
337434}
338435
436+ func (dbm * databaseMigrator ) schemaExists (schema string ) (bool , error ) {
437+ querySql := "SELECT EXISTS (SELECT FROM information_schema.schemata WHERE schemata.schema_name = $1)"
438+ row := dbm .PgxPool .QueryRow (context .Background (), querySql , schema )
439+ var exists bool
440+ err := row .Scan (& exists )
441+ if err != nil {
442+ return false , err
443+ }
444+ return exists , nil
445+ }
446+
339447func (dbm * databaseMigrator ) tableExists (schema string , table string ) (bool , error ) {
340448 //goland:noinspection SqlResolve
341449 querySql := "SELECT EXISTS (SELECT FROM pg_tables WHERE schemaname = $1 AND tablename = $2)"
@@ -348,6 +456,14 @@ func (dbm *databaseMigrator) tableExists(schema string, table string) (bool, err
348456 return exists , nil
349457}
350458
459+ func (dbm * databaseMigrator ) createSchema (schema string ) error {
460+ _ , err := dbm .PgxPool .Exec (context .Background (), "CREATE SCHEMA IF NOT EXISTS " + schema )
461+ if err != nil {
462+ return err
463+ }
464+ return nil
465+ }
466+
351467func (dbm * databaseMigrator ) createChangelogTable () error {
352468 tx , err := dbm .PgxPool .Begin (context .Background ())
353469 if err != nil {
0 commit comments