Skip to content

Commit 3e42d44

Browse files
authored
tikv: update the usage example for Txn KV API (#487)
* tikv: update the usage example for Txn KV API * tikv: update the code fencing * tikv: address comments
1 parent 40ebc4f commit 3e42d44

File tree

1 file changed

+122
-79
lines changed

1 file changed

+122
-79
lines changed

tikv/go-client-api.md

+122-79
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo
2121

2222
2. Import the dependency packages.
2323

24-
```bash
24+
```go
2525
import (
2626
"fmt"
2727
"github.com/pingcap/tidb/config"
@@ -31,7 +31,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo
3131

3232
3. Create a Raw Key-Value client.
3333

34-
```bash
34+
```go
3535
cli, err := tikv.NewRawKVClient([]string{"192.168.199.113:2379"}, config.Security{})
3636
```
3737

@@ -42,7 +42,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo
4242

4343
4. Call the Raw Key-Value client methods to access the data on TiKV. The Raw Key-Value API contains the following methods, and you can also find them at [GoDoc](https://godoc.org/github.com/pingcap/tidb/store/tikv#RawKVClient).
4444

45-
```bash
45+
```go
4646
type RawKVClient struct
4747
func (c *RawKVClient) Close() error
4848
func (c *RawKVClient) ClusterID() uint64
@@ -54,7 +54,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo
5454

5555
### Usage example of the Raw Key-Value API
5656

57-
```bash
57+
```go
5858
package main
5959
6060
import (
@@ -142,23 +142,32 @@ To use the Transactional Key-Value API in applications developed by golang, take
142142
1. Install the necessary packages.
143143
144144
```bash
145+
go get -v -u github.com/juju/errors
145146
go get -v -u github.com/pingcap/tidb/kv
146147
go get -v -u github.com/pingcap/tidb/store/tikv
148+
go get -v -u golang.org/x/net/context
147149
```
148150
149151
2. Import the dependency packages.
150152
151-
```bash
153+
```go
152154
import (
155+
"flag"
156+
"fmt"
157+
"os"
158+
159+
"github.com/juju/errors"
153160
"github.com/pingcap/tidb/kv"
154161
"github.com/pingcap/tidb/store/tikv"
155-
"fmt"
162+
"github.com/pingcap/tidb/terror"
163+
164+
goctx "golang.org/x/net/context"
156165
)
157166
```
158167
159168
3. Create Storage using a URL scheme.
160169
161-
```bash
170+
```go
162171
driver := tikv.Driver{}
163172
storage, err := driver.Open("tikv://192.168.199.113:2379")
164173
```
@@ -169,7 +178,7 @@ To use the Transactional Key-Value API in applications developed by golang, take
169178
170179
5. Call the Transactional Key-Value API's methods to access the data on TiKV. The Transactional Key-Value API contains the following methods:
171180
172-
```bash
181+
```go
173182
Begin() -> Txn
174183
Txn.Get(key []byte) -> (value []byte)
175184
Txn.Set(key []byte, value []byte)
@@ -180,116 +189,150 @@ To use the Transactional Key-Value API in applications developed by golang, take
180189
181190
### Usage example of the Transactional Key-Value API
182191
183-
```bash
192+
```go
184193
package main
185194
186195
import (
187-
"context"
196+
"flag"
188197
"fmt"
189-
"strconv"
198+
"os"
190199
200+
"github.com/juju/errors"
191201
"github.com/pingcap/tidb/kv"
192202
"github.com/pingcap/tidb/store/tikv"
203+
"github.com/pingcap/tidb/terror"
204+
205+
goctx "golang.org/x/net/context"
193206
)
194207
195-
// if key not found, set value to zero
196-
// else increase the value
197-
func increase(storage kv.Storage, key []byte) error {
198-
txn, err := storage.Begin()
208+
type KV struct {
209+
K, V []byte
210+
}
211+
212+
func (kv KV) String() string {
213+
return fmt.Sprintf("%s => %s (%v)", kv.K, kv.V, kv.V)
214+
}
215+
216+
var (
217+
store kv.Storage
218+
pdAddr = flag.String("pd", "192.168.199.113:2379", "pd address:192.168.199.113:2379")
219+
)
220+
221+
// Init initializes information.
222+
func initStore() {
223+
driver := tikv.Driver{}
224+
var err error
225+
store, err = driver.Open(fmt.Sprintf("tikv://%s", *pdAddr))
226+
terror.MustNil(err)
227+
}
228+
229+
// key1 val1 key2 val2 ...
230+
func puts(args ...[]byte) error {
231+
tx, err := store.Begin()
199232
if err != nil {
200-
return err
233+
return errors.Trace(err)
201234
}
202-
defer txn.Rollback()
203-
var oldValue int
204-
val, err := txn.Get(key)
205-
if err != nil {
206-
if !kv.ErrNotExist.Equal(err) {
207-
return err
208-
}
209-
} else {
210-
oldValue, err = strconv.Atoi(string(val))
235+
236+
for i := 0; i < len(args); i += 2 {
237+
key, val := args[i], args[i+1]
238+
err := tx.Set(key, val)
211239
if err != nil {
212-
return err
240+
return errors.Trace(err)
213241
}
214242
}
215-
216-
err = txn.Set(key, []byte(strconv.Itoa(oldValue+1)))
243+
err = tx.Commit(goctx.Background())
217244
if err != nil {
218-
return err
245+
return errors.Trace(err)
219246
}
220-
err = txn.Commit(context.Background())
247+
221248
return nil
222249
}
223250
224-
// lookup value for key
225-
func lookup(storage kv.Storage, key []byte) (int, error) {
226-
var value int
227-
txn, err := storage.Begin()
251+
func get(k []byte) (KV, error) {
252+
tx, err := store.Begin()
228253
if err != nil {
229-
return value, err
254+
return KV{}, errors.Trace(err)
230255
}
231-
defer txn.Rollback()
232-
val, err := txn.Get(key)
256+
v, err := tx.Get(k)
233257
if err != nil {
234-
return value, err
258+
return KV{}, errors.Trace(err)
235259
}
236-
value, err = strconv.Atoi(string(val))
237-
if err != nil {
238-
return value, err
239-
}
240-
return value, nil
260+
return KV{K: k, V: v}, nil
241261
}
242262
243-
func main() {
244-
driver := tikv.Driver{}
245-
storage, err := driver.Open("tikv://192.168.199.113:2379")
263+
func dels(keys ...[]byte) error {
264+
tx, err := store.Begin()
246265
if err != nil {
247-
panic(err)
266+
return errors.Trace(err)
248267
}
249-
defer storage.Close()
250-
251-
key := []byte("Account")
252-
// lookup account
253-
account, err := lookup(storage, key)
268+
for _, key := range keys {
269+
err := tx.Delete(key)
270+
if err != nil {
271+
return errors.Trace(err)
272+
}
273+
}
274+
err = tx.Commit(goctx.Background())
254275
if err != nil {
255-
fmt.Printf("failed to lookup key %s: %v\n", key, err)
256-
} else {
257-
fmt.Printf("Account is %d\n", account)
276+
return errors.Trace(err)
258277
}
278+
return nil
279+
}
259280
260-
// increase account
261-
err = increase(storage, key)
281+
func scan(keyPrefix []byte, limit int) ([]KV, error) {
282+
tx, err := store.Begin()
262283
if err != nil {
263-
panic(err)
284+
return nil, errors.Trace(err)
264285
}
265-
266-
// lookup account again
267-
account, err = lookup(storage, key)
286+
it, err := tx.Seek(keyPrefix)
268287
if err != nil {
269-
fmt.Printf("failed to lookup key %s: %v\n", key, err)
270-
} else {
271-
fmt.Printf("Account increased to %d\n", account)
288+
return nil, errors.Trace(err)
272289
}
290+
defer it.Close()
291+
var ret []KV
292+
for it.Valid() && limit > 0 {
293+
ret = append(ret, KV{K: it.Key()[:], V: it.Value()[:]})
294+
limit--
295+
it.Next()
296+
}
297+
return ret, nil
298+
}
299+
300+
func main() {
301+
pdAddr := os.Getenv("PD_ADDR")
302+
if pdAddr != "" {
303+
os.Args = append(os.Args, "-pd", pdAddr)
304+
}
305+
flag.Parse()
306+
initStore()
307+
308+
// set
309+
err := puts([]byte("key1"), []byte("value1"), []byte("key2"), []byte("value2"))
310+
terror.MustNil(err)
311+
312+
// get
313+
kv, err := get([]byte("key1"))
314+
terror.MustNil(err)
315+
fmt.Println(kv)
316+
317+
// scan
318+
ret, err := scan([]byte("key"), 10)
319+
for _, kv := range ret {
320+
fmt.Println(kv)
321+
}
322+
323+
// delete
324+
err = dels([]byte("key1"), []byte("key2"))
325+
terror.MustNil(err)
273326
}
274327
```
275328
276329
The result is like:
277330
278331
```bash
279332
INFO[0000] [pd] create pd client with endpoints [192.168.199.113:2379]
280-
INFO[0000] [pd] leader switches to: http://127.0.0.1:2379, previous:
281-
INFO[0000] [pd] init cluster id 6554145799874853483
282-
INFO[0000] [kv] Rollback txn 400197262324006914
283-
failed to lookup key Account: [kv:2]Error: key not exist
284-
INFO[0000] [kv] Rollback txn 400197262324006917
285-
Account increased to 1
286-
287-
# run the program again
288-
INFO[0000] [pd] create pd client with endpoints [192.168.199.113:2379]
289-
INFO[0000] [pd] leader switches to: http://127.0.0.1:2379, previous:
290-
INFO[0000] [pd] init cluster id 6554145799874853483
291-
INFO[0000] [kv] Rollback txn 400198364324954114
292-
Account is 1
293-
INFO[0000] [kv] Rollback txn 400198364324954117
294-
Account increased to 2
333+
INFO[0000] [pd] leader switches to: http://192.168.199.113:2379, previous:
334+
INFO[0000] [pd] init cluster id 6563858376412119197
335+
key1 => value1 ([118 97 108 117 101 49])
336+
key1 => value1 ([118 97 108 117 101 49])
337+
key2 => value2 ([118 97 108 117 101 50])
295338
```

0 commit comments

Comments
 (0)