From da5876f6324659a28e56b5f5c91a034c010570e2 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 8 Aug 2019 10:31:24 +0300 Subject: [PATCH] Add api method settings_getConfigs to retrieve list of configs in a batch quer --- multiaccounts/accounts/database.go | 32 ++++++++++++++++++++++++- multiaccounts/accounts/database_test.go | 22 +++++++++++++++-- services/accounts/out.json | 1 + services/accounts/settings.go | 10 ++++---- 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 services/accounts/out.json diff --git a/multiaccounts/accounts/database.go b/multiaccounts/accounts/database.go index f6fbc6df8..bd5683271 100644 --- a/multiaccounts/accounts/database.go +++ b/multiaccounts/accounts/database.go @@ -2,7 +2,10 @@ package accounts import ( "database/sql" + "encoding/json" "errors" + "fmt" + "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -56,10 +59,37 @@ func (db *Database) GetConfig(typ string, value interface{}) error { return db.db.QueryRow("SELECT value FROM settings WHERE type = ?", typ).Scan(&sqlite.JSONBlob{value}) } -func (db *Database) GetBlob(typ string) (rst []byte, err error) { +func (db *Database) GetConfigBlob(typ string) (rst json.RawMessage, err error) { return rst, db.db.QueryRow("SELECT value FROM settings WHERE type = ?", typ).Scan(&rst) } +func (db *Database) GetConfigBlobs(types []string) (map[string]json.RawMessage, error) { + // it expands number of bind vars to the number of types. sql interface doesn't allow to bypass it without modifying driver. + // expansion can be hidden in a function that modifies string but better to make it explicitly. + query := fmt.Sprintf("SELECT type, value FROM settings WHERE type IN (?%s)", strings.Repeat(",?", len(types)-1)) // nolint: gosec + args := make([]interface{}, len(types)) + for i := range types { + args[i] = types[i] + } + rows, err := db.db.Query(query, args...) + if err != nil { + return nil, err + } + rst := make(map[string]json.RawMessage, len(types)) + for rows.Next() { + var ( + buf = json.RawMessage{} + typ string + ) + err = rows.Scan(&typ, &buf) + if err != nil { + return nil, err + } + rst[typ] = buf + } + return rst, nil +} + func (db *Database) GetAccounts() ([]Account, error) { rows, err := db.db.Query("SELECT address, wallet, chat, type, storage, pubkey, path, name, color FROM accounts") if err != nil { diff --git a/multiaccounts/accounts/database_test.go b/multiaccounts/accounts/database_test.go index 2c3300fdf..5e161527f 100644 --- a/multiaccounts/accounts/database_test.go +++ b/multiaccounts/accounts/database_test.go @@ -39,7 +39,7 @@ func TestConfig(t *testing.T) { require.Equal(t, conf, rst) } -func TestBlob(t *testing.T) { +func TestConfigBlob(t *testing.T) { db, stop := setupTestDB(t) defer stop() tag := "random-param" @@ -47,7 +47,25 @@ func TestBlob(t *testing.T) { require.NoError(t, db.SaveConfig(tag, param)) expected, err := json.Marshal(param) require.NoError(t, err) - rst, err := db.GetBlob(tag) + rst, err := db.GetConfigBlob(tag) + require.NoError(t, err) + require.Equal(t, json.RawMessage(expected), rst) +} + +func TestGetConfigBlobs(t *testing.T) { + db, stop := setupTestDB(t) + defer stop() + expected := map[string]json.RawMessage{ + "tag1": json.RawMessage("1"), + "tag2": json.RawMessage("2"), + "tag3": json.RawMessage("3"), + } + types := make([]string, 0, len(expected)) + for k, v := range expected { + require.NoError(t, db.SaveConfig(k, v)) + types = append(types, k) + } + rst, err := db.GetConfigBlobs(types) require.NoError(t, err) require.Equal(t, expected, rst) } diff --git a/services/accounts/out.json b/services/accounts/out.json new file mode 100644 index 000000000..6b48d6538 --- /dev/null +++ b/services/accounts/out.json @@ -0,0 +1 @@ +{"ClusterConfig":{"Enabled":true,"Fleet":"eth.beta","BootNodes":["enode://7427dfe38bd4cf7c58bb96417806fab25782ec3e6046a8053370022cbaa281536e8d64ecd1b02e1f8f72768e295d06258ba43d88304db068e6f2417ae8bcb9a6@104.154.88.123:443","enode://e8a7c03b58911e98bbd66accb2a55d57683f35b23bf9dfca89e5e244eb5cc3f25018b4112db507faca34fb69ffb44b362f79eda97a669a8df29c72e654416784@47.91.224.35:443","enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@206.189.243.57:443","enode://43947863cfa5aad1178f482ac35a8ebb9116cded1c23f7f9af1a47badfc1ee7f0dd9ec0543417cc347225a6e47e46c6873f647559e43434596c54e17a4d3a1e4@47.52.74.140:443"],"TrustedMailServers":["enode://744098ab6d3308af5cd03920aea60c46d16b2cd3d33bf367cbaf1d01c2fcd066ff8878576d0967897cd7dbb0e63f873cc0b4f7e4b0f1d7222e6b3451a78d9bda@47.89.20.15:443","enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@206.189.243.168:443","enode://7de99e4cb1b3523bd26ca212369540646607c721ad4f3e5c821ed9148150ce6ce2e72631723002210fac1fd52dfa8bbdf3555e05379af79515e1179da37cc3db@35.188.19.210:443","enode://da61e9eff86a56633b635f887d8b91e0ff5236bbc05b8169834292e92afb92929dcf6efdbf373a37903da8fe0384d5a0a8247e83f1ce211aa429200b6d28c548@47.91.156.93:443","enode://74957e361ab290e6af45a124536bc9adee39fbd2f995a77ace6ed7d05d9a1c7c98b78b2df5f8071c439b9c0afe4a69893ede4ad633473f96bc195ddf33f6ce00@47.52.255.195:443","enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@206.189.243.162:443"],"StaticNodes":["enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@206.189.243.177:443","enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@206.189.243.172:443"],"RendezvousNodes":["/ip4/206.189.243.57/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf","/ip4/174.138.105.243/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV"]},"DataDir":"/ethereum/mainnet_rpc_dev","LogLevel":"INFO","Rendezvous":true,"WhisperConfig":{"Enabled":true,"LightClient":true,"MinimumPoW":0.001,"EnableNTPSync":true},"LogEnabled":true,"BrowsersConfig":{"Enabled":true},"RequireTopics":{"whisper":{"Min":2,"Max":2}},"UpstreamConfig":{"Enabled":true,"URL":"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a"},"ListenAddr":":30304","PermissionsConfig":{"Enabled":true},"NetworkId":1,"Name":"StatusIM","NoDiscovery":false,"ShhextConfig":{"BackupDisabledDataDir":"/data/user/0/im.status.ethereum.debug/files/../no_backup","InstallationID":"cf40e6c9-262f-5a76-9621-7b6fe0a91cd2","MaxMessageDeliveryAttempts":6,"MailServerConfirmations":true,"DataSyncEnabled":false,"DisableGenericDiscoveryTopic":false,"SendV1Messages":false,"PFSEnabled":true},"WalletConfig":{"Enabled":true},"StatusAccountsConfig":{"Enabled":true}} diff --git a/services/accounts/settings.go b/services/accounts/settings.go index a06894534..1e7f89420 100644 --- a/services/accounts/settings.go +++ b/services/accounts/settings.go @@ -22,11 +22,11 @@ func (api *SettingsAPI) SaveConfig(ctx context.Context, typ string, conf json.Ra } func (api *SettingsAPI) GetConfig(ctx context.Context, typ string) (json.RawMessage, error) { - rst, err := api.db.GetBlob(typ) - if err != nil { - return nil, err - } - return json.RawMessage(rst), nil + return api.db.GetConfigBlob(typ) +} + +func (api *SettingsAPI) GetConfigs(ctx context.Context, types []string) (map[string]json.RawMessage, error) { + return api.db.GetConfigBlobs(types) } func (api *SettingsAPI) SaveNodeConfig(ctx context.Context, conf *params.NodeConfig) error {