parent
58c92ee41b
commit
4bbbb52892
|
@ -129,16 +129,16 @@ OK
|
||||||
|
|
||||||
### TXN [options]
|
### TXN [options]
|
||||||
|
|
||||||
TXN applies multiple etcd requests as a single atomic transaction. A transaction consists of list of conditions, a list of requests to apply if all the conditions are true, and a list of requests to apply if any condition is false.
|
TXN reads multiple etcd requests from standard input and applies them as a single atomic transaction.
|
||||||
|
A transaction consists of list of conditions, a list of requests to apply if all the conditions are true, and a list of requests to apply if any condition is false.
|
||||||
|
|
||||||
#### Options
|
#### Options
|
||||||
|
|
||||||
- hex -- print out keys and values as hex encoded string
|
- hex -- print out keys and values as hex encoded string
|
||||||
|
|
||||||
- interactive -- input transaction with interactive mode
|
- interactive -- input transaction with interactive prompting
|
||||||
|
|
||||||
#### Input Format
|
#### Input Format
|
||||||
Interactive mode:
|
|
||||||
```ebnf
|
```ebnf
|
||||||
<Txn> ::= <CMP>* "\n" <THEN> "\n" <ELSE> "\n"
|
<Txn> ::= <CMP>* "\n" <THEN> "\n" <ELSE> "\n"
|
||||||
<CMP> ::= (<CMPCREATE>|<CMPMOD>|<CMPVAL>|<CMPVER>) "\n"
|
<CMP> ::= (<CMPCREATE>|<CMPMOD>|<CMPVAL>|<CMPVER>) "\n"
|
||||||
|
@ -156,8 +156,6 @@ Interactive mode:
|
||||||
<VERSION> ::= "\""[0-9]+"\""
|
<VERSION> ::= "\""[0-9]+"\""
|
||||||
```
|
```
|
||||||
|
|
||||||
TODO: non-interactive mode
|
|
||||||
|
|
||||||
#### Return value
|
#### Return value
|
||||||
|
|
||||||
##### Simple reply
|
##### Simple reply
|
||||||
|
@ -178,6 +176,7 @@ The protobuf encoding of the Txn [RPC response][etcdrpc].
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
|
txn in interactive mode:
|
||||||
``` bash
|
``` bash
|
||||||
./etcdctl txn -i
|
./etcdctl txn -i
|
||||||
mod("key1") > "0"
|
mod("key1") > "0"
|
||||||
|
@ -194,10 +193,22 @@ OK
|
||||||
OK
|
OK
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Notes
|
txn in non-interactive mode:
|
||||||
|
```
|
||||||
|
./etcdctl txn <<<'mod("key1") > "0"
|
||||||
|
|
||||||
TODO: non-interactive mode
|
put key1 "overwrote-key1"
|
||||||
|
|
||||||
|
put key1 "created-key1"
|
||||||
|
put key2 "some extra key"
|
||||||
|
|
||||||
|
'
|
||||||
|
FAILURE
|
||||||
|
|
||||||
|
OK
|
||||||
|
|
||||||
|
OK
|
||||||
|
````
|
||||||
|
|
||||||
### WATCH [options] [key or prefix]
|
### WATCH [options] [key or prefix]
|
||||||
|
|
||||||
|
|
|
@ -47,18 +47,14 @@ func txnCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
ExitWithError(ExitBadArgs, fmt.Errorf("txn command does not accept argument."))
|
ExitWithError(ExitBadArgs, fmt.Errorf("txn command does not accept argument."))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !txnInteractive {
|
|
||||||
ExitWithError(ExitBadFeature, fmt.Errorf("txn command only supports interactive mode"))
|
|
||||||
}
|
|
||||||
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
txn := mustClientFromCmd(cmd).Txn(context.Background())
|
txn := mustClientFromCmd(cmd).Txn(context.Background())
|
||||||
fmt.Println("compares:")
|
promptInteractive("compares:")
|
||||||
txn.If(readCompares(reader)...)
|
txn.If(readCompares(reader)...)
|
||||||
fmt.Println("success requests (get, put, delete):")
|
promptInteractive("success requests (get, put, delete):")
|
||||||
txn.Then(readOps(reader)...)
|
txn.Then(readOps(reader)...)
|
||||||
fmt.Println("failure requests (get, put, delete):")
|
promptInteractive("failure requests (get, put, delete):")
|
||||||
txn.Else(readOps(reader)...)
|
txn.Else(readOps(reader)...)
|
||||||
|
|
||||||
resp, err := txn.Commit()
|
resp, err := txn.Commit()
|
||||||
|
@ -69,6 +65,12 @@ func txnCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
display.Txn(*resp)
|
display.Txn(*resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func promptInteractive(s string) {
|
||||||
|
if txnInteractive {
|
||||||
|
fmt.Println(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func readCompares(r *bufio.Reader) (cmps []clientv3.Cmp) {
|
func readCompares(r *bufio.Reader) (cmps []clientv3.Cmp) {
|
||||||
for {
|
for {
|
||||||
line, err := r.ReadString('\n')
|
line, err := r.ReadString('\n')
|
||||||
|
|
Loading…
Reference in New Issue