Allow setting readonly mode in bookmarks (#707)

This commit is contained in:
Dan Sosedoff 2024-01-12 21:17:14 -06:00 committed by GitHub
parent e560f07de6
commit 408e23adb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 16 deletions

View File

@ -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
@ -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,
}
}

View File

@ -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)
})
@ -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)
})
@ -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()

View File

@ -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"`
@ -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() {
@ -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
}

View File

@ -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) {