mirror of https://github.com/mitchell/selfpass.git
112 lines
2.2 KiB
Go
112 lines
2.2 KiB
Go
|
package repositories
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"github.com/mediocregopher/radix/v3"
|
||
|
"github.com/mitchell/selfpass/credentials/types"
|
||
|
)
|
||
|
|
||
|
func NewRedisConn(cfg ConnConfig) (c RedisConn, err error) {
|
||
|
p, err := radix.NewPool(cfg.NetworkType, cfg.Address, int(cfg.Size), cfg.Options...)
|
||
|
return RedisConn{p: p}, err
|
||
|
}
|
||
|
|
||
|
type ConnConfig struct {
|
||
|
NetworkType string
|
||
|
Address string
|
||
|
Size uint
|
||
|
Options []radix.PoolOpt
|
||
|
}
|
||
|
|
||
|
type RedisConn struct {
|
||
|
p *radix.Pool
|
||
|
}
|
||
|
|
||
|
func (conn RedisConn) GetAllMetadata(ctx context.Context, sourceHost string, errch chan<- error) (output <-chan types.Metadata) {
|
||
|
mdch := make(chan types.Metadata, 1)
|
||
|
|
||
|
go func() {
|
||
|
defer close(mdch)
|
||
|
|
||
|
var key string
|
||
|
scr := radix.NewScanner(conn.p, radix.ScanOpts{Command: scan, Pattern: sourceHost + star})
|
||
|
|
||
|
for scr.Next(&key) {
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
return
|
||
|
default:
|
||
|
var md types.Metadata
|
||
|
|
||
|
if err := conn.p.Do(radix.Cmd(&md, hGetAll, key)); err != nil {
|
||
|
errch <- err
|
||
|
return
|
||
|
}
|
||
|
|
||
|
mdch <- md
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
return mdch
|
||
|
}
|
||
|
|
||
|
func (conn RedisConn) Get(ctx context.Context, id string) (output types.Credential, err error) {
|
||
|
var key string
|
||
|
scr := radix.NewScanner(conn.p, radix.ScanOpts{Command: scan, Pattern: star + id, Count: 1})
|
||
|
|
||
|
if !scr.Next(&key) {
|
||
|
return output, nil
|
||
|
}
|
||
|
|
||
|
if err = scr.Close(); err != nil {
|
||
|
return output, err
|
||
|
}
|
||
|
|
||
|
err = conn.p.Do(radix.Cmd(&output, hGetAll, key))
|
||
|
|
||
|
return output, err
|
||
|
}
|
||
|
|
||
|
func (conn RedisConn) Put(ctx context.Context, c types.Credential) (err error) {
|
||
|
err = conn.p.Do(radix.FlatCmd(nil, hMSet, c.SourceHost+dash+c.ID, c))
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (conn RedisConn) Delete(ctx context.Context, id string) (err error) {
|
||
|
var key string
|
||
|
scr := radix.NewScanner(conn.p, radix.ScanOpts{Command: scan, Pattern: star + id, Count: 1})
|
||
|
|
||
|
if !scr.Next(&key) {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if err = scr.Close(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
err = conn.p.Do(radix.Cmd(nil, del, key))
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (conn RedisConn) DumpDB(ctx context.Context) (bs []byte, err error) {
|
||
|
bs = []byte{}
|
||
|
|
||
|
if err := conn.p.Do(radix.Cmd(&bs, "DUMP")); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return bs, nil
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
dash = "-"
|
||
|
star = "*"
|
||
|
scan = "SCAN"
|
||
|
hGetAll = "HGETALL"
|
||
|
hMSet = "HMSET"
|
||
|
del = "DEL"
|
||
|
)
|