Add opts to service proto (#1517)
* Add opts to service proto * Support database/table opts
This commit is contained in:
parent
fccab8ad27
commit
359b8bc503
@ -7,6 +7,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
@ -21,214 +22,51 @@ var (
|
|||||||
DefaultTable = "micro"
|
DefaultTable = "micro"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
statements = map[string]string{
|
||||||
|
"list": "SELECT key, value, expiry FROM %s.%s;",
|
||||||
|
"read": "SELECT key, value, expiry FROM %s.%s WHERE key = $1;",
|
||||||
|
"readMany": "SELECT key, value, expiry FROM %s.%s WHERE key LIKE $1;",
|
||||||
|
"readOffset": "SELECT key, value, expiry FROM %s.%s WHERE key LIKE $1 ORDER BY key DESC LIMIT $2 OFFSET $3;",
|
||||||
|
"write": "INSERT INTO %s.%s(key, value, expiry) VALUES ($1, $2::bytea, $3) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, expiry = EXCLUDED.expiry;",
|
||||||
|
"delete": "DELETE FROM %s.%s WHERE key = $1;",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type sqlStore struct {
|
type sqlStore struct {
|
||||||
|
options store.Options
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
|
||||||
database string
|
sync.RWMutex
|
||||||
table string
|
// known databases
|
||||||
|
databases map[string]bool
|
||||||
list *sql.Stmt
|
|
||||||
readOne *sql.Stmt
|
|
||||||
readMany *sql.Stmt
|
|
||||||
readOffset *sql.Stmt
|
|
||||||
write *sql.Stmt
|
|
||||||
delete *sql.Stmt
|
|
||||||
|
|
||||||
options store.Options
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sqlStore) Close() error {
|
func (s *sqlStore) createDB(database, table string) {
|
||||||
closeStmt(s.delete)
|
if len(database) == 0 {
|
||||||
closeStmt(s.list)
|
database = s.options.Database
|
||||||
closeStmt(s.readMany)
|
|
||||||
closeStmt(s.readOffset)
|
|
||||||
closeStmt(s.readOne)
|
|
||||||
closeStmt(s.write)
|
|
||||||
if s.db != nil {
|
|
||||||
return s.db.Close()
|
|
||||||
}
|
}
|
||||||
return nil
|
if len(table) == 0 {
|
||||||
|
table = s.options.Table
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sqlStore) Init(opts ...store.Option) error {
|
s.Lock()
|
||||||
for _, o := range opts {
|
_, ok := s.databases[database+":"+table]
|
||||||
o(&s.options)
|
if !ok {
|
||||||
|
s.initDB(database, table)
|
||||||
|
s.databases[database+":"+table] = true
|
||||||
}
|
}
|
||||||
// reconfigure
|
s.Unlock()
|
||||||
return s.configure()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all the known records
|
func (s *sqlStore) initDB(database, table string) error {
|
||||||
func (s *sqlStore) List(opts ...store.ListOption) ([]string, error) {
|
|
||||||
rows, err := s.list.Query()
|
|
||||||
var keys []string
|
|
||||||
var timehelper pq.NullTime
|
|
||||||
if err != nil {
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return keys, nil
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
for rows.Next() {
|
|
||||||
record := &store.Record{}
|
|
||||||
if err := rows.Scan(&record.Key, &record.Value, &timehelper); err != nil {
|
|
||||||
return keys, err
|
|
||||||
}
|
|
||||||
if timehelper.Valid {
|
|
||||||
if timehelper.Time.Before(time.Now()) {
|
|
||||||
// record has expired
|
|
||||||
go s.Delete(record.Key)
|
|
||||||
} else {
|
|
||||||
record.Expiry = time.Until(timehelper.Time)
|
|
||||||
keys = append(keys, record.Key)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
keys = append(keys, record.Key)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
rowErr := rows.Close()
|
|
||||||
if rowErr != nil {
|
|
||||||
// transaction rollback or something
|
|
||||||
return keys, rowErr
|
|
||||||
}
|
|
||||||
if err := rows.Err(); err != nil {
|
|
||||||
return keys, err
|
|
||||||
}
|
|
||||||
return keys, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read a single key
|
|
||||||
func (s *sqlStore) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) {
|
|
||||||
var options store.ReadOptions
|
|
||||||
for _, o := range opts {
|
|
||||||
o(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.Prefix || options.Suffix {
|
|
||||||
return s.read(key, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
var records []*store.Record
|
|
||||||
var timehelper pq.NullTime
|
|
||||||
|
|
||||||
row := s.readOne.QueryRow(key)
|
|
||||||
record := &store.Record{}
|
|
||||||
if err := row.Scan(&record.Key, &record.Value, &timehelper); err != nil {
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return records, store.ErrNotFound
|
|
||||||
}
|
|
||||||
return records, err
|
|
||||||
}
|
|
||||||
if timehelper.Valid {
|
|
||||||
if timehelper.Time.Before(time.Now()) {
|
|
||||||
// record has expired
|
|
||||||
go s.Delete(key)
|
|
||||||
return records, store.ErrNotFound
|
|
||||||
}
|
|
||||||
record.Expiry = time.Until(timehelper.Time)
|
|
||||||
records = append(records, record)
|
|
||||||
} else {
|
|
||||||
records = append(records, record)
|
|
||||||
}
|
|
||||||
|
|
||||||
return records, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read Many records
|
|
||||||
func (s *sqlStore) read(key string, options store.ReadOptions) ([]*store.Record, error) {
|
|
||||||
pattern := "%"
|
|
||||||
if options.Prefix {
|
|
||||||
pattern = key + pattern
|
|
||||||
}
|
|
||||||
if options.Suffix {
|
|
||||||
pattern = pattern + key
|
|
||||||
}
|
|
||||||
var rows *sql.Rows
|
|
||||||
var err error
|
|
||||||
if options.Limit != 0 {
|
|
||||||
rows, err = s.readOffset.Query(pattern, options.Limit, options.Offset)
|
|
||||||
} else {
|
|
||||||
rows, err = s.readMany.Query(pattern)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return []*store.Record{}, nil
|
|
||||||
}
|
|
||||||
return []*store.Record{}, errors.Wrap(err, "sqlStore.read failed")
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
var records []*store.Record
|
|
||||||
var timehelper pq.NullTime
|
|
||||||
|
|
||||||
for rows.Next() {
|
|
||||||
record := &store.Record{}
|
|
||||||
if err := rows.Scan(&record.Key, &record.Value, &timehelper); err != nil {
|
|
||||||
return records, err
|
|
||||||
}
|
|
||||||
if timehelper.Valid {
|
|
||||||
if timehelper.Time.Before(time.Now()) {
|
|
||||||
// record has expired
|
|
||||||
go s.Delete(record.Key)
|
|
||||||
} else {
|
|
||||||
record.Expiry = time.Until(timehelper.Time)
|
|
||||||
records = append(records, record)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
records = append(records, record)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rowErr := rows.Close()
|
|
||||||
if rowErr != nil {
|
|
||||||
// transaction rollback or something
|
|
||||||
return records, rowErr
|
|
||||||
}
|
|
||||||
if err := rows.Err(); err != nil {
|
|
||||||
return records, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return records, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write records
|
|
||||||
func (s *sqlStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
|
||||||
var err error
|
|
||||||
if r.Expiry != 0 {
|
|
||||||
_, err = s.write.Exec(r.Key, r.Value, time.Now().Add(r.Expiry))
|
|
||||||
} else {
|
|
||||||
_, err = s.write.Exec(r.Key, r.Value, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "Couldn't insert record "+r.Key)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete records with keys
|
|
||||||
func (s *sqlStore) Delete(key string, opts ...store.DeleteOption) error {
|
|
||||||
result, err := s.delete.Exec(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = result.RowsAffected()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sqlStore) initDB() error {
|
|
||||||
// Create the namespace's database
|
// Create the namespace's database
|
||||||
_, err := s.db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s ;", s.database))
|
_, err := s.db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s ;", database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.db.Exec(fmt.Sprintf("SET DATABASE = %s ;", s.database))
|
_, err = s.db.Exec(fmt.Sprintf("SET DATABASE = %s ;", database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Couldn't set database")
|
return errors.Wrap(err, "Couldn't set database")
|
||||||
}
|
}
|
||||||
@ -240,58 +78,17 @@ func (s *sqlStore) initDB() error {
|
|||||||
value bytea,
|
value bytea,
|
||||||
expiry timestamp with time zone,
|
expiry timestamp with time zone,
|
||||||
CONSTRAINT %s_pkey PRIMARY KEY (key)
|
CONSTRAINT %s_pkey PRIMARY KEY (key)
|
||||||
);`, s.table, s.table))
|
);`, table, table))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Couldn't create table")
|
return errors.Wrap(err, "Couldn't create table")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Index
|
// Create Index
|
||||||
_, err = s.db.Exec(fmt.Sprintf(`CREATE INDEX IF NOT EXISTS "%s" ON %s.%s USING btree ("key");`, "key_index_"+s.table, s.database, s.table))
|
_, err = s.db.Exec(fmt.Sprintf(`CREATE INDEX IF NOT EXISTS "%s" ON %s.%s USING btree ("key");`, "key_index_"+table, database, table))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
list, err := s.db.Prepare(fmt.Sprintf("SELECT key, value, expiry FROM %s.%s;", s.database, s.table))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "List statement couldn't be prepared")
|
|
||||||
}
|
|
||||||
closeStmt(s.list)
|
|
||||||
s.list = list
|
|
||||||
readOne, err := s.db.Prepare(fmt.Sprintf("SELECT key, value, expiry FROM %s.%s WHERE key = $1;", s.database, s.table))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "ReadOne statement couldn't be prepared")
|
|
||||||
}
|
|
||||||
closeStmt(s.readOne)
|
|
||||||
s.readOne = readOne
|
|
||||||
readMany, err := s.db.Prepare(fmt.Sprintf("SELECT key, value, expiry FROM %s.%s WHERE key LIKE $1;", s.database, s.table))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "ReadMany statement couldn't be prepared")
|
|
||||||
}
|
|
||||||
closeStmt(s.readMany)
|
|
||||||
s.readMany = readMany
|
|
||||||
readOffset, err := s.db.Prepare(fmt.Sprintf("SELECT key, value, expiry FROM %s.%s WHERE key LIKE $1 ORDER BY key DESC LIMIT $2 OFFSET $3;", s.database, s.table))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "ReadOffset statement couldn't be prepared")
|
|
||||||
}
|
|
||||||
closeStmt(s.readOffset)
|
|
||||||
s.readOffset = readOffset
|
|
||||||
write, err := s.db.Prepare(fmt.Sprintf(`INSERT INTO %s.%s(key, value, expiry)
|
|
||||||
VALUES ($1, $2::bytea, $3)
|
|
||||||
ON CONFLICT (key)
|
|
||||||
DO UPDATE
|
|
||||||
SET value = EXCLUDED.value, expiry = EXCLUDED.expiry;`, s.database, s.table))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "Write statement couldn't be prepared")
|
|
||||||
}
|
|
||||||
closeStmt(s.write)
|
|
||||||
s.write = write
|
|
||||||
delete, err := s.db.Prepare(fmt.Sprintf("DELETE FROM %s.%s WHERE key = $1;", s.database, s.table))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "Delete statement couldn't be prepared")
|
|
||||||
}
|
|
||||||
closeStmt(s.delete)
|
|
||||||
s.delete = delete
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,21 +141,286 @@ func (s *sqlStore) configure() error {
|
|||||||
|
|
||||||
// save the values
|
// save the values
|
||||||
s.db = db
|
s.db = db
|
||||||
s.database = database
|
|
||||||
s.table = table
|
|
||||||
|
|
||||||
// initialise the database
|
// initialise the database
|
||||||
return s.initDB()
|
return s.initDB(s.options.Database, s.options.Table)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sqlStore) String() string {
|
func (s *sqlStore) prepare(database, table, query string) (*sql.Stmt, error) {
|
||||||
return "cockroach"
|
st, ok := statements[query]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("unsupported statement")
|
||||||
|
}
|
||||||
|
if len(database) == 0 {
|
||||||
|
database = s.options.Database
|
||||||
|
}
|
||||||
|
if len(table) == 0 {
|
||||||
|
table = s.options.Table
|
||||||
|
}
|
||||||
|
|
||||||
|
q := fmt.Sprintf(st, database, table)
|
||||||
|
stmt, err := s.db.Prepare(q)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return stmt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) Close() error {
|
||||||
|
if s.db != nil {
|
||||||
|
return s.db.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) Init(opts ...store.Option) error {
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&s.options)
|
||||||
|
}
|
||||||
|
// reconfigure
|
||||||
|
return s.configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all the known records
|
||||||
|
func (s *sqlStore) List(opts ...store.ListOption) ([]string, error) {
|
||||||
|
var options store.ListOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the db if not exists
|
||||||
|
s.createDB(options.Database, options.Table)
|
||||||
|
|
||||||
|
st, err := s.prepare(options.Database, options.Table, "list")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
rows, err := st.Query()
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var keys []string
|
||||||
|
var timehelper pq.NullTime
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
record := &store.Record{}
|
||||||
|
if err := rows.Scan(&record.Key, &record.Value, &timehelper); err != nil {
|
||||||
|
return keys, err
|
||||||
|
}
|
||||||
|
if timehelper.Valid {
|
||||||
|
if timehelper.Time.Before(time.Now()) {
|
||||||
|
// record has expired
|
||||||
|
go s.Delete(record.Key)
|
||||||
|
} else {
|
||||||
|
record.Expiry = time.Until(timehelper.Time)
|
||||||
|
keys = append(keys, record.Key)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keys = append(keys, record.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
rowErr := rows.Close()
|
||||||
|
if rowErr != nil {
|
||||||
|
// transaction rollback or something
|
||||||
|
return keys, rowErr
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return keys, err
|
||||||
|
}
|
||||||
|
return keys, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a single key
|
||||||
|
func (s *sqlStore) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) {
|
||||||
|
var options store.ReadOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the db if not exists
|
||||||
|
s.createDB(options.Database, options.Table)
|
||||||
|
|
||||||
|
if options.Prefix || options.Suffix {
|
||||||
|
return s.read(key, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
var records []*store.Record
|
||||||
|
var timehelper pq.NullTime
|
||||||
|
|
||||||
|
st, err := s.prepare(options.Database, options.Table, "read")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
row := st.QueryRow(key)
|
||||||
|
record := &store.Record{}
|
||||||
|
if err := row.Scan(&record.Key, &record.Value, &timehelper); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return records, store.ErrNotFound
|
||||||
|
}
|
||||||
|
return records, err
|
||||||
|
}
|
||||||
|
if timehelper.Valid {
|
||||||
|
if timehelper.Time.Before(time.Now()) {
|
||||||
|
// record has expired
|
||||||
|
go s.Delete(key)
|
||||||
|
return records, store.ErrNotFound
|
||||||
|
}
|
||||||
|
record.Expiry = time.Until(timehelper.Time)
|
||||||
|
records = append(records, record)
|
||||||
|
} else {
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Many records
|
||||||
|
func (s *sqlStore) read(key string, options store.ReadOptions) ([]*store.Record, error) {
|
||||||
|
pattern := "%"
|
||||||
|
if options.Prefix {
|
||||||
|
pattern = key + pattern
|
||||||
|
}
|
||||||
|
if options.Suffix {
|
||||||
|
pattern = pattern + key
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows *sql.Rows
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if options.Limit != 0 {
|
||||||
|
st, err := s.prepare(options.Database, options.Table, "readOffset")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
rows, err = st.Query(pattern, options.Limit, options.Offset)
|
||||||
|
} else {
|
||||||
|
st, err := s.prepare(options.Database, options.Table, "readMany")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
rows, err = st.Query(pattern)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return []*store.Record{}, nil
|
||||||
|
}
|
||||||
|
return []*store.Record{}, errors.Wrap(err, "sqlStore.read failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var records []*store.Record
|
||||||
|
var timehelper pq.NullTime
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
record := &store.Record{}
|
||||||
|
if err := rows.Scan(&record.Key, &record.Value, &timehelper); err != nil {
|
||||||
|
return records, err
|
||||||
|
}
|
||||||
|
if timehelper.Valid {
|
||||||
|
if timehelper.Time.Before(time.Now()) {
|
||||||
|
// record has expired
|
||||||
|
go s.Delete(record.Key)
|
||||||
|
} else {
|
||||||
|
record.Expiry = time.Until(timehelper.Time)
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rowErr := rows.Close()
|
||||||
|
if rowErr != nil {
|
||||||
|
// transaction rollback or something
|
||||||
|
return records, rowErr
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return records, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write records
|
||||||
|
func (s *sqlStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
||||||
|
var options store.WriteOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the db if not exists
|
||||||
|
s.createDB(options.Database, options.Table)
|
||||||
|
|
||||||
|
st, err := s.prepare(options.Database, options.Table, "write")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
if r.Expiry != 0 {
|
||||||
|
_, err = st.Exec(r.Key, r.Value, time.Now().Add(r.Expiry))
|
||||||
|
} else {
|
||||||
|
_, err = st.Exec(r.Key, r.Value, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Couldn't insert record "+r.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete records with keys
|
||||||
|
func (s *sqlStore) Delete(key string, opts ...store.DeleteOption) error {
|
||||||
|
var options store.DeleteOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the db if not exists
|
||||||
|
s.createDB(options.Database, options.Table)
|
||||||
|
|
||||||
|
st, err := s.prepare(options.Database, options.Table, "delete")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
result, err := st.Exec(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sqlStore) Options() store.Options {
|
func (s *sqlStore) Options() store.Options {
|
||||||
return s.options
|
return s.options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *sqlStore) String() string {
|
||||||
|
return "cockroach"
|
||||||
|
}
|
||||||
|
|
||||||
// NewStore returns a new micro Store backed by sql
|
// NewStore returns a new micro Store backed by sql
|
||||||
func NewStore(opts ...store.Option) store.Store {
|
func NewStore(opts ...store.Option) store.Store {
|
||||||
var options store.Options
|
var options store.Options
|
||||||
@ -370,16 +432,11 @@ func NewStore(opts ...store.Option) store.Store {
|
|||||||
s := new(sqlStore)
|
s := new(sqlStore)
|
||||||
// set the options
|
// set the options
|
||||||
s.options = options
|
s.options = options
|
||||||
|
// mark known databases
|
||||||
|
s.databases = make(map[string]bool)
|
||||||
// best-effort configure the store
|
// best-effort configure the store
|
||||||
s.configure()
|
s.configure()
|
||||||
|
|
||||||
// return store
|
// return store
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeStmt(s *sql.Stmt) {
|
|
||||||
if s != nil {
|
|
||||||
s.Close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -7,10 +7,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/micro/go-micro/v2/store"
|
"github.com/micro/go-micro/v2/store"
|
||||||
"github.com/pkg/errors"
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,7 +29,9 @@ var (
|
|||||||
|
|
||||||
// NewStore returns a memory store
|
// NewStore returns a memory store
|
||||||
func NewStore(opts ...store.Option) store.Store {
|
func NewStore(opts ...store.Option) store.Store {
|
||||||
s := &fileStore{}
|
s := &fileStore{
|
||||||
|
handles: make(map[string]*fileHandle),
|
||||||
|
}
|
||||||
s.init(opts...)
|
s.init(opts...)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -37,9 +39,14 @@ func NewStore(opts ...store.Option) store.Store {
|
|||||||
type fileStore struct {
|
type fileStore struct {
|
||||||
options store.Options
|
options store.Options
|
||||||
dir string
|
dir string
|
||||||
fileName string
|
|
||||||
dbPath string
|
|
||||||
// the database handle
|
// the database handle
|
||||||
|
sync.RWMutex
|
||||||
|
handles map[string]*fileHandle
|
||||||
|
}
|
||||||
|
|
||||||
|
type fileHandle struct {
|
||||||
|
key string
|
||||||
db *bolt.DB
|
db *bolt.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +57,12 @@ type record struct {
|
|||||||
ExpiresAt time.Time
|
ExpiresAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) delete(key string) error {
|
func key(database, table string) string {
|
||||||
return m.db.Update(func(tx *bolt.Tx) error {
|
return database + ":" + table
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *fileStore) delete(fd *fileHandle, key string) error {
|
||||||
|
return fd.db.Update(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte(dataBucket))
|
b := tx.Bucket([]byte(dataBucket))
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -76,42 +87,63 @@ func (m *fileStore) init(opts ...store.Option) error {
|
|||||||
|
|
||||||
// create a directory /tmp/micro
|
// create a directory /tmp/micro
|
||||||
dir := filepath.Join(DefaultDir, m.options.Database)
|
dir := filepath.Join(DefaultDir, m.options.Database)
|
||||||
// create the database handle
|
|
||||||
fname := m.options.Table + ".db"
|
|
||||||
// Ignoring this as the folder might exist.
|
// Ignoring this as the folder might exist.
|
||||||
// Reads/Writes updates will return with sensible error messages
|
// Reads/Writes updates will return with sensible error messages
|
||||||
// about the dir not existing in case this cannot create the path anyway
|
// about the dir not existing in case this cannot create the path anyway
|
||||||
os.MkdirAll(dir, 0700)
|
os.MkdirAll(dir, 0700)
|
||||||
|
|
||||||
m.dir = dir
|
return nil
|
||||||
m.fileName = fname
|
|
||||||
m.dbPath = filepath.Join(dir, fname)
|
|
||||||
|
|
||||||
// close existing handle
|
|
||||||
if m.db != nil {
|
|
||||||
m.db.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *fileStore) getDB(database, table string) (*fileHandle, error) {
|
||||||
|
if len(database) == 0 {
|
||||||
|
database = f.options.Database
|
||||||
|
}
|
||||||
|
if len(table) == 0 {
|
||||||
|
table = f.options.Table
|
||||||
|
}
|
||||||
|
|
||||||
|
k := key(database, table)
|
||||||
|
|
||||||
|
f.RLock()
|
||||||
|
fd, ok := f.handles[k]
|
||||||
|
f.RUnlock()
|
||||||
|
|
||||||
|
// return the file handle
|
||||||
|
if ok {
|
||||||
|
return fd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a directory /tmp/micro
|
||||||
|
dir := filepath.Join(DefaultDir, database)
|
||||||
|
// create the database handle
|
||||||
|
fname := table + ".db"
|
||||||
|
// make the dir
|
||||||
|
os.MkdirAll(dir, 0700)
|
||||||
|
// database path
|
||||||
|
dbPath := filepath.Join(dir, fname)
|
||||||
|
|
||||||
// create new db handle
|
// create new db handle
|
||||||
db, err := bolt.Open(m.dbPath, 0700, &bolt.Options{Timeout: 5 * time.Second})
|
db, err := bolt.Open(dbPath, 0700, &bolt.Options{Timeout: 5 * time.Second})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the new db
|
f.Lock()
|
||||||
m.db = db
|
fd = &fileHandle{
|
||||||
|
key: k,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
f.handles[k] = fd
|
||||||
|
f.Unlock()
|
||||||
|
|
||||||
// create the table
|
return fd, nil
|
||||||
return db.Update(func(tx *bolt.Tx) error {
|
|
||||||
_, err := tx.CreateBucketIfNotExists([]byte(dataBucket))
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) list(limit, offset uint) []string {
|
func (m *fileStore) list(fd *fileHandle, limit, offset uint) []string {
|
||||||
var allItems []string
|
var allItems []string
|
||||||
|
|
||||||
m.db.View(func(tx *bolt.Tx) error {
|
fd.db.View(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte(dataBucket))
|
b := tx.Bucket([]byte(dataBucket))
|
||||||
// nothing to read
|
// nothing to read
|
||||||
if b == nil {
|
if b == nil {
|
||||||
@ -162,10 +194,10 @@ func (m *fileStore) list(limit, offset uint) []string {
|
|||||||
return allKeys
|
return allKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) get(k string) (*store.Record, error) {
|
func (m *fileStore) get(fd *fileHandle, k string) (*store.Record, error) {
|
||||||
var value []byte
|
var value []byte
|
||||||
|
|
||||||
m.db.View(func(tx *bolt.Tx) error {
|
fd.db.View(func(tx *bolt.Tx) error {
|
||||||
// @todo this is still very experimental...
|
// @todo this is still very experimental...
|
||||||
b := tx.Bucket([]byte(dataBucket))
|
b := tx.Bucket([]byte(dataBucket))
|
||||||
if b == nil {
|
if b == nil {
|
||||||
@ -200,7 +232,7 @@ func (m *fileStore) get(k string) (*store.Record, error) {
|
|||||||
return newRecord, nil
|
return newRecord, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) set(r *store.Record) error {
|
func (m *fileStore) set(fd *fileHandle, r *store.Record) error {
|
||||||
// copy the incoming record and then
|
// copy the incoming record and then
|
||||||
// convert the expiry in to a hard timestamp
|
// convert the expiry in to a hard timestamp
|
||||||
item := &record{}
|
item := &record{}
|
||||||
@ -213,7 +245,7 @@ func (m *fileStore) set(r *store.Record) error {
|
|||||||
// marshal the data
|
// marshal the data
|
||||||
data, _ := json.Marshal(item)
|
data, _ := json.Marshal(item)
|
||||||
|
|
||||||
return m.db.Update(func(tx *bolt.Tx) error {
|
return fd.db.Update(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte(dataBucket))
|
b := tx.Bucket([]byte(dataBucket))
|
||||||
if b == nil {
|
if b == nil {
|
||||||
var err error
|
var err error
|
||||||
@ -226,53 +258,63 @@ func (m *fileStore) set(r *store.Record) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) Close() error {
|
func (f *fileStore) Close() error {
|
||||||
if m.db != nil {
|
f.Lock()
|
||||||
return m.db.Close()
|
defer f.Unlock()
|
||||||
|
for k, v := range f.handles {
|
||||||
|
v.db.Close()
|
||||||
|
delete(f.handles, k)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) Init(opts ...store.Option) error {
|
func (f *fileStore) Init(opts ...store.Option) error {
|
||||||
return m.init(opts...)
|
return f.init(opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) Delete(key string, opts ...store.DeleteOption) error {
|
func (m *fileStore) Delete(key string, opts ...store.DeleteOption) error {
|
||||||
deleteOptions := store.DeleteOptions{}
|
var deleteOptions store.DeleteOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&deleteOptions)
|
o(&deleteOptions)
|
||||||
}
|
}
|
||||||
return m.delete(key)
|
|
||||||
|
fd, err := m.getDB(deleteOptions.Database, deleteOptions.Table)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.delete(fd, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) {
|
func (m *fileStore) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) {
|
||||||
readOpts := store.ReadOptions{}
|
var readOpts store.ReadOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&readOpts)
|
o(&readOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd, err := m.getDB(readOpts.Database, readOpts.Table)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var keys []string
|
var keys []string
|
||||||
|
|
||||||
// Handle Prefix / suffix
|
// Handle Prefix / suffix
|
||||||
// TODO: do range scan here rather than listing all keys
|
// TODO: do range scan here rather than listing all keys
|
||||||
if readOpts.Prefix || readOpts.Suffix {
|
if readOpts.Prefix || readOpts.Suffix {
|
||||||
var opts []store.ListOption
|
// list the keys
|
||||||
if readOpts.Prefix {
|
k := m.list(fd, readOpts.Limit, readOpts.Offset)
|
||||||
opts = append(opts, store.ListPrefix(key))
|
|
||||||
}
|
|
||||||
if readOpts.Suffix {
|
|
||||||
opts = append(opts, store.ListSuffix(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
opts = append(opts, store.ListLimit(readOpts.Limit))
|
// check for prefix and suffix
|
||||||
opts = append(opts, store.ListOffset(readOpts.Offset))
|
for _, v := range k {
|
||||||
|
if readOpts.Prefix && !strings.HasPrefix(v, key) {
|
||||||
k, err := m.List(opts...)
|
continue
|
||||||
if err != nil {
|
}
|
||||||
return nil, errors.Wrap(err, "FileStore: Read couldn't List()")
|
if readOpts.Suffix && !strings.HasSuffix(v, key) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
keys = append(keys, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = k
|
|
||||||
} else {
|
} else {
|
||||||
keys = []string{key}
|
keys = []string{key}
|
||||||
}
|
}
|
||||||
@ -280,7 +322,7 @@ func (m *fileStore) Read(key string, opts ...store.ReadOption) ([]*store.Record,
|
|||||||
var results []*store.Record
|
var results []*store.Record
|
||||||
|
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
r, err := m.get(k)
|
r, err := m.get(fd, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
@ -291,11 +333,16 @@ func (m *fileStore) Read(key string, opts ...store.ReadOption) ([]*store.Record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
func (m *fileStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
||||||
writeOpts := store.WriteOptions{}
|
var writeOpts store.WriteOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&writeOpts)
|
o(&writeOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd, err := m.getDB(writeOpts.Database, writeOpts.Table)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(opts) > 0 {
|
if len(opts) > 0 {
|
||||||
// Copy the record before applying options, or the incoming record will be mutated
|
// Copy the record before applying options, or the incoming record will be mutated
|
||||||
newRecord := store.Record{}
|
newRecord := store.Record{}
|
||||||
@ -310,10 +357,10 @@ func (m *fileStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
|||||||
newRecord.Expiry = writeOpts.TTL
|
newRecord.Expiry = writeOpts.TTL
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.set(&newRecord)
|
return m.set(fd, &newRecord)
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.set(r)
|
return m.set(fd, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) Options() store.Options {
|
func (m *fileStore) Options() store.Options {
|
||||||
@ -321,14 +368,19 @@ func (m *fileStore) Options() store.Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *fileStore) List(opts ...store.ListOption) ([]string, error) {
|
func (m *fileStore) List(opts ...store.ListOption) ([]string, error) {
|
||||||
listOptions := store.ListOptions{}
|
var listOptions store.ListOptions
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&listOptions)
|
o(&listOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd, err := m.getDB(listOptions.Database, listOptions.Table)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// TODO apply prefix/suffix in range query
|
// TODO apply prefix/suffix in range query
|
||||||
allKeys := m.list(listOptions.Limit, listOptions.Offset)
|
allKeys := m.list(fd, listOptions.Limit, listOptions.Offset)
|
||||||
|
|
||||||
if len(listOptions.Prefix) > 0 {
|
if len(listOptions.Prefix) > 0 {
|
||||||
var prefixKeys []string
|
var prefixKeys []string
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
package memory
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/micro/go-micro/v2/store"
|
"github.com/micro/go-micro/v2/store"
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -15,7 +15,10 @@ import (
|
|||||||
// NewStore returns a memory store
|
// NewStore returns a memory store
|
||||||
func NewStore(opts ...store.Option) store.Store {
|
func NewStore(opts ...store.Option) store.Store {
|
||||||
s := &memoryStore{
|
s := &memoryStore{
|
||||||
options: store.Options{},
|
options: store.Options{
|
||||||
|
Database: "micro",
|
||||||
|
Table: "micro",
|
||||||
|
},
|
||||||
store: cache.New(cache.NoExpiration, 5*time.Minute),
|
store: cache.New(cache.NoExpiration, 5*time.Minute),
|
||||||
}
|
}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@ -30,6 +33,101 @@ type memoryStore struct {
|
|||||||
store *cache.Cache
|
store *cache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type internalRecord struct {
|
||||||
|
key string
|
||||||
|
value []byte
|
||||||
|
expiresAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryStore) key(prefix, key string) string {
|
||||||
|
return filepath.Join(prefix, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryStore) prefix(database, table string) string {
|
||||||
|
if len(database) == 0 {
|
||||||
|
database = m.options.Database
|
||||||
|
}
|
||||||
|
if len(table) == 0 {
|
||||||
|
table = m.options.Table
|
||||||
|
}
|
||||||
|
return filepath.Join(database, table)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryStore) get(prefix, key string) (*store.Record, error) {
|
||||||
|
key = m.key(prefix, key)
|
||||||
|
|
||||||
|
var storedRecord *internalRecord
|
||||||
|
r, found := m.store.Get(key)
|
||||||
|
if !found {
|
||||||
|
return nil, store.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
storedRecord, ok := r.(*internalRecord)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("Retrieved a non *internalRecord from the cache")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the record on the way out
|
||||||
|
newRecord := &store.Record{}
|
||||||
|
newRecord.Key = strings.TrimPrefix(storedRecord.key, prefix+"/")
|
||||||
|
newRecord.Value = make([]byte, len(storedRecord.value))
|
||||||
|
copy(newRecord.Value, storedRecord.value)
|
||||||
|
if !storedRecord.expiresAt.IsZero() {
|
||||||
|
newRecord.Expiry = time.Until(storedRecord.expiresAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newRecord, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryStore) set(prefix string, r *store.Record) {
|
||||||
|
key := m.key(prefix, r.Key)
|
||||||
|
|
||||||
|
// copy the incoming record and then
|
||||||
|
// convert the expiry in to a hard timestamp
|
||||||
|
i := &internalRecord{}
|
||||||
|
i.key = r.Key
|
||||||
|
i.value = make([]byte, len(r.Value))
|
||||||
|
copy(i.value, r.Value)
|
||||||
|
|
||||||
|
if r.Expiry != 0 {
|
||||||
|
i.expiresAt = time.Now().Add(r.Expiry)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.store.Set(key, i, r.Expiry)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryStore) delete(prefix, key string) {
|
||||||
|
key = m.key(prefix, key)
|
||||||
|
m.store.Delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryStore) list(prefix string, limit, offset uint) []string {
|
||||||
|
allItems := m.store.Items()
|
||||||
|
allKeys := make([]string, len(allItems))
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for k := range allItems {
|
||||||
|
if !strings.HasPrefix(k, prefix+"/") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allKeys[i] = strings.TrimPrefix(k, prefix+"/")
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit != 0 || offset != 0 {
|
||||||
|
sort.Slice(allKeys, func(i, j int) bool { return allKeys[i] < allKeys[j] })
|
||||||
|
min := func(i, j uint) uint {
|
||||||
|
if i < j {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
return j
|
||||||
|
}
|
||||||
|
return allKeys[offset:min(limit, uint(len(allKeys)))]
|
||||||
|
}
|
||||||
|
|
||||||
|
return allKeys
|
||||||
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Close() error {
|
func (m *memoryStore) Close() error {
|
||||||
m.store.Flush()
|
m.store.Flush()
|
||||||
return nil
|
return nil
|
||||||
@ -53,31 +151,33 @@ func (m *memoryStore) Read(key string, opts ...store.ReadOption) ([]*store.Recor
|
|||||||
o(&readOpts)
|
o(&readOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prefix := m.prefix(readOpts.Database, readOpts.Table)
|
||||||
|
|
||||||
var keys []string
|
var keys []string
|
||||||
|
|
||||||
// Handle Prefix / suffix
|
// Handle Prefix / suffix
|
||||||
if readOpts.Prefix || readOpts.Suffix {
|
if readOpts.Prefix || readOpts.Suffix {
|
||||||
var opts []store.ListOption
|
k := m.list(prefix, readOpts.Limit, readOpts.Offset)
|
||||||
if readOpts.Prefix {
|
|
||||||
opts = append(opts, store.ListPrefix(key))
|
for _, kk := range k {
|
||||||
|
if readOpts.Prefix && !strings.HasPrefix(kk, key) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if readOpts.Suffix {
|
|
||||||
opts = append(opts, store.ListSuffix(key))
|
if readOpts.Suffix && !strings.HasSuffix(kk, key) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
opts = append(opts, store.ListLimit(readOpts.Limit))
|
|
||||||
opts = append(opts, store.ListOffset(readOpts.Offset))
|
keys = append(keys, kk)
|
||||||
k, err := m.List(opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "Memory: Read couldn't List()")
|
|
||||||
}
|
}
|
||||||
keys = k
|
|
||||||
} else {
|
} else {
|
||||||
keys = []string{key}
|
keys = []string{key}
|
||||||
}
|
}
|
||||||
|
|
||||||
var results []*store.Record
|
var results []*store.Record
|
||||||
|
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
r, err := m.get(k)
|
r, err := m.get(prefix, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
@ -87,40 +187,14 @@ func (m *memoryStore) Read(key string, opts ...store.ReadOption) ([]*store.Recor
|
|||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) get(k string) (*store.Record, error) {
|
|
||||||
if len(m.options.Table) > 0 {
|
|
||||||
k = m.options.Table + "/" + k
|
|
||||||
}
|
|
||||||
if len(m.options.Database) > 0 {
|
|
||||||
k = m.options.Database + "/" + k
|
|
||||||
}
|
|
||||||
var storedRecord *internalRecord
|
|
||||||
r, found := m.store.Get(k)
|
|
||||||
if !found {
|
|
||||||
return nil, store.ErrNotFound
|
|
||||||
}
|
|
||||||
storedRecord, ok := r.(*internalRecord)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("Retrieved a non *internalRecord from the cache")
|
|
||||||
}
|
|
||||||
// Copy the record on the way out
|
|
||||||
newRecord := &store.Record{}
|
|
||||||
newRecord.Key = storedRecord.key
|
|
||||||
newRecord.Value = make([]byte, len(storedRecord.value))
|
|
||||||
copy(newRecord.Value, storedRecord.value)
|
|
||||||
if !storedRecord.expiresAt.IsZero() {
|
|
||||||
newRecord.Expiry = time.Until(storedRecord.expiresAt)
|
|
||||||
}
|
|
||||||
|
|
||||||
return newRecord, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memoryStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
func (m *memoryStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
||||||
writeOpts := store.WriteOptions{}
|
writeOpts := store.WriteOptions{}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&writeOpts)
|
o(&writeOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prefix := m.prefix(writeOpts.Database, writeOpts.Table)
|
||||||
|
|
||||||
if len(opts) > 0 {
|
if len(opts) > 0 {
|
||||||
// Copy the record before applying options, or the incoming record will be mutated
|
// Copy the record before applying options, or the incoming record will be mutated
|
||||||
newRecord := store.Record{}
|
newRecord := store.Record{}
|
||||||
@ -135,33 +209,14 @@ func (m *memoryStore) Write(r *store.Record, opts ...store.WriteOption) error {
|
|||||||
if writeOpts.TTL != 0 {
|
if writeOpts.TTL != 0 {
|
||||||
newRecord.Expiry = writeOpts.TTL
|
newRecord.Expiry = writeOpts.TTL
|
||||||
}
|
}
|
||||||
m.set(&newRecord)
|
m.set(prefix, &newRecord)
|
||||||
} else {
|
|
||||||
m.set(r)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) set(r *store.Record) {
|
// set
|
||||||
key := r.Key
|
m.set(prefix, r)
|
||||||
if len(m.options.Table) > 0 {
|
|
||||||
key = m.options.Table + "/" + key
|
|
||||||
}
|
|
||||||
if len(m.options.Database) > 0 {
|
|
||||||
key = m.options.Database + "/" + key
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy the incoming record and then
|
return nil
|
||||||
// convert the expiry in to a hard timestamp
|
|
||||||
i := &internalRecord{}
|
|
||||||
i.key = r.Key
|
|
||||||
i.value = make([]byte, len(r.Value))
|
|
||||||
copy(i.value, r.Value)
|
|
||||||
if r.Expiry != 0 {
|
|
||||||
i.expiresAt = time.Now().Add(r.Expiry)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.store.Set(key, i, r.Expiry)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Delete(key string, opts ...store.DeleteOption) error {
|
func (m *memoryStore) Delete(key string, opts ...store.DeleteOption) error {
|
||||||
@ -169,18 +224,10 @@ func (m *memoryStore) Delete(key string, opts ...store.DeleteOption) error {
|
|||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&deleteOptions)
|
o(&deleteOptions)
|
||||||
}
|
}
|
||||||
m.delete(key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memoryStore) delete(key string) {
|
prefix := m.prefix(deleteOptions.Database, deleteOptions.Table)
|
||||||
if len(m.options.Table) > 0 {
|
m.delete(prefix, key)
|
||||||
key = m.options.Table + "/" + key
|
return nil
|
||||||
}
|
|
||||||
if len(m.options.Database) > 0 {
|
|
||||||
key = m.options.Database + "/" + key
|
|
||||||
}
|
|
||||||
m.store.Delete(key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Options() store.Options {
|
func (m *memoryStore) Options() store.Options {
|
||||||
@ -193,59 +240,29 @@ func (m *memoryStore) List(opts ...store.ListOption) ([]string, error) {
|
|||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&listOptions)
|
o(&listOptions)
|
||||||
}
|
}
|
||||||
allKeys := m.list(listOptions.Limit, listOptions.Offset)
|
|
||||||
|
prefix := m.prefix(listOptions.Database, listOptions.Table)
|
||||||
|
keys := m.list(prefix, listOptions.Limit, listOptions.Offset)
|
||||||
|
|
||||||
if len(listOptions.Prefix) > 0 {
|
if len(listOptions.Prefix) > 0 {
|
||||||
var prefixKeys []string
|
var prefixKeys []string
|
||||||
for _, k := range allKeys {
|
for _, k := range keys {
|
||||||
if strings.HasPrefix(k, listOptions.Prefix) {
|
if strings.HasPrefix(k, listOptions.Prefix) {
|
||||||
prefixKeys = append(prefixKeys, k)
|
prefixKeys = append(prefixKeys, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allKeys = prefixKeys
|
keys = prefixKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(listOptions.Suffix) > 0 {
|
if len(listOptions.Suffix) > 0 {
|
||||||
var suffixKeys []string
|
var suffixKeys []string
|
||||||
for _, k := range allKeys {
|
for _, k := range keys {
|
||||||
if strings.HasSuffix(k, listOptions.Suffix) {
|
if strings.HasSuffix(k, listOptions.Suffix) {
|
||||||
suffixKeys = append(suffixKeys, k)
|
suffixKeys = append(suffixKeys, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allKeys = suffixKeys
|
keys = suffixKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
return allKeys, nil
|
return keys, nil
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memoryStore) list(limit, offset uint) []string {
|
|
||||||
allItems := m.store.Items()
|
|
||||||
allKeys := make([]string, len(allItems))
|
|
||||||
i := 0
|
|
||||||
for k := range allItems {
|
|
||||||
if len(m.options.Database) > 0 {
|
|
||||||
k = strings.TrimPrefix(k, m.options.Database+"/")
|
|
||||||
}
|
|
||||||
if len(m.options.Table) > 0 {
|
|
||||||
k = strings.TrimPrefix(k, m.options.Table+"/")
|
|
||||||
}
|
|
||||||
allKeys[i] = k
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if limit != 0 || offset != 0 {
|
|
||||||
sort.Slice(allKeys, func(i, j int) bool { return allKeys[i] < allKeys[j] })
|
|
||||||
min := func(i, j uint) uint {
|
|
||||||
if i < j {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
return j
|
|
||||||
}
|
|
||||||
return allKeys[offset:min(limit, uint(len(allKeys)))]
|
|
||||||
}
|
|
||||||
return allKeys
|
|
||||||
}
|
|
||||||
|
|
||||||
type internalRecord struct {
|
|
||||||
key string
|
|
||||||
value []byte
|
|
||||||
expiresAt time.Time
|
|
||||||
}
|
}
|
||||||
|
@ -259,13 +259,13 @@ func basictest(s store.Store, t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
} else {
|
} else {
|
||||||
if len(results) != 5 {
|
if len(results) != 5 {
|
||||||
t.Error("Expected 5 results, got ", len(results))
|
t.Fatal("Expected 5 results, got ", len(results))
|
||||||
}
|
}
|
||||||
if results[0].Key != "a0" {
|
if results[0].Key != "a0" {
|
||||||
t.Errorf("Expected a0, got %s", results[0].Key)
|
t.Fatalf("Expected a0, got %s", results[0].Key)
|
||||||
}
|
}
|
||||||
if results[4].Key != "a4" {
|
if results[4].Key != "a4" {
|
||||||
t.Errorf("Expected a4, got %s", results[4].Key)
|
t.Fatalf("Expected a4, got %s", results[4].Key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if results, err := s.Read("a", store.ReadLimit(30), store.ReadOffset(5), store.ReadPrefix()); err != nil {
|
if results, err := s.Read("a", store.ReadLimit(30), store.ReadOffset(5), store.ReadPrefix()); err != nil {
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// source: store/service/proto/store.proto
|
// source: github.com/micro/go-micro/store/service/proto/store.proto
|
||||||
|
|
||||||
package go_micro_store
|
package go_micro_store
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
proto "github.com/golang/protobuf/proto"
|
proto "github.com/golang/protobuf/proto"
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
math "math"
|
math "math"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,7 +36,7 @@ func (m *Record) Reset() { *m = Record{} }
|
|||||||
func (m *Record) String() string { return proto.CompactTextString(m) }
|
func (m *Record) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Record) ProtoMessage() {}
|
func (*Record) ProtoMessage() {}
|
||||||
func (*Record) Descriptor() ([]byte, []int) {
|
func (*Record) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{0}
|
return fileDescriptor_42854049893ccb13, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Record) XXX_Unmarshal(b []byte) error {
|
func (m *Record) XXX_Unmarshal(b []byte) error {
|
||||||
@ -83,10 +79,12 @@ func (m *Record) GetExpiry() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ReadOptions struct {
|
type ReadOptions struct {
|
||||||
Prefix bool `protobuf:"varint,1,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"`
|
||||||
Suffix bool `protobuf:"varint,2,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
Table string `protobuf:"bytes,2,opt,name=table,proto3" json:"table,omitempty"`
|
||||||
Limit uint64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
|
Prefix bool `protobuf:"varint,3,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
||||||
Offset uint64 `protobuf:"varint,4,opt,name=offset,proto3" json:"offset,omitempty"`
|
Suffix bool `protobuf:"varint,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
||||||
|
Limit uint64 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||||
|
Offset uint64 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
@ -96,7 +94,7 @@ func (m *ReadOptions) Reset() { *m = ReadOptions{} }
|
|||||||
func (m *ReadOptions) String() string { return proto.CompactTextString(m) }
|
func (m *ReadOptions) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ReadOptions) ProtoMessage() {}
|
func (*ReadOptions) ProtoMessage() {}
|
||||||
func (*ReadOptions) Descriptor() ([]byte, []int) {
|
func (*ReadOptions) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{1}
|
return fileDescriptor_42854049893ccb13, []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ReadOptions) XXX_Unmarshal(b []byte) error {
|
func (m *ReadOptions) XXX_Unmarshal(b []byte) error {
|
||||||
@ -117,6 +115,20 @@ func (m *ReadOptions) XXX_DiscardUnknown() {
|
|||||||
|
|
||||||
var xxx_messageInfo_ReadOptions proto.InternalMessageInfo
|
var xxx_messageInfo_ReadOptions proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *ReadOptions) GetDatabase() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Database
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ReadOptions) GetTable() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Table
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (m *ReadOptions) GetPrefix() bool {
|
func (m *ReadOptions) GetPrefix() bool {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Prefix
|
return m.Prefix
|
||||||
@ -157,7 +169,7 @@ func (m *ReadRequest) Reset() { *m = ReadRequest{} }
|
|||||||
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ReadRequest) ProtoMessage() {}
|
func (*ReadRequest) ProtoMessage() {}
|
||||||
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{2}
|
return fileDescriptor_42854049893ccb13, []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -203,7 +215,7 @@ func (m *ReadResponse) Reset() { *m = ReadResponse{} }
|
|||||||
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ReadResponse) ProtoMessage() {}
|
func (*ReadResponse) ProtoMessage() {}
|
||||||
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{3}
|
return fileDescriptor_42854049893ccb13, []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -232,10 +244,12 @@ func (m *ReadResponse) GetRecords() []*Record {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WriteOptions struct {
|
type WriteOptions struct {
|
||||||
|
Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"`
|
||||||
|
Table string `protobuf:"bytes,2,opt,name=table,proto3" json:"table,omitempty"`
|
||||||
// time.Time
|
// time.Time
|
||||||
Expiry int64 `protobuf:"varint,1,opt,name=expiry,proto3" json:"expiry,omitempty"`
|
Expiry int64 `protobuf:"varint,3,opt,name=expiry,proto3" json:"expiry,omitempty"`
|
||||||
// time.Duration
|
// time.Duration
|
||||||
Ttl int64 `protobuf:"varint,2,opt,name=ttl,proto3" json:"ttl,omitempty"`
|
Ttl int64 `protobuf:"varint,4,opt,name=ttl,proto3" json:"ttl,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
@ -245,7 +259,7 @@ func (m *WriteOptions) Reset() { *m = WriteOptions{} }
|
|||||||
func (m *WriteOptions) String() string { return proto.CompactTextString(m) }
|
func (m *WriteOptions) String() string { return proto.CompactTextString(m) }
|
||||||
func (*WriteOptions) ProtoMessage() {}
|
func (*WriteOptions) ProtoMessage() {}
|
||||||
func (*WriteOptions) Descriptor() ([]byte, []int) {
|
func (*WriteOptions) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{4}
|
return fileDescriptor_42854049893ccb13, []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *WriteOptions) XXX_Unmarshal(b []byte) error {
|
func (m *WriteOptions) XXX_Unmarshal(b []byte) error {
|
||||||
@ -266,6 +280,20 @@ func (m *WriteOptions) XXX_DiscardUnknown() {
|
|||||||
|
|
||||||
var xxx_messageInfo_WriteOptions proto.InternalMessageInfo
|
var xxx_messageInfo_WriteOptions proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *WriteOptions) GetDatabase() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Database
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *WriteOptions) GetTable() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Table
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (m *WriteOptions) GetExpiry() int64 {
|
func (m *WriteOptions) GetExpiry() int64 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Expiry
|
return m.Expiry
|
||||||
@ -292,7 +320,7 @@ func (m *WriteRequest) Reset() { *m = WriteRequest{} }
|
|||||||
func (m *WriteRequest) String() string { return proto.CompactTextString(m) }
|
func (m *WriteRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*WriteRequest) ProtoMessage() {}
|
func (*WriteRequest) ProtoMessage() {}
|
||||||
func (*WriteRequest) Descriptor() ([]byte, []int) {
|
func (*WriteRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{5}
|
return fileDescriptor_42854049893ccb13, []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *WriteRequest) XXX_Unmarshal(b []byte) error {
|
func (m *WriteRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -337,7 +365,7 @@ func (m *WriteResponse) Reset() { *m = WriteResponse{} }
|
|||||||
func (m *WriteResponse) String() string { return proto.CompactTextString(m) }
|
func (m *WriteResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*WriteResponse) ProtoMessage() {}
|
func (*WriteResponse) ProtoMessage() {}
|
||||||
func (*WriteResponse) Descriptor() ([]byte, []int) {
|
func (*WriteResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{6}
|
return fileDescriptor_42854049893ccb13, []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *WriteResponse) XXX_Unmarshal(b []byte) error {
|
func (m *WriteResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -359,6 +387,8 @@ func (m *WriteResponse) XXX_DiscardUnknown() {
|
|||||||
var xxx_messageInfo_WriteResponse proto.InternalMessageInfo
|
var xxx_messageInfo_WriteResponse proto.InternalMessageInfo
|
||||||
|
|
||||||
type DeleteOptions struct {
|
type DeleteOptions struct {
|
||||||
|
Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"`
|
||||||
|
Table string `protobuf:"bytes,2,opt,name=table,proto3" json:"table,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
@ -368,7 +398,7 @@ func (m *DeleteOptions) Reset() { *m = DeleteOptions{} }
|
|||||||
func (m *DeleteOptions) String() string { return proto.CompactTextString(m) }
|
func (m *DeleteOptions) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DeleteOptions) ProtoMessage() {}
|
func (*DeleteOptions) ProtoMessage() {}
|
||||||
func (*DeleteOptions) Descriptor() ([]byte, []int) {
|
func (*DeleteOptions) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{7}
|
return fileDescriptor_42854049893ccb13, []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DeleteOptions) XXX_Unmarshal(b []byte) error {
|
func (m *DeleteOptions) XXX_Unmarshal(b []byte) error {
|
||||||
@ -389,6 +419,20 @@ func (m *DeleteOptions) XXX_DiscardUnknown() {
|
|||||||
|
|
||||||
var xxx_messageInfo_DeleteOptions proto.InternalMessageInfo
|
var xxx_messageInfo_DeleteOptions proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *DeleteOptions) GetDatabase() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Database
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DeleteOptions) GetTable() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Table
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type DeleteRequest struct {
|
type DeleteRequest struct {
|
||||||
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
Options *DeleteOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
Options *DeleteOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
||||||
@ -401,7 +445,7 @@ func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
|
|||||||
func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
|
func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DeleteRequest) ProtoMessage() {}
|
func (*DeleteRequest) ProtoMessage() {}
|
||||||
func (*DeleteRequest) Descriptor() ([]byte, []int) {
|
func (*DeleteRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{8}
|
return fileDescriptor_42854049893ccb13, []int{8}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
|
func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -446,7 +490,7 @@ func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
|
|||||||
func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
|
func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DeleteResponse) ProtoMessage() {}
|
func (*DeleteResponse) ProtoMessage() {}
|
||||||
func (*DeleteResponse) Descriptor() ([]byte, []int) {
|
func (*DeleteResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{9}
|
return fileDescriptor_42854049893ccb13, []int{9}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
|
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -468,10 +512,12 @@ func (m *DeleteResponse) XXX_DiscardUnknown() {
|
|||||||
var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
|
var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
|
||||||
|
|
||||||
type ListOptions struct {
|
type ListOptions struct {
|
||||||
Prefix string `protobuf:"bytes,1,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"`
|
||||||
Suffix string `protobuf:"bytes,2,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
Table string `protobuf:"bytes,2,opt,name=table,proto3" json:"table,omitempty"`
|
||||||
Limit uint64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
|
Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
||||||
Offset uint64 `protobuf:"varint,4,opt,name=offset,proto3" json:"offset,omitempty"`
|
Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
||||||
|
Limit uint64 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||||
|
Offset uint64 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
@ -481,7 +527,7 @@ func (m *ListOptions) Reset() { *m = ListOptions{} }
|
|||||||
func (m *ListOptions) String() string { return proto.CompactTextString(m) }
|
func (m *ListOptions) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ListOptions) ProtoMessage() {}
|
func (*ListOptions) ProtoMessage() {}
|
||||||
func (*ListOptions) Descriptor() ([]byte, []int) {
|
func (*ListOptions) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{10}
|
return fileDescriptor_42854049893ccb13, []int{10}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ListOptions) XXX_Unmarshal(b []byte) error {
|
func (m *ListOptions) XXX_Unmarshal(b []byte) error {
|
||||||
@ -502,6 +548,20 @@ func (m *ListOptions) XXX_DiscardUnknown() {
|
|||||||
|
|
||||||
var xxx_messageInfo_ListOptions proto.InternalMessageInfo
|
var xxx_messageInfo_ListOptions proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *ListOptions) GetDatabase() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Database
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ListOptions) GetTable() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Table
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (m *ListOptions) GetPrefix() string {
|
func (m *ListOptions) GetPrefix() string {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Prefix
|
return m.Prefix
|
||||||
@ -541,7 +601,7 @@ func (m *ListRequest) Reset() { *m = ListRequest{} }
|
|||||||
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ListRequest) ProtoMessage() {}
|
func (*ListRequest) ProtoMessage() {}
|
||||||
func (*ListRequest) Descriptor() ([]byte, []int) {
|
func (*ListRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{11}
|
return fileDescriptor_42854049893ccb13, []int{11}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -580,7 +640,7 @@ func (m *ListResponse) Reset() { *m = ListResponse{} }
|
|||||||
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ListResponse) ProtoMessage() {}
|
func (*ListResponse) ProtoMessage() {}
|
||||||
func (*ListResponse) Descriptor() ([]byte, []int) {
|
func (*ListResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{12}
|
return fileDescriptor_42854049893ccb13, []int{12}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -618,7 +678,7 @@ func (m *DatabasesRequest) Reset() { *m = DatabasesRequest{} }
|
|||||||
func (m *DatabasesRequest) String() string { return proto.CompactTextString(m) }
|
func (m *DatabasesRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DatabasesRequest) ProtoMessage() {}
|
func (*DatabasesRequest) ProtoMessage() {}
|
||||||
func (*DatabasesRequest) Descriptor() ([]byte, []int) {
|
func (*DatabasesRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{13}
|
return fileDescriptor_42854049893ccb13, []int{13}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DatabasesRequest) XXX_Unmarshal(b []byte) error {
|
func (m *DatabasesRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -650,7 +710,7 @@ func (m *DatabasesResponse) Reset() { *m = DatabasesResponse{} }
|
|||||||
func (m *DatabasesResponse) String() string { return proto.CompactTextString(m) }
|
func (m *DatabasesResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DatabasesResponse) ProtoMessage() {}
|
func (*DatabasesResponse) ProtoMessage() {}
|
||||||
func (*DatabasesResponse) Descriptor() ([]byte, []int) {
|
func (*DatabasesResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{14}
|
return fileDescriptor_42854049893ccb13, []int{14}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DatabasesResponse) XXX_Unmarshal(b []byte) error {
|
func (m *DatabasesResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -689,7 +749,7 @@ func (m *TablesRequest) Reset() { *m = TablesRequest{} }
|
|||||||
func (m *TablesRequest) String() string { return proto.CompactTextString(m) }
|
func (m *TablesRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*TablesRequest) ProtoMessage() {}
|
func (*TablesRequest) ProtoMessage() {}
|
||||||
func (*TablesRequest) Descriptor() ([]byte, []int) {
|
func (*TablesRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{15}
|
return fileDescriptor_42854049893ccb13, []int{15}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TablesRequest) XXX_Unmarshal(b []byte) error {
|
func (m *TablesRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -728,7 +788,7 @@ func (m *TablesResponse) Reset() { *m = TablesResponse{} }
|
|||||||
func (m *TablesResponse) String() string { return proto.CompactTextString(m) }
|
func (m *TablesResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*TablesResponse) ProtoMessage() {}
|
func (*TablesResponse) ProtoMessage() {}
|
||||||
func (*TablesResponse) Descriptor() ([]byte, []int) {
|
func (*TablesResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_1ba364858f5c3cdb, []int{16}
|
return fileDescriptor_42854049893ccb13, []int{16}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TablesResponse) XXX_Unmarshal(b []byte) error {
|
func (m *TablesResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -776,332 +836,48 @@ func init() {
|
|||||||
proto.RegisterType((*TablesResponse)(nil), "go.micro.store.TablesResponse")
|
proto.RegisterType((*TablesResponse)(nil), "go.micro.store.TablesResponse")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { proto.RegisterFile("store/service/proto/store.proto", fileDescriptor_1ba364858f5c3cdb) }
|
func init() {
|
||||||
|
proto.RegisterFile("github.com/micro/go-micro/store/service/proto/store.proto", fileDescriptor_42854049893ccb13)
|
||||||
var fileDescriptor_1ba364858f5c3cdb = []byte{
|
|
||||||
// 563 bytes of a gzipped FileDescriptorProto
|
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x5d, 0x8f, 0xd2, 0x40,
|
|
||||||
0x14, 0xa5, 0xb4, 0x74, 0xe9, 0x85, 0x45, 0x9c, 0x18, 0x42, 0x90, 0x55, 0x9c, 0xa7, 0x26, 0x26,
|
|
||||||
0x65, 0xc5, 0xf8, 0xf1, 0x68, 0x22, 0x1a, 0x35, 0x26, 0x26, 0xa3, 0xd1, 0xc4, 0xb7, 0x02, 0x83,
|
|
||||||
0x69, 0x60, 0x77, 0x6a, 0x67, 0x20, 0xcb, 0x0f, 0xf4, 0x7f, 0x99, 0xf9, 0x2a, 0xa5, 0xb4, 0x3e,
|
|
||||||
0xf8, 0x36, 0xf7, 0xcc, 0x9d, 0x73, 0xee, 0xb9, 0xf7, 0xb6, 0xf0, 0x98, 0x0b, 0x96, 0xd1, 0x29,
|
|
||||||
0xa7, 0xd9, 0x3e, 0x59, 0xd2, 0x69, 0x9a, 0x31, 0xc1, 0xa6, 0x0a, 0x8b, 0xd4, 0x19, 0xf5, 0x7e,
|
|
||||||
0xb1, 0xe8, 0x26, 0x59, 0x66, 0x2c, 0x52, 0x28, 0xfe, 0x00, 0x3e, 0xa1, 0x4b, 0x96, 0xad, 0x50,
|
|
||||||
0x1f, 0xdc, 0x0d, 0x3d, 0x0c, 0x9d, 0x89, 0x13, 0x06, 0x44, 0x1e, 0xd1, 0x03, 0x68, 0xed, 0xe3,
|
|
||||||
0xed, 0x8e, 0x0e, 0x9b, 0x13, 0x27, 0xec, 0x12, 0x1d, 0xa0, 0x01, 0xf8, 0xf4, 0x2e, 0x4d, 0xb2,
|
|
||||||
0xc3, 0xd0, 0x9d, 0x38, 0xa1, 0x4b, 0x4c, 0x84, 0x37, 0xd0, 0x21, 0x34, 0x5e, 0x7d, 0x49, 0x45,
|
|
||||||
0xc2, 0x6e, 0xb9, 0x4c, 0x4b, 0x33, 0xba, 0x4e, 0xee, 0x14, 0x63, 0x9b, 0x98, 0x48, 0xe2, 0x7c,
|
|
||||||
0xb7, 0x96, 0x78, 0x53, 0xe3, 0x3a, 0x92, 0x62, 0xdb, 0xe4, 0x26, 0x11, 0x8a, 0xd5, 0x23, 0x3a,
|
|
||||||
0x90, 0xd9, 0x6c, 0xbd, 0xe6, 0x54, 0x0c, 0x3d, 0x05, 0x9b, 0x08, 0x7f, 0xd7, 0x62, 0x84, 0xfe,
|
|
||||||
0xde, 0x51, 0x2e, 0x2a, 0x6a, 0x7f, 0x01, 0x17, 0x4c, 0x57, 0xa2, 0x74, 0x3a, 0xb3, 0x87, 0xd1,
|
|
||||||
0xa9, 0xf3, 0xa8, 0x50, 0x2c, 0xb1, 0xb9, 0xf8, 0x0d, 0x74, 0x35, 0x2f, 0x4f, 0xd9, 0x2d, 0xa7,
|
|
||||||
0xe8, 0x1a, 0x2e, 0x32, 0xd5, 0x1e, 0x3e, 0x74, 0x26, 0x6e, 0xd8, 0x99, 0x0d, 0xce, 0x69, 0xe4,
|
|
||||||
0x35, 0xb1, 0x69, 0xf8, 0x35, 0x74, 0x7f, 0x64, 0x89, 0xa0, 0x85, 0x3e, 0x98, 0x76, 0x39, 0xc5,
|
|
||||||
0x76, 0xc9, 0x92, 0x85, 0xd8, 0xaa, 0xe2, 0x5c, 0x22, 0x8f, 0x78, 0x6f, 0x5e, 0x5a, 0x53, 0x11,
|
|
||||||
0xf8, 0x9a, 0x54, 0xbd, 0xac, 0x97, 0x36, 0x59, 0xe8, 0x65, 0xd9, 0xf2, 0xb8, 0xfc, 0xa0, 0x58,
|
|
||||||
0xd8, 0xd1, 0xf3, 0x3d, 0xb8, 0x34, 0xba, 0xda, 0xb4, 0x04, 0xe6, 0x74, 0x4b, 0xf3, 0x54, 0xfc,
|
|
||||||
0xd3, 0x02, 0xf5, 0xfd, 0x7e, 0x55, 0x16, 0xbf, 0x2a, 0x8b, 0x9f, 0x50, 0x1e, 0xd5, 0xfb, 0xd0,
|
|
||||||
0xb3, 0xdc, 0x46, 0x7e, 0x03, 0x9d, 0xcf, 0x09, 0x17, 0xd5, 0x8b, 0x14, 0xd4, 0x2c, 0x52, 0xf0,
|
|
||||||
0x9f, 0x8b, 0x34, 0xd7, 0x62, 0xd6, 0x58, 0x61, 0x6d, 0x9c, 0xea, 0xb5, 0x29, 0x94, 0x76, 0x34,
|
|
||||||
0x11, 0x42, 0x57, 0xb3, 0x98, 0xb5, 0x41, 0xe0, 0x6d, 0xe8, 0x41, 0xb6, 0xc2, 0x0d, 0x03, 0xa2,
|
|
||||||
0xce, 0x9f, 0xbc, 0xb6, 0xd3, 0x6f, 0x62, 0x04, 0xfd, 0x79, 0x2c, 0xe2, 0x45, 0xcc, 0x29, 0x37,
|
|
||||||
0xa2, 0xf8, 0x19, 0xdc, 0x2f, 0x60, 0x86, 0x62, 0x0c, 0xc1, 0xca, 0x82, 0x6a, 0xf7, 0x02, 0x72,
|
|
||||||
0x04, 0xf0, 0x53, 0xb8, 0xfc, 0x16, 0x2f, 0xb6, 0x39, 0x07, 0x1a, 0x41, 0xdb, 0xde, 0x9a, 0x3e,
|
|
||||||
0xe5, 0x31, 0x0e, 0xa1, 0x67, 0x93, 0x0d, 0xf9, 0x00, 0x7c, 0xa1, 0x10, 0xc3, 0x6c, 0xa2, 0xd9,
|
|
||||||
0x1f, 0x17, 0x5a, 0x5f, 0xa5, 0x4d, 0xf4, 0x16, 0x3c, 0xf9, 0x21, 0xa0, 0xca, 0xcf, 0xc6, 0x88,
|
|
||||||
0x8e, 0xc6, 0xd5, 0x97, 0x66, 0x8e, 0x0d, 0xf4, 0x1e, 0x5a, 0x6a, 0xb3, 0x50, 0xf5, 0x26, 0x5a,
|
|
||||||
0x9a, 0xab, 0x9a, 0xdb, 0x9c, 0xe7, 0x23, 0xf8, 0x7a, 0x47, 0x50, 0xcd, 0x56, 0x59, 0xa6, 0x47,
|
|
||||||
0x75, 0xd7, 0x39, 0xd5, 0x3b, 0xf0, 0xe4, 0xa4, 0x50, 0xe5, 0x5c, 0x6b, 0x7d, 0x15, 0x87, 0x8b,
|
|
||||||
0x1b, 0xd7, 0x0e, 0x22, 0x10, 0xe4, 0x23, 0x43, 0x93, 0x33, 0xd5, 0xd2, 0x84, 0x47, 0x4f, 0xfe,
|
|
||||||
0x91, 0x51, 0x74, 0xa9, 0xc7, 0x74, 0xee, 0xf2, 0x64, 0xd6, 0xe7, 0x2e, 0x4f, 0xa7, 0x8b, 0x1b,
|
|
||||||
0x0b, 0x5f, 0xfd, 0xec, 0x9f, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x04, 0x5f, 0x7c, 0x0f,
|
|
||||||
0x06, 0x00, 0x00,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
var fileDescriptor_42854049893ccb13 = []byte{
|
||||||
var _ context.Context
|
// 598 bytes of a gzipped FileDescriptorProto
|
||||||
var _ grpc.ClientConn
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x8e, 0xd2, 0x40,
|
||||||
|
0x14, 0xa6, 0xdb, 0xd2, 0xa5, 0x87, 0x1f, 0x71, 0x62, 0x48, 0x83, 0xac, 0xa9, 0x73, 0xd5, 0xc4,
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
0x58, 0x56, 0x8c, 0x1a, 0xef, 0x34, 0xa2, 0x51, 0x63, 0x62, 0x32, 0x1a, 0x4d, 0xbc, 0x2b, 0x30,
|
||||||
// is compatible with the grpc package it is being compiled against.
|
0x60, 0x5d, 0xd8, 0x62, 0x67, 0x20, 0xcb, 0xc3, 0xf8, 0x38, 0xbe, 0x97, 0x99, 0x3f, 0x28, 0xd0,
|
||||||
const _ = grpc.SupportPackageIsVersion4
|
0xee, 0x85, 0xbb, 0x77, 0x73, 0xce, 0x1c, 0xbe, 0x39, 0xdf, 0x4f, 0x03, 0xbc, 0x9c, 0x25, 0xfc,
|
||||||
|
0xe7, 0x6a, 0x14, 0x8d, 0xd3, 0x45, 0x7f, 0x91, 0x8c, 0xb3, 0xb4, 0x3f, 0x4b, 0x1f, 0xab, 0x03,
|
||||||
// StoreClient is the client API for Store service.
|
0xe3, 0x69, 0x46, 0xfb, 0x8c, 0x66, 0xeb, 0x64, 0x4c, 0xfb, 0xcb, 0x2c, 0xe5, 0xba, 0x17, 0xc9,
|
||||||
//
|
0x33, 0x6a, 0xcd, 0xd2, 0x48, 0x4e, 0x46, 0xb2, 0x8b, 0xdf, 0x83, 0x4b, 0xe8, 0x38, 0xcd, 0x26,
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
0xa8, 0x0d, 0xf6, 0x05, 0xdd, 0xf8, 0x56, 0x60, 0x85, 0x1e, 0x11, 0x47, 0x74, 0x0f, 0xaa, 0xeb,
|
||||||
type StoreClient interface {
|
0x78, 0xbe, 0xa2, 0xfe, 0x49, 0x60, 0x85, 0x0d, 0xa2, 0x0a, 0xd4, 0x01, 0x97, 0x5e, 0x2d, 0x93,
|
||||||
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error)
|
0x6c, 0xe3, 0xdb, 0x81, 0x15, 0xda, 0x44, 0x57, 0xf8, 0x8f, 0x05, 0x75, 0x42, 0xe3, 0xc9, 0xe7,
|
||||||
Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error)
|
0x25, 0x4f, 0xd2, 0x4b, 0x86, 0xba, 0x50, 0x9b, 0xc4, 0x3c, 0x1e, 0xc5, 0x8c, 0x6a, 0xd0, 0x6d,
|
||||||
Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
|
0x2d, 0x90, 0x79, 0x3c, 0x9a, 0x2b, 0x64, 0x8f, 0xa8, 0x42, 0x20, 0x2f, 0x33, 0x3a, 0x4d, 0xae,
|
||||||
List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (Store_ListClient, error)
|
0x24, 0x72, 0x8d, 0xe8, 0x4a, 0xf4, 0xd9, 0x6a, 0x2a, 0xfa, 0x8e, 0xea, 0xab, 0x4a, 0xa0, 0xcc,
|
||||||
Databases(ctx context.Context, in *DatabasesRequest, opts ...grpc.CallOption) (*DatabasesResponse, error)
|
0x93, 0x45, 0xc2, 0xfd, 0x6a, 0x60, 0x85, 0x0e, 0x51, 0x85, 0x98, 0x4e, 0xa7, 0x53, 0x46, 0xb9,
|
||||||
Tables(ctx context.Context, in *TablesRequest, opts ...grpc.CallOption) (*TablesResponse, error)
|
0xef, 0xca, 0xb6, 0xae, 0xf0, 0x37, 0xb5, 0x1e, 0xa1, 0xbf, 0x57, 0x94, 0xf1, 0x02, 0xba, 0xcf,
|
||||||
}
|
0xe0, 0x34, 0x55, 0xbb, 0xcb, 0xb5, 0xea, 0x83, 0xfb, 0xd1, 0xbe, 0x58, 0x51, 0x8e, 0x1e, 0x31,
|
||||||
|
0xb3, 0xf8, 0x15, 0x34, 0x14, 0x2e, 0x5b, 0xa6, 0x97, 0x8c, 0xa2, 0x73, 0x38, 0xcd, 0xa4, 0xa2,
|
||||||
type storeClient struct {
|
0xcc, 0xb7, 0x02, 0x3b, 0xac, 0x0f, 0x3a, 0xc7, 0x30, 0xe2, 0x9a, 0x98, 0x31, 0xfc, 0x0b, 0x1a,
|
||||||
cc *grpc.ClientConn
|
0xdf, 0xb3, 0x84, 0xd3, 0x1b, 0x29, 0x57, 0xe4, 0x89, 0x20, 0xc9, 0xf9, 0x5c, 0xca, 0x66, 0x13,
|
||||||
}
|
0x71, 0xc4, 0x6b, 0xfd, 0x96, 0x91, 0x21, 0x02, 0x57, 0xad, 0x21, 0x5f, 0x2a, 0x5f, 0x56, 0x4f,
|
||||||
|
0xa1, 0xe7, 0x87, 0x22, 0xf5, 0x0e, 0x7f, 0x90, 0xa7, 0xb2, 0x53, 0xe9, 0x0e, 0x34, 0xf5, 0xbb,
|
||||||
func NewStoreClient(cc *grpc.ClientConn) StoreClient {
|
0x4a, 0x26, 0xfc, 0x1a, 0x9a, 0x43, 0x3a, 0xa7, 0x37, 0x60, 0x8d, 0x7f, 0x18, 0x88, 0x72, 0x4f,
|
||||||
return &storeClient{cc}
|
0x5f, 0x1c, 0xae, 0x7b, 0x76, 0xb8, 0xee, 0xde, 0x12, 0xbb, 0x7d, 0xdb, 0xd0, 0x32, 0xd8, 0x7a,
|
||||||
}
|
0x61, 0x91, 0xef, 0x4f, 0x09, 0xe3, 0xb7, 0x95, 0x6f, 0xaf, 0x24, 0xdf, 0xde, 0x7f, 0xe6, 0x7b,
|
||||||
|
0xa8, 0xd6, 0x33, 0x5a, 0xe4, 0xd2, 0x6c, 0x15, 0xa7, 0x39, 0x47, 0x66, 0xc7, 0x3b, 0x84, 0x86,
|
||||||
func (c *storeClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
|
0x42, 0xd1, 0x69, 0x46, 0xe0, 0x5c, 0xd0, 0x8d, 0x50, 0xcf, 0x0e, 0x3d, 0x22, 0xcf, 0x1f, 0x9d,
|
||||||
out := new(ReadResponse)
|
0x9a, 0xd5, 0x3e, 0xc1, 0x08, 0xda, 0x43, 0xcd, 0x97, 0xe9, 0x47, 0xf1, 0x13, 0xb8, 0x9b, 0xeb,
|
||||||
err := c.cc.Invoke(ctx, "/go.micro.store.Store/Read", in, out, opts...)
|
0x69, 0x88, 0x1e, 0x78, 0x46, 0x18, 0xf5, 0x49, 0x78, 0x64, 0xd7, 0xc0, 0x8f, 0xa0, 0xf9, 0x55,
|
||||||
if err != nil {
|
0xa8, 0x63, 0x30, 0xae, 0xd3, 0x15, 0x87, 0xd0, 0x32, 0xc3, 0x1a, 0xbc, 0x03, 0xae, 0x14, 0xd7,
|
||||||
return nil, err
|
0x20, 0xeb, 0x6a, 0xf0, 0xd7, 0x86, 0xea, 0x17, 0x41, 0x13, 0xbd, 0x01, 0x47, 0x7c, 0x9f, 0xa8,
|
||||||
}
|
0xf0, 0x6b, 0xd6, 0x8f, 0x76, 0x7b, 0xc5, 0x97, 0xda, 0xfa, 0x0a, 0x7a, 0x07, 0x55, 0x19, 0x5f,
|
||||||
return out, nil
|
0x54, 0x1c, 0x77, 0x03, 0x73, 0x56, 0x72, 0xbb, 0xc5, 0xf9, 0x00, 0xae, 0x8a, 0x15, 0x2a, 0x09,
|
||||||
}
|
0xa2, 0x41, 0x7a, 0x50, 0x76, 0xbd, 0x85, 0x7a, 0x0b, 0x8e, 0x70, 0x0a, 0x15, 0xfa, 0x5a, 0xca,
|
||||||
|
0x2b, 0x6f, 0x2e, 0xae, 0x9c, 0x5b, 0x88, 0x80, 0xb7, 0xb5, 0x0c, 0x05, 0x47, 0xaf, 0x1e, 0x38,
|
||||||
func (c *storeClient) Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error) {
|
0xdc, 0x7d, 0x78, 0xcd, 0x44, 0x9e, 0xa5, 0xb2, 0xe9, 0x98, 0xe5, 0x9e, 0xd7, 0xc7, 0x2c, 0xf7,
|
||||||
out := new(WriteResponse)
|
0xdd, 0xc5, 0x95, 0x91, 0x2b, 0xff, 0xb6, 0x9e, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xab, 0xcb,
|
||||||
err := c.cc.Invoke(ctx, "/go.micro.store.Store/Write", in, out, opts...)
|
0x6e, 0xac, 0xf3, 0x06, 0x00, 0x00,
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *storeClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) {
|
|
||||||
out := new(DeleteResponse)
|
|
||||||
err := c.cc.Invoke(ctx, "/go.micro.store.Store/Delete", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *storeClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (Store_ListClient, error) {
|
|
||||||
stream, err := c.cc.NewStream(ctx, &_Store_serviceDesc.Streams[0], "/go.micro.store.Store/List", opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
x := &storeListClient{stream}
|
|
||||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := x.ClientStream.CloseSend(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Store_ListClient interface {
|
|
||||||
Recv() (*ListResponse, error)
|
|
||||||
grpc.ClientStream
|
|
||||||
}
|
|
||||||
|
|
||||||
type storeListClient struct {
|
|
||||||
grpc.ClientStream
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *storeListClient) Recv() (*ListResponse, error) {
|
|
||||||
m := new(ListResponse)
|
|
||||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *storeClient) Databases(ctx context.Context, in *DatabasesRequest, opts ...grpc.CallOption) (*DatabasesResponse, error) {
|
|
||||||
out := new(DatabasesResponse)
|
|
||||||
err := c.cc.Invoke(ctx, "/go.micro.store.Store/Databases", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *storeClient) Tables(ctx context.Context, in *TablesRequest, opts ...grpc.CallOption) (*TablesResponse, error) {
|
|
||||||
out := new(TablesResponse)
|
|
||||||
err := c.cc.Invoke(ctx, "/go.micro.store.Store/Tables", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoreServer is the server API for Store service.
|
|
||||||
type StoreServer interface {
|
|
||||||
Read(context.Context, *ReadRequest) (*ReadResponse, error)
|
|
||||||
Write(context.Context, *WriteRequest) (*WriteResponse, error)
|
|
||||||
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
|
|
||||||
List(*ListRequest, Store_ListServer) error
|
|
||||||
Databases(context.Context, *DatabasesRequest) (*DatabasesResponse, error)
|
|
||||||
Tables(context.Context, *TablesRequest) (*TablesResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedStoreServer can be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedStoreServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*UnimplementedStoreServer) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedStoreServer) Write(ctx context.Context, req *WriteRequest) (*WriteResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Write not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedStoreServer) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedStoreServer) List(req *ListRequest, srv Store_ListServer) error {
|
|
||||||
return status.Errorf(codes.Unimplemented, "method List not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedStoreServer) Databases(ctx context.Context, req *DatabasesRequest) (*DatabasesResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Databases not implemented")
|
|
||||||
}
|
|
||||||
func (*UnimplementedStoreServer) Tables(ctx context.Context, req *TablesRequest) (*TablesResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Tables not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterStoreServer(s *grpc.Server, srv StoreServer) {
|
|
||||||
s.RegisterService(&_Store_serviceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Store_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(ReadRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(StoreServer).Read(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/go.micro.store.Store/Read",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(StoreServer).Read(ctx, req.(*ReadRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Store_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(WriteRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(StoreServer).Write(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/go.micro.store.Store/Write",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(StoreServer).Write(ctx, req.(*WriteRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Store_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DeleteRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(StoreServer).Delete(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/go.micro.store.Store/Delete",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(StoreServer).Delete(ctx, req.(*DeleteRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Store_List_Handler(srv interface{}, stream grpc.ServerStream) error {
|
|
||||||
m := new(ListRequest)
|
|
||||||
if err := stream.RecvMsg(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return srv.(StoreServer).List(m, &storeListServer{stream})
|
|
||||||
}
|
|
||||||
|
|
||||||
type Store_ListServer interface {
|
|
||||||
Send(*ListResponse) error
|
|
||||||
grpc.ServerStream
|
|
||||||
}
|
|
||||||
|
|
||||||
type storeListServer struct {
|
|
||||||
grpc.ServerStream
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *storeListServer) Send(m *ListResponse) error {
|
|
||||||
return x.ServerStream.SendMsg(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Store_Databases_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DatabasesRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(StoreServer).Databases(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/go.micro.store.Store/Databases",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(StoreServer).Databases(ctx, req.(*DatabasesRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Store_Tables_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(TablesRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(StoreServer).Tables(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/go.micro.store.Store/Tables",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(StoreServer).Tables(ctx, req.(*TablesRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _Store_serviceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "go.micro.store.Store",
|
|
||||||
HandlerType: (*StoreServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "Read",
|
|
||||||
Handler: _Store_Read_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "Write",
|
|
||||||
Handler: _Store_Write_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "Delete",
|
|
||||||
Handler: _Store_Delete_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "Databases",
|
|
||||||
Handler: _Store_Databases_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "Tables",
|
|
||||||
Handler: _Store_Tables_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{
|
|
||||||
{
|
|
||||||
StreamName: "List",
|
|
||||||
Handler: _Store_List_Handler,
|
|
||||||
ServerStreams: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Metadata: "store/service/proto/store.proto",
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||||
// source: store/service/proto/store.proto
|
// source: github.com/micro/go-micro/store/service/proto/store.proto
|
||||||
|
|
||||||
package go_micro_store
|
package go_micro_store
|
||||||
|
|
||||||
|
@ -21,10 +21,12 @@ message Record {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ReadOptions {
|
message ReadOptions {
|
||||||
bool prefix = 1;
|
string database = 1;
|
||||||
bool suffix = 2;
|
string table = 2;
|
||||||
uint64 limit = 3;
|
bool prefix = 3;
|
||||||
uint64 offset = 4;
|
bool suffix = 4;
|
||||||
|
uint64 limit = 5;
|
||||||
|
uint64 offset = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ReadRequest {
|
message ReadRequest {
|
||||||
@ -37,10 +39,12 @@ message ReadResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message WriteOptions {
|
message WriteOptions {
|
||||||
|
string database = 1;
|
||||||
|
string table = 2;
|
||||||
// time.Time
|
// time.Time
|
||||||
int64 expiry = 1;
|
int64 expiry = 3;
|
||||||
// time.Duration
|
// time.Duration
|
||||||
int64 ttl = 2;
|
int64 ttl = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WriteRequest {
|
message WriteRequest {
|
||||||
@ -50,7 +54,10 @@ message WriteRequest {
|
|||||||
|
|
||||||
message WriteResponse {}
|
message WriteResponse {}
|
||||||
|
|
||||||
message DeleteOptions {}
|
message DeleteOptions {
|
||||||
|
string database = 1;
|
||||||
|
string table = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message DeleteRequest {
|
message DeleteRequest {
|
||||||
string key = 1;
|
string key = 1;
|
||||||
@ -60,12 +67,15 @@ message DeleteRequest {
|
|||||||
message DeleteResponse {}
|
message DeleteResponse {}
|
||||||
|
|
||||||
message ListOptions {
|
message ListOptions {
|
||||||
string prefix = 1;
|
string database = 1;
|
||||||
string suffix = 2;
|
string table = 2;
|
||||||
uint64 limit = 3;
|
string prefix = 3;
|
||||||
uint64 offset = 4;
|
string suffix = 4;
|
||||||
|
uint64 limit = 5;
|
||||||
|
uint64 offset = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
message ListRequest {
|
message ListRequest {
|
||||||
ListOptions options = 1;
|
ListOptions options = 1;
|
||||||
}
|
}
|
||||||
|
@ -46,23 +46,27 @@ func (s *serviceStore) Init(opts ...store.Option) error {
|
|||||||
|
|
||||||
func (s *serviceStore) Context() context.Context {
|
func (s *serviceStore) Context() context.Context {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
md := make(metadata.Metadata)
|
md := make(metadata.Metadata)
|
||||||
|
|
||||||
if len(s.Database) > 0 {
|
|
||||||
md["Micro-Database"] = s.Database
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(s.Table) > 0 {
|
|
||||||
md["Micro-Table"] = s.Table
|
|
||||||
}
|
|
||||||
|
|
||||||
return metadata.NewContext(ctx, md)
|
return metadata.NewContext(ctx, md)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync all the known records
|
// Sync all the known records
|
||||||
func (s *serviceStore) List(opts ...store.ListOption) ([]string, error) {
|
func (s *serviceStore) List(opts ...store.ListOption) ([]string, error) {
|
||||||
stream, err := s.Client.List(s.Context(), &pb.ListRequest{}, client.WithAddress(s.Nodes...))
|
var options store.ListOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
listOpts := &pb.ListOptions{
|
||||||
|
Database: options.Database,
|
||||||
|
Table: options.Table,
|
||||||
|
Prefix: options.Prefix,
|
||||||
|
Suffix: options.Suffix,
|
||||||
|
Limit: uint64(options.Limit),
|
||||||
|
Offset: uint64(options.Offset),
|
||||||
|
}
|
||||||
|
|
||||||
|
stream, err := s.Client.List(s.Context(), &pb.ListRequest{Options: listOpts}, client.WithAddress(s.Nodes...))
|
||||||
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
||||||
return nil, store.ErrNotFound
|
return nil, store.ErrNotFound
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -96,11 +100,18 @@ func (s *serviceStore) Read(key string, opts ...store.ReadOption) ([]*store.Reco
|
|||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readOpts := &pb.ReadOptions{
|
||||||
|
Database: options.Database,
|
||||||
|
Table: options.Table,
|
||||||
|
Prefix: options.Prefix,
|
||||||
|
Suffix: options.Suffix,
|
||||||
|
Limit: uint64(options.Limit),
|
||||||
|
Offset: uint64(options.Offset),
|
||||||
|
}
|
||||||
|
|
||||||
rsp, err := s.Client.Read(s.Context(), &pb.ReadRequest{
|
rsp, err := s.Client.Read(s.Context(), &pb.ReadRequest{
|
||||||
Key: key,
|
Key: key,
|
||||||
Options: &pb.ReadOptions{
|
Options: readOpts,
|
||||||
Prefix: options.Prefix,
|
|
||||||
},
|
|
||||||
}, client.WithAddress(s.Nodes...))
|
}, client.WithAddress(s.Nodes...))
|
||||||
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
||||||
return nil, store.ErrNotFound
|
return nil, store.ErrNotFound
|
||||||
@ -123,13 +134,23 @@ func (s *serviceStore) Read(key string, opts ...store.ReadOption) ([]*store.Reco
|
|||||||
|
|
||||||
// Write a record
|
// Write a record
|
||||||
func (s *serviceStore) Write(record *store.Record, opts ...store.WriteOption) error {
|
func (s *serviceStore) Write(record *store.Record, opts ...store.WriteOption) error {
|
||||||
|
var options store.WriteOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeOpts := &pb.WriteOptions{
|
||||||
|
Database: options.Database,
|
||||||
|
Table: options.Table,
|
||||||
|
}
|
||||||
|
|
||||||
_, err := s.Client.Write(s.Context(), &pb.WriteRequest{
|
_, err := s.Client.Write(s.Context(), &pb.WriteRequest{
|
||||||
Record: &pb.Record{
|
Record: &pb.Record{
|
||||||
Key: record.Key,
|
Key: record.Key,
|
||||||
Value: record.Value,
|
Value: record.Value,
|
||||||
Expiry: int64(record.Expiry.Seconds()),
|
Expiry: int64(record.Expiry.Seconds()),
|
||||||
},
|
},
|
||||||
}, client.WithAddress(s.Nodes...))
|
Options: writeOpts}, client.WithAddress(s.Nodes...))
|
||||||
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
||||||
return store.ErrNotFound
|
return store.ErrNotFound
|
||||||
}
|
}
|
||||||
@ -139,8 +160,19 @@ func (s *serviceStore) Write(record *store.Record, opts ...store.WriteOption) er
|
|||||||
|
|
||||||
// Delete a record with key
|
// Delete a record with key
|
||||||
func (s *serviceStore) Delete(key string, opts ...store.DeleteOption) error {
|
func (s *serviceStore) Delete(key string, opts ...store.DeleteOption) error {
|
||||||
|
var options store.DeleteOptions
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteOpts := &pb.DeleteOptions{
|
||||||
|
Database: options.Database,
|
||||||
|
Table: options.Table,
|
||||||
|
}
|
||||||
|
|
||||||
_, err := s.Client.Delete(s.Context(), &pb.DeleteRequest{
|
_, err := s.Client.Delete(s.Context(), &pb.DeleteRequest{
|
||||||
Key: key,
|
Key: key,
|
||||||
|
Options: deleteOpts,
|
||||||
}, client.WithAddress(s.Nodes...))
|
}, client.WithAddress(s.Nodes...))
|
||||||
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
if err != nil && errors.Equal(err, errors.NotFound("", "")) {
|
||||||
return store.ErrNotFound
|
return store.ErrNotFound
|
||||||
|
Loading…
Reference in New Issue
Block a user