2019-06-12 07:46:20 +01:00
|
|
|
package store
|
2019-06-11 17:20:52 +01:00
|
|
|
|
|
|
|
import (
|
2019-12-16 14:38:51 +00:00
|
|
|
"context"
|
2021-01-26 02:08:22 +03:00
|
|
|
"crypto/tls"
|
2020-03-12 13:41:30 +00:00
|
|
|
"time"
|
2020-08-29 17:44:49 +03:00
|
|
|
|
2021-10-02 19:55:07 +03:00
|
|
|
"go.unistack.org/micro/v3/codec"
|
|
|
|
"go.unistack.org/micro/v3/logger"
|
|
|
|
"go.unistack.org/micro/v3/metadata"
|
|
|
|
"go.unistack.org/micro/v3/meter"
|
2024-04-22 08:47:50 +03:00
|
|
|
"go.unistack.org/micro/v3/options"
|
2021-10-02 19:55:07 +03:00
|
|
|
"go.unistack.org/micro/v3/tracer"
|
2019-06-11 17:20:52 +01:00
|
|
|
)
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// Options contains configuration for the Store
|
2019-12-16 12:13:18 +00:00
|
|
|
type Options struct {
|
2021-03-06 19:45:13 +03:00
|
|
|
// Meter used for metrics
|
|
|
|
Meter meter.Meter
|
|
|
|
// Tracer used for tracing
|
|
|
|
Tracer tracer.Tracer
|
|
|
|
// Context holds external options
|
|
|
|
Context context.Context
|
|
|
|
// Codec used to marshal/unmarshal
|
|
|
|
Codec codec.Codec
|
|
|
|
// Logger used for logging
|
|
|
|
Logger logger.Logger
|
|
|
|
// TLSConfig holds tls.TLSConfig options
|
|
|
|
TLSConfig *tls.Config
|
2021-02-14 11:28:50 +03:00
|
|
|
// Name specifies store name
|
2021-01-29 13:17:32 +03:00
|
|
|
Name string
|
2021-07-14 17:11:37 +03:00
|
|
|
// Namespace of the records
|
|
|
|
Namespace string
|
2022-11-07 14:53:58 +03:00
|
|
|
// Separator used as key parts separator
|
|
|
|
Separator string
|
2021-07-14 17:11:37 +03:00
|
|
|
// Addrs contains store address
|
|
|
|
Addrs []string
|
2021-09-28 23:43:43 +03:00
|
|
|
// Wrappers store wrapper that called before actual functions
|
|
|
|
// Wrappers []Wrapper
|
2022-07-08 22:16:33 +03:00
|
|
|
// Timeout specifies timeout duration for all operations
|
|
|
|
Timeout time.Duration
|
2024-04-22 08:47:50 +03:00
|
|
|
// Hooks can be run before/after store Read/List/Write/Exists/Delete
|
|
|
|
Hooks options.Hooks
|
2024-11-26 12:18:17 +03:00
|
|
|
// LazyConnect creates a connection when using store
|
|
|
|
LazyConnect bool
|
2019-12-16 12:13:18 +00:00
|
|
|
}
|
|
|
|
|
2020-12-08 00:38:37 +03:00
|
|
|
// NewOptions creates options struct
|
2020-09-05 02:11:29 +03:00
|
|
|
func NewOptions(opts ...Option) Options {
|
|
|
|
options := Options{
|
2022-11-07 14:53:58 +03:00
|
|
|
Logger: logger.DefaultLogger,
|
|
|
|
Context: context.Background(),
|
|
|
|
Codec: codec.DefaultCodec,
|
|
|
|
Tracer: tracer.DefaultTracer,
|
|
|
|
Meter: meter.DefaultMeter,
|
|
|
|
Separator: DefaultSeparator,
|
2020-09-03 15:11:05 +03:00
|
|
|
}
|
2020-09-05 02:11:29 +03:00
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return options
|
2020-09-03 15:11:05 +03:00
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// Option sets values in Options
|
2019-12-16 14:38:51 +00:00
|
|
|
type Option func(o *Options)
|
|
|
|
|
2021-01-26 02:08:22 +03:00
|
|
|
// TLSConfig specifies a *tls.Config
|
|
|
|
func TLSConfig(t *tls.Config) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.TLSConfig = t
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-08 00:38:37 +03:00
|
|
|
// Context pass context to store
|
2020-10-16 09:38:57 +03:00
|
|
|
func Context(ctx context.Context) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Context = ctx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-10 22:08:56 +03:00
|
|
|
// Codec sets the codec
|
|
|
|
func Codec(c codec.Codec) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Codec = c
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-29 17:44:49 +03:00
|
|
|
// Logger sets the logger
|
|
|
|
func Logger(l logger.Logger) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Logger = l
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-22 23:32:33 +03:00
|
|
|
// Meter sets the meter
|
|
|
|
func Meter(m meter.Meter) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Meter = m
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// Name the name of the store
|
2021-01-29 14:02:54 +03:00
|
|
|
func Name(n string) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Name = n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-07 14:53:58 +03:00
|
|
|
// Separator the value used as key parts separator
|
|
|
|
func Separator(s string) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Separator = s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// Namespace sets namespace of the store
|
|
|
|
func Namespace(ns string) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Namespace = ns
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-22 23:32:33 +03:00
|
|
|
// Tracer sets the tracer
|
|
|
|
func Tracer(t tracer.Tracer) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Tracer = t
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-08 22:16:33 +03:00
|
|
|
// Timeout sets the timeout
|
|
|
|
func Timeout(td time.Duration) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.Timeout = td
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-26 17:48:09 +03:00
|
|
|
// LazyConnect initialize connection only when needed
|
|
|
|
func LazyConnect(b bool) Option {
|
|
|
|
return func(o *Options) {
|
|
|
|
o.LazyConnect = b
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// Addrs contains the addresses or other connection information of the backing storage.
|
2020-03-12 13:41:30 +00:00
|
|
|
// For example, an etcd implementation would contain the nodes of the cluster.
|
|
|
|
// A SQL implementation could contain one or more connection strings.
|
2021-07-14 17:11:37 +03:00
|
|
|
func Addrs(addrs ...string) Option {
|
2019-12-16 14:38:51 +00:00
|
|
|
return func(o *Options) {
|
2021-07-14 17:11:37 +03:00
|
|
|
o.Addrs = addrs
|
2019-12-16 14:38:51 +00:00
|
|
|
}
|
2019-06-11 17:20:52 +01:00
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ReadOptions configures an individual Read operation
|
|
|
|
type ReadOptions struct {
|
|
|
|
// Context holds external options
|
|
|
|
Context context.Context
|
|
|
|
// Namespace holds namespace
|
|
|
|
Namespace string
|
2024-04-13 12:52:06 +03:00
|
|
|
// Name holds mnemonic name
|
|
|
|
Name string
|
|
|
|
// Timeout specifies max timeout for operation
|
|
|
|
Timeout time.Duration
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
|
2020-12-10 22:37:40 +03:00
|
|
|
// NewReadOptions fills ReadOptions struct with opts slice
|
|
|
|
func NewReadOptions(opts ...ReadOption) ReadOptions {
|
|
|
|
options := ReadOptions{}
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return options
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// ReadOption sets values in ReadOptions
|
|
|
|
type ReadOption func(r *ReadOptions)
|
|
|
|
|
2024-04-13 12:52:06 +03:00
|
|
|
// ReadTimeout pass timeout to ReadOptions
|
|
|
|
func ReadTimeout(td time.Duration) ReadOption {
|
|
|
|
return func(o *ReadOptions) {
|
|
|
|
o.Timeout = td
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReadName pass name to ReadOptions
|
|
|
|
func ReadName(name string) ReadOption {
|
|
|
|
return func(o *ReadOptions) {
|
|
|
|
o.Name = name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ReadContext pass context.Context to ReadOptions
|
|
|
|
func ReadContext(ctx context.Context) ReadOption {
|
|
|
|
return func(o *ReadOptions) {
|
|
|
|
o.Context = ctx
|
2020-04-09 17:56:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ReadNamespace pass namespace to ReadOptions
|
|
|
|
func ReadNamespace(ns string) ReadOption {
|
|
|
|
return func(o *ReadOptions) {
|
|
|
|
o.Namespace = ns
|
2020-12-10 22:37:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// WriteOptions configures an individual Write operation
|
|
|
|
type WriteOptions struct {
|
2021-03-06 19:45:13 +03:00
|
|
|
// Context holds external options
|
|
|
|
Context context.Context
|
|
|
|
// Metadata contains additional metadata
|
|
|
|
Metadata metadata.Metadata
|
|
|
|
// Namespace holds namespace
|
2021-01-26 02:08:22 +03:00
|
|
|
Namespace string
|
2024-04-13 12:52:06 +03:00
|
|
|
// Name holds mnemonic name
|
|
|
|
Name string
|
|
|
|
// Timeout specifies max timeout for operation
|
|
|
|
Timeout time.Duration
|
2021-03-06 19:45:13 +03:00
|
|
|
// TTL specifies key TTL
|
|
|
|
TTL time.Duration
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// NewWriteOptions fills WriteOptions struct with opts slice
|
|
|
|
func NewWriteOptions(opts ...WriteOption) WriteOptions {
|
|
|
|
options := WriteOptions{}
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return options
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// WriteOption sets values in WriteOptions
|
|
|
|
type WriteOption func(w *WriteOptions)
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// WriteContext pass context.Context to wirte options
|
|
|
|
func WriteContext(ctx context.Context) WriteOption {
|
|
|
|
return func(o *WriteOptions) {
|
|
|
|
o.Context = ctx
|
2020-04-09 17:56:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// WriteMetadata add metadata.Metadata
|
|
|
|
func WriteMetadata(md metadata.Metadata) WriteOption {
|
|
|
|
return func(o *WriteOptions) {
|
|
|
|
o.Metadata = metadata.Copy(md)
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// WriteTTL is the time the record expires
|
|
|
|
func WriteTTL(d time.Duration) WriteOption {
|
|
|
|
return func(o *WriteOptions) {
|
|
|
|
o.TTL = d
|
2020-12-10 22:08:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// WriteNamespace pass namespace to write options
|
|
|
|
func WriteNamespace(ns string) WriteOption {
|
|
|
|
return func(o *WriteOptions) {
|
|
|
|
o.Namespace = ns
|
2020-12-10 22:37:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-13 12:52:06 +03:00
|
|
|
// WriteName pass name to WriteOptions
|
|
|
|
func WriteName(name string) WriteOption {
|
|
|
|
return func(o *WriteOptions) {
|
|
|
|
o.Name = name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WriteTimeout pass timeout to WriteOptions
|
|
|
|
func WriteTimeout(td time.Duration) WriteOption {
|
|
|
|
return func(o *WriteOptions) {
|
|
|
|
o.Timeout = td
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// DeleteOptions configures an individual Delete operation
|
2020-04-09 17:56:13 +01:00
|
|
|
type DeleteOptions struct {
|
2021-03-06 19:45:13 +03:00
|
|
|
// Context holds external options
|
|
|
|
Context context.Context
|
|
|
|
// Namespace holds namespace
|
2021-01-26 02:08:22 +03:00
|
|
|
Namespace string
|
2024-04-13 12:52:06 +03:00
|
|
|
// Name holds mnemonic name
|
|
|
|
Name string
|
|
|
|
// Timeout specifies max timeout for operation
|
|
|
|
Timeout time.Duration
|
2020-04-09 17:56:13 +01:00
|
|
|
}
|
2020-03-12 13:41:30 +00:00
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// NewDeleteOptions fills DeleteOptions struct with opts slice
|
|
|
|
func NewDeleteOptions(opts ...DeleteOption) DeleteOptions {
|
|
|
|
options := DeleteOptions{}
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return options
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// DeleteOption sets values in DeleteOptions
|
|
|
|
type DeleteOption func(d *DeleteOptions)
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// DeleteContext pass context.Context to delete options
|
|
|
|
func DeleteContext(ctx context.Context) DeleteOption {
|
|
|
|
return func(o *DeleteOptions) {
|
|
|
|
o.Context = ctx
|
2020-04-09 17:56:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// DeleteNamespace pass namespace to delete options
|
|
|
|
func DeleteNamespace(ns string) DeleteOption {
|
|
|
|
return func(o *DeleteOptions) {
|
|
|
|
o.Namespace = ns
|
2020-12-10 22:37:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-13 12:52:06 +03:00
|
|
|
// DeleteName pass name to DeleteOptions
|
|
|
|
func DeleteName(name string) DeleteOption {
|
|
|
|
return func(o *DeleteOptions) {
|
|
|
|
o.Name = name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteTimeout pass timeout to DeleteOptions
|
|
|
|
func DeleteTimeout(td time.Duration) DeleteOption {
|
|
|
|
return func(o *DeleteOptions) {
|
|
|
|
o.Timeout = td
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// ListOptions configures an individual List operation
|
|
|
|
type ListOptions struct {
|
2021-01-26 02:08:22 +03:00
|
|
|
Context context.Context
|
2021-03-06 19:45:13 +03:00
|
|
|
Prefix string
|
|
|
|
Suffix string
|
|
|
|
Namespace string
|
2024-04-13 12:52:06 +03:00
|
|
|
// Name holds mnemonic name
|
|
|
|
Name string
|
|
|
|
Limit uint
|
|
|
|
Offset uint
|
|
|
|
// Timeout specifies max timeout for operation
|
|
|
|
Timeout time.Duration
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// NewListOptions fills ListOptions struct with opts slice
|
|
|
|
func NewListOptions(opts ...ListOption) ListOptions {
|
|
|
|
options := ListOptions{}
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return options
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// ListOption sets values in ListOptions
|
|
|
|
type ListOption func(l *ListOptions)
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ListContext pass context.Context to list options
|
|
|
|
func ListContext(ctx context.Context) ListOption {
|
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Context = ctx
|
2020-04-09 17:56:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// ListPrefix returns all keys that are prefixed with key
|
2021-07-14 17:11:37 +03:00
|
|
|
func ListPrefix(s string) ListOption {
|
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Prefix = s
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListSuffix returns all keys that end with key
|
|
|
|
func ListSuffix(s string) ListOption {
|
2021-07-14 17:11:37 +03:00
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Suffix = s
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ListLimit limits the number of returned keys
|
|
|
|
func ListLimit(n uint) ListOption {
|
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Limit = n
|
2020-03-12 13:41:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ListOffset use with Limit for pagination
|
|
|
|
func ListOffset(n uint) ListOption {
|
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Offset = n
|
2020-02-03 08:16:02 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-26 02:08:22 +03:00
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ListNamespace pass namespace to list options
|
|
|
|
func ListNamespace(ns string) ListOption {
|
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Namespace = ns
|
|
|
|
}
|
|
|
|
}
|
2021-01-26 02:08:22 +03:00
|
|
|
|
2024-04-13 12:52:06 +03:00
|
|
|
// ListTimeout pass timeout to ListOptions
|
|
|
|
func ListTimeout(td time.Duration) ListOption {
|
|
|
|
return func(o *ListOptions) {
|
|
|
|
o.Timeout = td
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-14 11:28:50 +03:00
|
|
|
// ExistsOptions holds options for Exists method
|
2021-01-26 02:08:22 +03:00
|
|
|
type ExistsOptions struct {
|
2021-03-06 19:45:13 +03:00
|
|
|
// Context holds external options
|
|
|
|
Context context.Context
|
|
|
|
// Namespace contains namespace
|
2021-01-26 02:08:22 +03:00
|
|
|
Namespace string
|
2024-04-13 12:52:06 +03:00
|
|
|
// Name holds mnemonic name
|
|
|
|
Name string
|
|
|
|
// Timeout specifies max timeout for operation
|
|
|
|
Timeout time.Duration
|
2021-01-26 02:08:22 +03:00
|
|
|
}
|
|
|
|
|
2021-07-14 17:11:37 +03:00
|
|
|
// ExistsOption specifies Exists call options
|
|
|
|
type ExistsOption func(*ExistsOptions)
|
|
|
|
|
2021-02-14 11:28:50 +03:00
|
|
|
// NewExistsOptions helper for Exists method
|
2021-01-26 02:08:22 +03:00
|
|
|
func NewExistsOptions(opts ...ExistsOption) ExistsOptions {
|
|
|
|
options := ExistsOptions{
|
|
|
|
Context: context.Background(),
|
|
|
|
}
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return options
|
|
|
|
}
|
2021-07-14 17:11:37 +03:00
|
|
|
|
|
|
|
// ExistsContext pass context.Context to exist options
|
|
|
|
func ExistsContext(ctx context.Context) ExistsOption {
|
|
|
|
return func(o *ExistsOptions) {
|
|
|
|
o.Context = ctx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExistsNamespace pass namespace to exist options
|
|
|
|
func ExistsNamespace(ns string) ExistsOption {
|
|
|
|
return func(o *ExistsOptions) {
|
|
|
|
o.Namespace = ns
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-13 12:52:06 +03:00
|
|
|
// ExistsName pass name to exist options
|
|
|
|
func ExistsName(name string) ExistsOption {
|
|
|
|
return func(o *ExistsOptions) {
|
|
|
|
o.Name = name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExistsTimeout timeout to ListOptions
|
|
|
|
func ExistsTimeout(td time.Duration) ExistsOption {
|
|
|
|
return func(o *ExistsOptions) {
|
|
|
|
o.Timeout = td
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-22 08:47:50 +03:00
|
|
|
// Hooks sets hook runs before action
|
|
|
|
func Hooks(h ...options.Hook) Option {
|
2021-09-30 20:32:59 +03:00
|
|
|
return func(o *Options) {
|
2024-04-22 08:47:50 +03:00
|
|
|
o.Hooks = append(o.Hooks, h...)
|
2021-09-30 20:32:59 +03:00
|
|
|
}
|
|
|
|
}
|