Allow setting readonly mode in bookmarks (#707)
This commit is contained in:
parent
e560f07de6
commit
408e23adb3
@ -20,6 +20,7 @@ type Bookmark struct {
|
|||||||
Database string // Database name
|
Database string // Database name
|
||||||
SSLMode string // Connection SSL mode
|
SSLMode string // Connection SSL mode
|
||||||
SSH *shared.SSHInfo // SSH tunnel config
|
SSH *shared.SSHInfo // SSH tunnel config
|
||||||
|
ReadOnly bool // Enable read-only transaction mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSHInfoIsEmpty returns true if ssh configuration is not provided
|
// SSHInfoIsEmpty returns true if ssh configuration is not provided
|
||||||
@ -40,12 +41,13 @@ func (b Bookmark) ConvertToOptions() command.Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return command.Options{
|
return command.Options{
|
||||||
URL: b.URL,
|
URL: b.URL,
|
||||||
Host: b.Host,
|
Host: b.Host,
|
||||||
Port: b.Port,
|
Port: b.Port,
|
||||||
User: user,
|
User: user,
|
||||||
Pass: pass,
|
Pass: pass,
|
||||||
DbName: b.Database,
|
DbName: b.Database,
|
||||||
SSLMode: b.SSLMode,
|
SSLMode: b.SSLMode,
|
||||||
|
ReadOnly: b.ReadOnly,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ func TestBookmarkWithVarsConvertToOptions(t *testing.T) {
|
|||||||
|
|
||||||
t.Setenv("DB_USER", "user123")
|
t.Setenv("DB_USER", "user123")
|
||||||
t.Setenv("DB_PASSWORD", "password123")
|
t.Setenv("DB_PASSWORD", "password123")
|
||||||
|
|
||||||
opt := b.ConvertToOptions()
|
opt := b.ConvertToOptions()
|
||||||
assert.Equal(t, expOpt, opt)
|
assert.Equal(t, expOpt, opt)
|
||||||
})
|
})
|
||||||
@ -87,6 +88,7 @@ func TestBookmarkWithVarsConvertToOptions(t *testing.T) {
|
|||||||
|
|
||||||
t.Setenv("DB_USER", "user123")
|
t.Setenv("DB_USER", "user123")
|
||||||
t.Setenv("DB_PASSWORD", "password123")
|
t.Setenv("DB_PASSWORD", "password123")
|
||||||
|
|
||||||
opt := b.ConvertToOptions()
|
opt := b.ConvertToOptions()
|
||||||
assert.Equal(t, expOpt, opt)
|
assert.Equal(t, expOpt, opt)
|
||||||
})
|
})
|
||||||
@ -101,16 +103,18 @@ func TestBookmarkConvertToOptions(t *testing.T) {
|
|||||||
Password: "password",
|
Password: "password",
|
||||||
Database: "mydatabase",
|
Database: "mydatabase",
|
||||||
SSLMode: "disable",
|
SSLMode: "disable",
|
||||||
|
ReadOnly: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
expOpt := command.Options{
|
expOpt := command.Options{
|
||||||
URL: "postgres://username:password@host:port/database?sslmode=disable",
|
URL: "postgres://username:password@host:port/database?sslmode=disable",
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
Port: 5432,
|
Port: 5432,
|
||||||
User: "postgres",
|
User: "postgres",
|
||||||
Pass: "password",
|
Pass: "password",
|
||||||
DbName: "mydatabase",
|
DbName: "mydatabase",
|
||||||
SSLMode: "disable",
|
SSLMode: "disable",
|
||||||
|
ReadOnly: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := b.ConvertToOptions()
|
opt := b.ConvertToOptions()
|
||||||
|
@ -41,6 +41,7 @@ type Client struct {
|
|||||||
serverType string
|
serverType string
|
||||||
lastQueryTime time.Time
|
lastQueryTime time.Time
|
||||||
queryTimeout time.Duration
|
queryTimeout time.Duration
|
||||||
|
readonly bool
|
||||||
closed bool
|
closed bool
|
||||||
External bool `json:"external"`
|
External bool `json:"external"`
|
||||||
History []history.Record `json:"history"`
|
History []history.Record `json:"history"`
|
||||||
@ -166,7 +167,16 @@ func NewFromBookmark(bookmark *bookmarks.Bookmark) (*Client, error) {
|
|||||||
sshInfo = bookmark.SSH
|
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() {
|
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.
|
// We're going to force-set transaction mode on every query.
|
||||||
// This is needed so that default mode could not be changed by user.
|
// 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 {
|
if err := client.SetReadOnlyMode(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -679,6 +679,14 @@ func testReadOnlyMode(t *testing.T) {
|
|||||||
|
|
||||||
_, err = client.Query("/* CREATE TABLE foobar(id integer); */ SELECT 'foo';")
|
_, err = client.Query("/* CREATE TABLE foobar(id integer); */ SELECT 'foo';")
|
||||||
assert.NoError(t, err)
|
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) {
|
func testTablesStats(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user