diff --git a/CHANGELOG.md b/CHANGELOG.md index d8a23ed69..1a9f55b1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. ### Bug Fixes +* cli: Fix database init when locale isn't english + ([Issue](https://github.com/hashicorp/boundary/issues/729)) + ([PR](https://github.com/hashicorp/boundary/pull/736)) * cli: Fix hyphenation in help output for resources with compound names ([Issue](https://github.com/hashicorp/boundary/issues/686)) ([PR](https://github.com/hashicorp/boundary/pull/689)) diff --git a/internal/cmd/commands/database/init.go b/internal/cmd/commands/database/init.go index b1b076afd..da193292d 100644 --- a/internal/cmd/commands/database/init.go +++ b/internal/cmd/commands/database/init.go @@ -254,7 +254,7 @@ func (c *InitCommand) Run(args []string) (retCode int) { c.UI.Info("Database already initialized.") return 0 } - case strings.Contains(err.Error(), "does not exist"): + case db.IsMissingTableError(err): // Doesn't exist so we continue on default: c.UI.Error(fmt.Errorf("Error querying database for init status: %w", err).Error()) diff --git a/internal/db/error.go b/internal/db/error.go index 1d9f62177..90b645f36 100644 --- a/internal/db/error.go +++ b/internal/db/error.go @@ -89,3 +89,15 @@ func IsNotNullError(err error) bool { return false } + +// IsMissingTableError returns a boolean indicating whether the error is known +// to report a undefined/missing table violation. +func IsMissingTableError(err error) bool { + var pqError *pq.Error + if errors.As(err, &pqError) { + if pqError.Code == "42P01" { + return true + } + } + return false +} diff --git a/internal/db/error_test.go b/internal/db/error_test.go index cd2610d76..f68cd8f16 100644 --- a/internal/db/error_test.go +++ b/internal/db/error_test.go @@ -1,10 +1,12 @@ package db import ( + "context" "testing" "github.com/lib/pq" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestError_IsUnique(t *testing.T) { @@ -124,3 +126,55 @@ func TestError_IsNotNullError(t *testing.T) { }) } } + +func TestError_IsMissingTableError(t *testing.T) { + var tests = []struct { + name string + in error + want bool + }{ + { + name: "nil-error", + in: nil, + want: false, + }, + { + name: "postgres-is-unique-not-not-null", + in: &pq.Error{ + Code: pq.ErrorCode("23505"), + }, + want: false, + }, + { + name: "postgres-is-check-constraint-not-not-null", + in: &pq.Error{ + Code: pq.ErrorCode("23514"), + }, + want: false, + }, + { + name: "postgres-is-missing-table", + in: &pq.Error{ + Code: pq.ErrorCode("42P01"), + }, + want: true, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + assert := assert.New(t) + err := tt.in + got := IsMissingTableError(err) + assert.Equal(tt.want, got) + }) + } + t.Run("query-missing-table", func(t *testing.T) { + assert, require := assert.New(t), require.New(t) + conn, _ := TestSetup(t, "postgres") + rw := New(conn) + _, err := rw.Query(context.Background(), "select * from non_existent_table", nil) + require.Error(err) + assert.True(IsMissingTableError(err)) + }) +}