Skip to content

Commit c00e987

Browse files
authored
feat: make encoding configurable in initdb (#133)
1 parent 74c945b commit c00e987

5 files changed

+71
-8
lines changed

config.go

+7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Config struct {
1919
dataPath string
2020
binariesPath string
2121
locale string
22+
encoding string
2223
startParameters map[string]string
2324
binaryRepositoryURL string
2425
startTimeout time.Duration
@@ -110,6 +111,12 @@ func (c Config) Locale(locale string) Config {
110111
return c
111112
}
112113

114+
// Encoding sets the default character set for initdb
115+
func (c Config) Encoding(encoding string) Config {
116+
c.encoding = encoding
117+
return c
118+
}
119+
113120
// StartParameters sets run-time parameters when starting Postgres (passed to Postgres via "-c").
114121
//
115122
// These parameters can be used to override the default configuration values in postgres.conf such

embedded_postgres.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (ep *EmbeddedPostgres) cleanDataDirectoryAndInit() error {
167167
return fmt.Errorf("unable to clean up data directory %s with error: %s", ep.config.dataPath, err)
168168
}
169169

170-
if err := ep.initDatabase(ep.config.binariesPath, ep.config.runtimePath, ep.config.dataPath, ep.config.username, ep.config.password, ep.config.locale, ep.syncedLogger.file); err != nil {
170+
if err := ep.initDatabase(ep.config.binariesPath, ep.config.runtimePath, ep.config.dataPath, ep.config.username, ep.config.password, ep.config.locale, ep.config.encoding, ep.syncedLogger.file); err != nil {
171171
return err
172172
}
173173

embedded_postgres_test.go

+33-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func Test_ErrorWhenUnableToInitDatabase(t *testing.T) {
123123
return jarFile, true
124124
}
125125

126-
database.initDatabase = func(binaryExtractLocation, runtimePath, dataLocation, username, password, locale string, logger *os.File) error {
126+
database.initDatabase = func(binaryExtractLocation, runtimePath, dataLocation, username, password, locale string, encoding string, logger *os.File) error {
127127
return errors.New("ah it did not work")
128128
}
129129

@@ -226,7 +226,7 @@ func Test_ErrorWhenCannotStartPostgresProcess(t *testing.T) {
226226
return jarFile, true
227227
}
228228

229-
database.initDatabase = func(binaryExtractLocation, runtimePath, dataLocation, username, password, locale string, logger *os.File) error {
229+
database.initDatabase = func(binaryExtractLocation, runtimePath, dataLocation, username, password, locale string, encoding string, logger *os.File) error {
230230
_, _ = logger.Write([]byte("ah it did not work"))
231231
return nil
232232
}
@@ -257,6 +257,7 @@ func Test_CustomConfig(t *testing.T) {
257257
Port(9876).
258258
StartTimeout(10 * time.Second).
259259
Locale("C").
260+
Encoding("UTF8").
260261
Logger(nil))
261262

262263
if err := database.Start(); err != nil {
@@ -356,6 +357,36 @@ func Test_CustomLocaleConfig(t *testing.T) {
356357
}
357358
}
358359

360+
func Test_CustomEncodingConfig(t *testing.T) {
361+
database := NewDatabase(DefaultConfig().Encoding("UTF8"))
362+
if err := database.Start(); err != nil {
363+
shutdownDBAndFail(t, err, database)
364+
}
365+
366+
db, err := sql.Open("postgres", "host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable")
367+
if err != nil {
368+
shutdownDBAndFail(t, err, database)
369+
}
370+
371+
rows := db.QueryRow("SHOW SERVER_ENCODING;")
372+
373+
var (
374+
value string
375+
)
376+
if err := rows.Scan(&value); err != nil {
377+
shutdownDBAndFail(t, err, database)
378+
}
379+
assert.Equal(t, "UTF8", value)
380+
381+
if err := db.Close(); err != nil {
382+
shutdownDBAndFail(t, err, database)
383+
}
384+
385+
if err := database.Stop(); err != nil {
386+
shutdownDBAndFail(t, err, database)
387+
}
388+
}
389+
359390
func Test_ConcurrentStart(t *testing.T) {
360391
var wg sync.WaitGroup
361392

prepare_database.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ const (
1818
fmtAfterError = "%v happened after error: %w"
1919
)
2020

21-
type initDatabase func(binaryExtractLocation, runtimePath, pgDataDir, username, password, locale string, logger *os.File) error
21+
type initDatabase func(binaryExtractLocation, runtimePath, pgDataDir, username, password, locale string, encoding string, logger *os.File) error
2222
type createDatabase func(port uint32, username, password, database string) error
2323

24-
func defaultInitDatabase(binaryExtractLocation, runtimePath, pgDataDir, username, password, locale string, logger *os.File) error {
24+
func defaultInitDatabase(binaryExtractLocation, runtimePath, pgDataDir, username, password, locale string, encoding string, logger *os.File) error {
2525
passwordFile, err := createPasswordFile(runtimePath, password)
2626
if err != nil {
2727
return err
@@ -38,6 +38,10 @@ func defaultInitDatabase(binaryExtractLocation, runtimePath, pgDataDir, username
3838
args = append(args, fmt.Sprintf("--locale=%s", locale))
3939
}
4040

41+
if encoding != "" {
42+
args = append(args, fmt.Sprintf("--encoding=%s", encoding))
43+
}
44+
4145
postgresInitDBBinary := filepath.Join(binaryExtractLocation, "bin/initdb")
4246
postgresInitDBProcess := exec.Command(postgresInitDBBinary, args...)
4347
postgresInitDBProcess.Stderr = logger

prepare_database_test.go

+24-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
)
1313

1414
func Test_defaultInitDatabase_ErrorWhenCannotCreatePasswordFile(t *testing.T) {
15-
err := defaultInitDatabase("path_not_exists", "path_not_exists", "path_not_exists", "Tom", "Beer", "", os.Stderr)
15+
err := defaultInitDatabase("path_not_exists", "path_not_exists", "path_not_exists", "Tom", "Beer", "", "", os.Stderr)
1616

1717
assert.EqualError(t, err, "unable to write password file to path_not_exists/pwfile")
1818
}
@@ -49,7 +49,7 @@ func Test_defaultInitDatabase_ErrorWhenCannotStartInitDBProcess(t *testing.T) {
4949

5050
_, _ = logFile.Write([]byte("and here are the logs!"))
5151

52-
err = defaultInitDatabase(binTempDir, runtimeTempDir, filepath.Join(runtimeTempDir, "data"), "Tom", "Beer", "", logFile)
52+
err = defaultInitDatabase(binTempDir, runtimeTempDir, filepath.Join(runtimeTempDir, "data"), "Tom", "Beer", "", "", logFile)
5353

5454
assert.NotNil(t, err)
5555
assert.Contains(t, err.Error(), fmt.Sprintf("unable to init database using '%s/bin/initdb -A password -U Tom -D %s/data --pwfile=%s/pwfile'",
@@ -72,7 +72,7 @@ func Test_defaultInitDatabase_ErrorInvalidLocaleSetting(t *testing.T) {
7272
}
7373
}()
7474

75-
err = defaultInitDatabase(tempDir, tempDir, filepath.Join(tempDir, "data"), "postgres", "postgres", "en_XY", os.Stderr)
75+
err = defaultInitDatabase(tempDir, tempDir, filepath.Join(tempDir, "data"), "postgres", "postgres", "en_XY", "", os.Stderr)
7676

7777
assert.NotNil(t, err)
7878
assert.Contains(t, err.Error(), fmt.Sprintf("unable to init database using '%s/bin/initdb -A password -U postgres -D %s/data --pwfile=%s/pwfile --locale=en_XY'",
@@ -81,6 +81,27 @@ func Test_defaultInitDatabase_ErrorInvalidLocaleSetting(t *testing.T) {
8181
tempDir))
8282
}
8383

84+
func Test_defaultInitDatabase_ErrorInvalidEncodingSetting(t *testing.T) {
85+
tempDir, err := os.MkdirTemp("", "prepare_database_test")
86+
if err != nil {
87+
panic(err)
88+
}
89+
90+
defer func() {
91+
if err := os.RemoveAll(tempDir); err != nil {
92+
panic(err)
93+
}
94+
}()
95+
96+
err = defaultInitDatabase(tempDir, tempDir, filepath.Join(tempDir, "data"), "postgres", "postgres", "", "invalid", os.Stderr)
97+
98+
assert.NotNil(t, err)
99+
assert.Contains(t, err.Error(), fmt.Sprintf("unable to init database using '%s/bin/initdb -A password -U postgres -D %s/data --pwfile=%s/pwfile --encoding=invalid'",
100+
tempDir,
101+
tempDir,
102+
tempDir))
103+
}
104+
84105
func Test_defaultInitDatabase_PwFileRemoved(t *testing.T) {
85106
tempDir, err := os.MkdirTemp("", "prepare_database_test")
86107
if err != nil {

0 commit comments

Comments
 (0)