Skip to content

Commit

Permalink
Merge pull request #272 from digitalocean/dbaas-sql-mode
Browse files Browse the repository at this point in the history
dbaas: get and set mysql sql mode
  • Loading branch information
bentranter authored Nov 13, 2019
2 parents 693f677 + 9f8a1f0 commit 94aa2b3
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 18 deletions.
109 changes: 91 additions & 18 deletions databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,62 @@ import (
"context"
"fmt"
"net/http"
"strings"
"time"
)

const (
databaseBasePath = "/v2/databases"
databaseSinglePath = databaseBasePath + "/%s"
databaseResizePath = databaseBasePath + "/%s/resize"
databaseMigratePath = databaseBasePath + "/%s/migrate"
databaseMaintenancePath = databaseBasePath + "/%s/maintenance"
databaseBackupsPath = databaseBasePath + "/%s/backups"
databaseUsersPath = databaseBasePath + "/%s/users"
databaseUserPath = databaseBasePath + "/%s/users/%s"
databaseDBPath = databaseBasePath + "/%s/dbs/%s"
databaseDBsPath = databaseBasePath + "/%s/dbs"
databasePoolPath = databaseBasePath + "/%s/pools/%s"
databasePoolsPath = databaseBasePath + "/%s/pools"
databaseReplicaPath = databaseBasePath + "/%s/replicas/%s"
databaseReplicasPath = databaseBasePath + "/%s/replicas"
evictionPolicyPath = databaseBasePath + "/%s/eviction_policy"
databaseFirewallRulesPath = databaseBasePath + "/%s/firewall"
databaseBasePath = "/v2/databases"
databaseSinglePath = databaseBasePath + "/%s"
databaseResizePath = databaseBasePath + "/%s/resize"
databaseMigratePath = databaseBasePath + "/%s/migrate"
databaseMaintenancePath = databaseBasePath + "/%s/maintenance"
databaseBackupsPath = databaseBasePath + "/%s/backups"
databaseUsersPath = databaseBasePath + "/%s/users"
databaseUserPath = databaseBasePath + "/%s/users/%s"
databaseDBPath = databaseBasePath + "/%s/dbs/%s"
databaseDBsPath = databaseBasePath + "/%s/dbs"
databasePoolPath = databaseBasePath + "/%s/pools/%s"
databasePoolsPath = databaseBasePath + "/%s/pools"
databaseReplicaPath = databaseBasePath + "/%s/replicas/%s"
databaseReplicasPath = databaseBasePath + "/%s/replicas"
databaseEvictionPolicyPath = databaseBasePath + "/%s/eviction_policy"
databaseSQLModePath = databaseBasePath + "/%s/sql_mode"
databaseFirewallRulesPath = databaseBasePath + "/%s/firewall"
)

// SQL Mode constants allow for MySQL-specific SQL flavor configuration.
const (
SQLModeAllowInvalidDates = "ALLOW_INVALID_DATES"
SQLModeANSIQuotes = "ANSI_QUOTES"
SQLModeHighNotPrecedence = "HIGH_NOT_PRECEDENCE"
SQLModeIgnoreSpace = "IGNORE_SPACE"
SQLModeNoAuthCreateUser = "NO_AUTO_CREATE_USER"
SQLModeNoAutoValueOnZero = "NO_AUTO_VALUE_ON_ZERO"
SQLModeNoBackslashEscapes = "NO_BACKSLASH_ESCAPES"
SQLModeNoDirInCreate = "NO_DIR_IN_CREATE"
SQLModeNoEngineSubstitution = "NO_ENGINE_SUBSTITUTION"
SQLModeNoFieldOptions = "NO_FIELD_OPTIONS"
SQLModeNoKeyOptions = "NO_KEY_OPTIONS"
SQLModeNoTableOptions = "NO_TABLE_OPTIONS"
SQLModeNoUnsignedSubtraction = "NO_UNSIGNED_SUBTRACTION"
SQLModeNoZeroDate = "NO_ZERO_DATE"
SQLModeNoZeroInDate = "NO_ZERO_IN_DATE"
SQLModeOnlyFullGroupBy = "ONLY_FULL_GROUP_BY"
SQLModePadCharToFullLength = "PAD_CHAR_TO_FULL_LENGTH"
SQLModePipesAsConcat = "PIPES_AS_CONCAT"
SQLModeRealAsFloat = "REAL_AS_FLOAT"
SQLModeStrictAllTables = "STRICT_ALL_TABLES"
SQLModeStrictTransTables = "STRICT_TRANS_TABLES"
SQLModeANSI = "ANSI"
SQLModeDB2 = "DB2"
SQLModeMaxDB = "MAXDB"
SQLModeMSSQL = "MSSQL"
SQLModeMYSQL323 = "MYSQL323"
SQLModeMYSQL40 = "MYSQL40"
SQLModeOracle = "ORACLE"
SQLModePostgreSQL = "POSTGRESQL"
SQLModeTraditional = "TRADITIONAL"
)

