mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
basic get
This commit is contained in:
parent
45ab5238fe
commit
45c9ec9f29
@ -7,6 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Get = "get"
|
||||||
Set = "set"
|
Set = "set"
|
||||||
Delete = "delete"
|
Delete = "delete"
|
||||||
TestAndSet = "testAndSet"
|
TestAndSet = "testAndSet"
|
||||||
@ -15,10 +16,11 @@ const (
|
|||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key, omitempty"`
|
||||||
Dir bool `json:"dir,omitempty"`
|
Dir bool `json:"dir,omitempty"`
|
||||||
PrevValue string `json:"prevValue,omitempty"`
|
PrevValue string `json:"prevValue,omitempty"`
|
||||||
Value string `json:"value,omitempty"`
|
Value string `json:"value,omitempty"`
|
||||||
|
Pairs []KeyValuePair `json:"kvs,omitempty"`
|
||||||
Expiration *time.Time `json:"expiration,omitempty"`
|
Expiration *time.Time `json:"expiration,omitempty"`
|
||||||
TTL int64 `json:"ttl,omitempty"` // Time to live in second
|
TTL int64 `json:"ttl,omitempty"` // Time to live in second
|
||||||
// The command index of the raft machine when the command is executed
|
// The command index of the raft machine when the command is executed
|
||||||
@ -26,6 +28,14 @@ type Event struct {
|
|||||||
Term uint64 `json:"term"`
|
Term uint64 `json:"term"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When user list a directory, we add all the node into key-value pair slice
|
||||||
|
type KeyValuePair struct {
|
||||||
|
Key string `json:"key, omitempty"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
Dir bool `json:"dir,omitempty"`
|
||||||
|
Pairs []KeyValuePair `json:"kvs,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func newEvent(action string, key string, index uint64, term uint64) *Event {
|
func newEvent(action string, key string, index uint64, term uint64) *Event {
|
||||||
return &Event{
|
return &Event{
|
||||||
Action: action,
|
Action: action,
|
||||||
|
@ -25,29 +25,42 @@ func New() *FileSystem {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FileSystem) InternalGet(path string, index uint64, term uint64) (*Node, error) {
|
func (fs *FileSystem) Get(path string, recusive bool, index uint64, term uint64) (*Event, error) {
|
||||||
fmt.Println("GET: ", path)
|
// TODO: add recursive get
|
||||||
path = filepath.Clean("/" + path)
|
n, err := fs.InternalGet(path, index, term)
|
||||||
|
|
||||||
// update file system known index and term
|
|
||||||
fs.Index, fs.Term = index, term
|
|
||||||
|
|
||||||
walkFunc := func(parent *Node, dirName string) (*Node, error) {
|
|
||||||
child, ok := parent.Children[dirName]
|
|
||||||
if ok {
|
|
||||||
return child, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, etcdErr.NewError(100, "get")
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := fs.walk(path, walkFunc)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return f, nil
|
e := newEvent(Get, path, index, term)
|
||||||
|
|
||||||
|
if n.IsDir() { // node is dir
|
||||||
|
e.Pairs = make([]KeyValuePair, len(n.Children))
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for _, subN := range n.Children {
|
||||||
|
|
||||||
|
if subN.IsDir() {
|
||||||
|
e.Pairs[i] = KeyValuePair{
|
||||||
|
Key: subN.Path,
|
||||||
|
Dir: true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e.Pairs[i] = KeyValuePair{
|
||||||
|
Key: subN.Path,
|
||||||
|
Value: subN.Value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // node is file
|
||||||
|
e.Value = n.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FileSystem) Set(path string, value string, expireTime time.Time, index uint64, term uint64) error {
|
func (fs *FileSystem) Set(path string, value string, expireTime time.Time, index uint64, term uint64) error {
|
||||||
@ -66,17 +79,35 @@ func (fs *FileSystem) Set(path string, value string, expireTime time.Time, index
|
|||||||
}
|
}
|
||||||
|
|
||||||
f := newFile(name, value, fs.Index, fs.Term, d, "", expireTime)
|
f := newFile(name, value, fs.Index, fs.Term, d, "", expireTime)
|
||||||
|
e := newEvent(Set, path, fs.Index, fs.Term)
|
||||||
|
e.Value = f.Value
|
||||||
|
|
||||||
|
// remove previous file if exist
|
||||||
|
oldFile, err := d.GetFile(name)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
if oldFile != nil {
|
||||||
|
oldFile.Remove(false)
|
||||||
|
e.PrevValue = oldFile.Value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = d.Add(f)
|
err = d.Add(f)
|
||||||
|
|
||||||
if err == nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node with TTL
|
||||||
if expireTime != Permanent {
|
if expireTime != Permanent {
|
||||||
go f.Expire()
|
go f.Expire()
|
||||||
}
|
e.Expiration = &f.ExpireTime
|
||||||
|
e.TTL = int64(expireTime.Sub(time.Now()) / time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FileSystem) TestAndSet() {
|
func (fs *FileSystem) TestAndSet() {
|
||||||
@ -119,6 +150,32 @@ func (fs *FileSystem) walk(path string, walkFunc func(prev *Node, component stri
|
|||||||
return curr, nil
|
return curr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalGet function get the node of the given path.
|
||||||
|
func (fs *FileSystem) InternalGet(path string, index uint64, term uint64) (*Node, error) {
|
||||||
|
fmt.Println("GET: ", path)
|
||||||
|
path = filepath.Clean("/" + path)
|
||||||
|
|
||||||
|
// update file system known index and term
|
||||||
|
fs.Index, fs.Term = index, term
|
||||||
|
|
||||||
|
walkFunc := func(parent *Node, dirName string) (*Node, error) {
|
||||||
|
child, ok := parent.Children[dirName]
|
||||||
|
if ok {
|
||||||
|
return child, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, etcdErr.NewError(100, "get")
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := fs.walk(path, walkFunc)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
// checkDir function will check whether the component is a directory under parent node.
|
// checkDir function will check whether the component is a directory under parent node.
|
||||||
// If it is a directory, this function will return the pointer to that node.
|
// If it is a directory, this function will return the pointer to that node.
|
||||||
// If it does not exist, this function will create a new directory and return the pointer to that node.
|
// If it does not exist, this function will create a new directory and return the pointer to that node.
|
||||||
|
@ -141,6 +141,28 @@ func (n *Node) List() ([]*Node, error) {
|
|||||||
return nodes, nil
|
return nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Node) GetFile(name string) (*Node, error) {
|
||||||
|
n.mu.Lock()
|
||||||
|
n.mu.Unlock()
|
||||||
|
|
||||||
|
if !n.IsDir() {
|
||||||
|
return nil, etcdErr.NewError(104, n.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, ok := n.Children[name]
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
if !f.IsDir() {
|
||||||
|
return f, nil
|
||||||
|
} else {
|
||||||
|
return nil, etcdErr.NewError(102, f.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Add function adds a node to the receiver node.
|
// Add function adds a node to the receiver node.
|
||||||
// If the receiver is not a directory, a "Not A Directory" error will be returned.
|
// If the receiver is not a directory, a "Not A Directory" error will be returned.
|
||||||
// If there is a existing node with the same name under the directory, a "Already Exist"
|
// If there is a existing node with the same name under the directory, a "Already Exist"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user