Skip to content

Commit

Permalink
Allow setting readonly mode in bookmarks (sosedoff#707)
Browse files Browse the repository at this point in the history
  • Loading branch information
sosedoff authored Jan 13, 2024
1 parent e560f07 commit 408e23a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 16 deletions.
16 changes: 9 additions & 7 deletions pkg/bookmarks/bookmarks.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Bookmark struct {
Database string // Database name
SSLMode string // Connection SSL mode
SSH *shared.SSHInfo // SSH tunnel config
ReadOnly bool // Enable read-only transaction mode
}

// SSHInfoIsEmpty returns true if ssh configuration is not provided
Expand All @@ -40,12 +41,13 @@ func (b Bookmark) ConvertToOptions() command.Options {
}

return command.Options{
URL: b.URL,
Host: b.Host,
Port: b.Port,
User: user,
Pass: pass,
DbName: b.Database,
SSLMode: b.SSLMode,
URL: b.URL,
Host: b.Host,
Port: b.Port,
User: user,
Pass: pass,
DbName: b.Database,
SSLMode: b.SSLMode,
ReadOnly: b.ReadOnly,
}
}
18 changes: 11 additions & 7 deletions pkg/bookmarks/bookmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func TestBookmarkWithVarsConvertToOptions(t *testing.T) {

t.Setenv("DB_USER", "user123")
t.Setenv("DB_PASSWORD", "password123")

opt := b.ConvertToOptions()
assert.Equal(t, expOpt, opt)
})
Expand All @@ -87,6 +88,7 @@ func TestBookmarkWithVarsConvertToOptions(t *testing.T) {

t.Setenv("DB_USER", "user123")
t.Setenv("DB_PASSWORD", "password123")

opt := b.ConvertToOptions()
assert.Equal(t, expOpt, opt)
})
Expand All @@ -101,16 +103,18 @@ func TestBookmarkConvertToOptions(t *testing.T) {
Password: "password",
Database: "mydatabase",
SSLMode: "disable",
ReadOnly: true,
}

expOpt := command.Options{
URL: "postgres://username:password@host:port/database?sslmode=disable",
Host: "localhost",
Port: 5432,
User: "postgres",
Pass: "password",
DbName: "mydatabase",
SSLMode: "disable",
URL: "postgres://username:password@host:port/database?sslmode=disable",
Host: "localhost",
Port: 5432,
User: "postgres",
Pass: "password",
DbName: "mydatabase",
SSLMode: "disable",
ReadOnly: true,
}

opt := b.ConvertToOptions()
Expand Down
14 changes: 12 additions & 2 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Client struct {
serverType string
lastQueryTime time.Time
queryTimeout time.Duration
readonly bool
closed bool
External bool `json:"external"`
History []history.Record `json:"history"`
Expand Down Expand Up @@ -166,7 +167,16 @@ func NewFromBookmark(bookmark *bookmarks.Bookmark) (*Client, error) {
sshInfo = bookmark.SSH
}

return NewFromUrl(connStr, sshInfo)
client, err := NewFromUrl(connStr, sshInfo)
if err != nil {
return nil, err
}

if bookmark.ReadOnly {
client.readonly = true
}

return client, nil
}

func (client *Client) init() {
Expand Down Expand Up @@ -476,7 +486,7 @@ func (client *Client) query(query string, args ...interface{}) (*Result, error)

// We're going to force-set transaction mode on every query.
// This is needed so that default mode could not be changed by user.
if command.Opts.ReadOnly {
if command.Opts.ReadOnly || client.readonly {
if err := client.SetReadOnlyMode(); err != nil {
return nil, err
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,14 @@ func testReadOnlyMode(t *testing.T) {

_, err = client.Query("/* CREATE TABLE foobar(id integer); */ SELECT 'foo';")
assert.NoError(t, err)

t.Run("with local readonly flag", func(t *testing.T) {
command.Opts.ReadOnly = false
client.readonly = true

_, err := client.Query("INSERT INTO foobar(id) VALUES(1)")
assert.Error(t, err, "query contains keywords not allowed in read-only mode")
})
}

func testTablesStats(t *testing.T) {
Expand Down

0 comments on commit 408e23a

Please sign in to comment.