// DatabasesService is an interface for interfacing with the databases endpoints
Expand Down Expand Up @@ -56,6 +92,8 @@ type DatabasesService interface {
DeleteReplica(context.Context, string, string) (*Response, error)
GetEvictionPolicy(context.Context, string) (string, *Response, error)
SetEvictionPolicy(context.Context, string, string) (*Response, error)
GetSQLMode(context.Context, string) (string, *Response, error)
SetSQLMode(context.Context, string, ...string) (*Response, error)
GetFirewallRules(context.Context, string) ([]DatabaseFirewallRule, *Response, error)
UpdateFirewallRules(context.Context, string, *DatabaseUpdateFirewallRulesRequest) (*Response, error)
}
Expand Down Expand Up @@ -276,10 +314,15 @@ type evictionPolicyRoot struct {
EvictionPolicy string `json:"eviction_policy"`
}

type sqlModeRoot struct {
SQLMode string `json:"sql_mode"`
}

type databaseFirewallRuleRoot struct {
Rules []DatabaseFirewallRule `json:"rules"`
}

// URN returns a URN identifier for the database
func (d Database) URN() string {
return ToURN("dbaas", d.ID)
}
Expand Down Expand Up @@ -663,7 +706,7 @@ func (svc *DatabasesServiceOp) DeleteReplica(ctx context.Context, databaseID, na

// GetEvictionPolicy loads the eviction policy for a given Redis cluster.
func (svc *DatabasesServiceOp) GetEvictionPolicy(ctx context.Context, databaseID string) (string, *Response, error) {
path := fmt.Sprintf(evictionPolicyPath, databaseID)
path := fmt.Sprintf(databaseEvictionPolicyPath, databaseID)
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return "", nil, err
Expand All @@ -678,7 +721,7 @@ func (svc *DatabasesServiceOp) GetEvictionPolicy(ctx context.Context, databaseID

// SetEvictionPolicy updates the eviction policy for a given Redis cluster.
func (svc *DatabasesServiceOp) SetEvictionPolicy(ctx context.Context, databaseID, policy string) (*Response, error) {
path := fmt.Sprintf(evictionPolicyPath, databaseID)
path := fmt.Sprintf(databaseEvictionPolicyPath, databaseID)
root := &evictionPolicyRoot{EvictionPolicy: policy}
req, err := svc.client.NewRequest(ctx, http.MethodPut, path, root)
if err != nil {
Expand All @@ -691,6 +734,36 @@ func (svc *DatabasesServiceOp) SetEvictionPolicy(ctx context.Context, databaseID
return resp, nil
}

// GetSQLMode loads the SQL Mode settings for a given MySQL cluster.
func (svc *DatabasesServiceOp) GetSQLMode(ctx context.Context, databaseID string) (string, *Response, error) {
path := fmt.Sprintf(databaseSQLModePath, databaseID)
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return "", nil, err
}
root := &sqlModeRoot{}
resp, err := svc.client.Do(ctx, req, root)
if err != nil {
return "", resp, err
}
return root.SQLMode, resp, nil
}

// SetSQLMode updates the SQL Mode settings for a given MySQL cluster.
func (svc *DatabasesServiceOp) SetSQLMode(ctx context.Context, databaseID string, sqlModes ...string) (*Response, error) {
path := fmt.Sprintf(databaseSQLModePath, databaseID)
root := &sqlModeRoot{SQLMode: strings.Join(sqlModes, ",")}
req, err := svc.client.NewRequest(ctx, http.MethodPut, path, root)
if err != nil {
return nil, err
}
resp, err := svc.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}

// GetFirewallRules loads the inbound sources for a given cluster.
func (svc *DatabasesServiceOp) GetFirewallRules(ctx context.Context, databaseID string) ([]DatabaseFirewallRule, *Response, error) {
path := fmt.Sprintf(databaseFirewallRulesPath, databaseID)
Expand Down
56 changes: 56 additions & 0 deletions databases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,62 @@ func TestDatabases_GetEvictionPolicy(t *testing.T) {
require.Equal(t, want, got)
}

func TestDatabases_SetSQLMode(t *testing.T) {
setup()
defer teardown()

dbID := "deadbeef-dead-4aa5-beef-deadbeef347d"

path := fmt.Sprintf("/v2/databases/%s/sql_mode", dbID)

mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodPut)
w.Write([]byte(`{ "sql_mode": "ONLY_FULL_GROUP_BY" }`))
})

_, err := client.Databases.SetSQLMode(ctx, dbID, "ONLY_FULL_GROUP_BY")
require.NoError(t, err)
}

func TestDatabases_SetSQLMode_Multiple(t *testing.T) {
setup()
defer teardown()

dbID := "deadbeef-dead-4aa5-beef-deadbeef347d"

path := fmt.Sprintf("/v2/databases/%s/sql_mode", dbID)

mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodPut)
w.Write([]byte(`{ "sql_mode": "ANSI, ANSI_QUOTES" }`))
})

_, err := client.Databases.SetSQLMode(ctx, dbID, SQLModeANSI, SQLModeANSIQuotes)
require.NoError(t, err)
}

func TestDatabases_GetSQLMode(t *testing.T) {
setup()
defer teardown()

dbID := "deadbeef-dead-4aa5-beef-deadbeef347d"

want := "ONLY_FULL_GROUP_BY"

body := `{ "sql_mode": "ONLY_FULL_GROUP_BY" }`

path := fmt.Sprintf("/v2/databases/%s/sql_mode", dbID)

mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, body)
})

got, _, err := client.Databases.GetSQLMode(ctx, dbID)
require.NoError(t, err)
require.Equal(t, want, got)
}

func TestDatabases_GetFirewallRules(t *testing.T) {
setup()
defer teardown()
Expand Down

0 comments on commit 94aa2b3

Please sign in to comment.