From 6c113272894d94ff5fca69ed32c7f8f2a9d99b9e Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 6 Mar 2020 14:17:23 -0500 Subject: [PATCH] Convert keystore funcs to use avdl compiled types --- keybase.go | 8 -- kvstore.go | 218 +++++++++++++++++++++++++++++++++-------------------- types.go | 76 +++++++------------ 3 files changed, 162 insertions(+), 140 deletions(-) diff --git a/keybase.go b/keybase.go index c12e90e..5720ed4 100644 --- a/keybase.go +++ b/keybase.go @@ -89,14 +89,6 @@ func (k *Keybase) NewTeam(name string) Team { } } -// NewKV returns a new KV instance -func (k *Keybase) NewKV(team string) KV { - return KV{ - keybase: k, - Team: team, - } -} - // NewWallet returns a new Wallet instance func (k *Keybase) NewWallet() Wallet { return Wallet{ diff --git a/kvstore.go b/kvstore.go index ac91b25..96d1ca7 100644 --- a/kvstore.go +++ b/kvstore.go @@ -2,136 +2,190 @@ package keybase import ( "encoding/json" - "errors" + "fmt" + + "samhofi.us/x/keybase/types/keybase1" ) -// kvAPIOut sends a JSON request to the kvstore API and returns its response. -func kvAPIOut(k *Keybase, kv KVAPI) (KVAPI, error) { - jsonBytes, _ := json.Marshal(kv) +// KVListNamespaces returns all namespaces for a team +func (k *Keybase) KVListNamespaces(team *string) (keybase1.KVListNamespaceResult, error) { + type res struct { + Result keybase1.KVListNamespaceResult `json:"result"` + Error *Error `json:"error"` + } + var r res + + arg := newKVArg("list", KVOptions{ + Team: team, + }) + + jsonBytes, _ := json.Marshal(arg) cmdOut, err := k.Exec("kvstore", "api", "-m", string(jsonBytes)) if err != nil { - return KVAPI{}, err + return r.Result, err } - var r KVAPI - if err := json.Unmarshal(cmdOut, &r); err != nil { - return KVAPI{}, err + err = json.Unmarshal(cmdOut, &r) + if err != nil { + return r.Result, err } if r.Error != nil { - return KVAPI{}, errors.New(r.Error.Message) + return r.Result, fmt.Errorf("%s", r.Error.Message) } - return r, nil + return r.Result, nil } -// Namespaces returns all namespaces for a team -func (kv KV) Namespaces() (KVAPI, error) { - m := KVAPI{ - Params: &kvParams{}, - } - m.Params.Options = kvOptions{ - Team: kv.Team, +// KVListKeys returns all non-deleted keys for a namespace +func (k *Keybase) KVListKeys(team *string, namespace string) (keybase1.KVListEntryResult, error) { + type res struct { + Result keybase1.KVListEntryResult `json:"result"` + Error *Error `json:"error"` } + var r res + + arg := newKVArg("list", KVOptions{ + Team: team, + Namespace: &namespace, + }) - m.Method = "list" + jsonBytes, _ := json.Marshal(arg) - r, err := kvAPIOut(kv.keybase, m) + cmdOut, err := k.Exec("kvstore", "api", "-m", string(jsonBytes)) if err != nil { - return r, err + return r.Result, err } - return r, nil -} -// Keys returns all non-deleted keys for a namespace -func (kv KV) Keys(namespace string) (KVAPI, error) { - m := KVAPI{ - Params: &kvParams{}, + err = json.Unmarshal(cmdOut, &r) + if err != nil { + return r.Result, err } - m.Params.Options = kvOptions{ - Team: kv.Team, - Namespace: namespace, + + if r.Error != nil { + return r.Result, fmt.Errorf("%s", r.Error.Message) } - m.Method = "list" + return r.Result, nil +} - r, err := kvAPIOut(kv.keybase, m) - if err != nil { - return r, err +// KVGet returns an entry +func (k *Keybase) KVGet(team *string, namespace string, key string) (keybase1.KVGetResult, error) { + type res struct { + Result keybase1.KVGetResult `json:"result"` + Error *Error `json:"error"` } - return r, nil -} + var r res + + arg := newKVArg("get", KVOptions{ + Team: team, + Namespace: &namespace, + EntryKey: &key, + }) -// Get returns an entry -func (kv KV) Get(namespace string, key string, revision ...uint) (KVAPI, error) { - m := KVAPI{ - Params: &kvParams{}, + jsonBytes, _ := json.Marshal(arg) + + cmdOut, err := k.Exec("kvstore", "api", "-m", string(jsonBytes)) + if err != nil { + return r.Result, err } - m.Params.Options = kvOptions{ - Team: kv.Team, - Namespace: namespace, - EntryKey: key, + + err = json.Unmarshal(cmdOut, &r) + if err != nil { + return r.Result, err } - if len(revision) > 0 { - m.Params.Options.Revision = revision[0] + if r.Error != nil { + return r.Result, fmt.Errorf("%s", r.Error.Message) } - m.Method = "get" + return r.Result, nil +} - r, err := kvAPIOut(kv.keybase, m) - if err != nil { - return r, err +// KVPutWithRevision puts an entry, specifying the revision number +func (k *Keybase) KVPutWithRevision(team *string, namespace string, key string, value string, revision int) (keybase1.KVPutResult, error) { + type res struct { + Result keybase1.KVPutResult `json:"result"` + Error *Error `json:"error"` } - return r, nil -} + var r res -// Put adds an entry -func (kv KV) Put(namespace string, key string, value string, revision ...uint) (KVAPI, error) { - m := KVAPI{ - Params: &kvParams{}, + opts := KVOptions{ + Team: team, + Namespace: &namespace, + EntryKey: &key, + EntryValue: &value, } - m.Params.Options = kvOptions{ - Team: kv.Team, - Namespace: namespace, - EntryKey: key, - EntryValue: value, + if revision != 0 { + opts.Revision = &revision } - if len(revision) > 0 { - m.Params.Options.Revision = revision[0] - } + arg := newKVArg("put", opts) - m.Method = "put" + jsonBytes, _ := json.Marshal(arg) - r, err := kvAPIOut(kv.keybase, m) + cmdOut, err := k.Exec("kvstore", "api", "-m", string(jsonBytes)) if err != nil { - return r, err + return r.Result, err + } + + err = json.Unmarshal(cmdOut, &r) + if err != nil { + return r.Result, err } - return r, nil -} -// Delete removes an entry -func (kv KV) Delete(namespace string, key string, revision ...uint) (KVAPI, error) { - m := KVAPI{ - Params: &kvParams{}, + if r.Error != nil { + return r.Result, fmt.Errorf("%s", r.Error.Message) } - m.Params.Options = kvOptions{ - Team: kv.Team, - Namespace: namespace, - EntryKey: key, + + return r.Result, nil +} + +// KVPut puts an entry +func (k *Keybase) KVPut(team *string, namespace string, key string, value string) (keybase1.KVPutResult, error) { + return k.KVPutWithRevision(team, namespace, key, value, 0) +} + +// KVDeleteWithRevision deletes an entry, specifying the revision number +func (k *Keybase) KVDeleteWithRevision(team *string, namespace string, key string, revision int) (keybase1.KVDeleteEntryResult, error) { + type res struct { + Result keybase1.KVDeleteEntryResult `json:"result"` + Error *Error `json:"error"` } + var r res - if len(revision) > 0 { - m.Params.Options.Revision = revision[0] + opts := KVOptions{ + Team: team, + Namespace: &namespace, + EntryKey: &key, } + if revision != 0 { + opts.Revision = &revision + } + + arg := newKVArg("del", opts) + + jsonBytes, _ := json.Marshal(arg) - m.Method = "del" + cmdOut, err := k.Exec("kvstore", "api", "-m", string(jsonBytes)) + if err != nil { + return r.Result, err + } - r, err := kvAPIOut(kv.keybase, m) + err = json.Unmarshal(cmdOut, &r) if err != nil { - return r, err + return r.Result, err } - return r, nil + + if r.Error != nil { + return r.Result, fmt.Errorf("%s", r.Error.Message) + } + + return r.Result, nil +} + +// KVDelete deletes an entry +func (k *Keybase) KVDelete(team *string, namespace string, key string) (keybase1.KVDeleteEntryResult, error) { + return k.KVDeleteWithRevision(team, namespace, key, 0) } diff --git a/types.go b/types.go index 114cefc..7676dd1 100644 --- a/types.go +++ b/types.go @@ -114,6 +114,32 @@ type SendResponse struct { Error *Error `json:"error,omitempty"` } +type KVOptions struct { + Team *string `json:"team"` + Namespace *string `json:"namespace,omitempty"` + EntryKey *string `json:"entryKey,omitempty"` + EntryValue *string `json:"entryValue,omitempty"` + Revision *int `json:"revision,omitempty"` +} + +type kvParams struct { + Options KVOptions `json:"options"` +} + +type kvArg struct { + Method string `json:"method"` + Params kvParams `json:"params"` +} + +func newKVArg(method string, options KVOptions) kvArg { + return kvArg{ + Method: method, + Params: kvParams{ + Options: options, + }, + } +} + // ChatAPI holds information about a message received by the `keybase chat api-listen` command type ChatAPI struct { Type string `json:"type,omitempty"` @@ -714,41 +740,6 @@ type teamInfo struct { Implicit implicit `json:"implicit,omitempty"` } -// KVAPI holds information sent and received to/from the kvstore api -type KVAPI struct { - Method string `json:"method,omitempty"` - Params *kvParams `json:"params,omitempty"` - Result *kvResult `json:"result,omitempty"` - Error *Error `json:"error"` - keybase Keybase -} - -type kvOptions struct { - Team string `json:"team,omitempty"` - Namespace string `json:"namespace,omitempty"` - EntryKey string `json:"entryKey,omitempty"` - Revision uint `json:"revision,omitempty"` - EntryValue string `json:"entryValue,omitempty"` -} - -type kvParams struct { - Options kvOptions `json:"options,omitempty"` -} - -type entryKey struct { - EntryKey string `json:"entryKey"` - Revision uint `json:"revision"` -} - -type kvResult struct { - TeamName string `json:"teamName"` - Namespaces []string `json:"namespaces"` - EntryKeys []entryKey `json:"entryKeys"` - EntryKey string `json:"entryKey"` - EntryValue string `json:"entryValue"` - Revision uint `json:"revision"` -} - // UserAPI holds information received from the user/lookup api type UserAPI struct { Status uStatus `json:"status"` @@ -951,20 +942,6 @@ type wallet interface { TxDetail(txid string) (WalletAPI, error) } -// KV holds basic information about a KVStore -type KV struct { - keybase *Keybase - Team string -} - -type kvInterface interface { - Namespaces() (KVAPI, error) - Keys(namespace string) (KVAPI, error) - Get(namespace string, key string) (KVAPI, error) - Put(namespace string, key string, value string) (KVAPI, error) - Delete(namespace string, key string) (KVAPI, error) -} - type keybase interface { AdvertiseCommand(advertisement BotAdvertisement) (ChatAPI, error) AdvertiseCommands(advertisements []BotAdvertisement) (ChatAPI, error) @@ -973,7 +950,6 @@ type keybase interface { CreateTeam(name string) (TeamAPI, error) NewChat(channel chat1.ChatChannel) Chat NewTeam(name string) Team - NewKV(team string) KV NewWallet() Wallet Run(handler func(ChatAPI), options ...RunOptions) status() status