-
Notifications
You must be signed in to change notification settings - Fork 152
Expand file tree
/
Copy pathraw.rs
More file actions
138 lines (121 loc) · 4.96 KB
/
raw.rs
File metadata and controls
138 lines (121 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0.
#![type_length_limit = "8165158"]
mod common;
use crate::common::parse_args;
use tikv_client::{
request::request_codec::RawApiV1, Config, IntoOwnedRange, Key, KvPair, RawClient as Client,
Result, Value,
};
const KEY: &str = "TiKV";
const VALUE: &str = "Rust";
#[tokio::main]
async fn main() -> Result<()> {
// You can try running this example by passing your pd endpoints
// (and SSL options if necessary) through command line arguments.
let args = parse_args("raw");
// Create a configuration to use for the example.
// Optionally encrypt the traffic.
let config = if let (Some(ca), Some(cert), Some(key)) = (args.ca, args.cert, args.key) {
Config::default().with_security(ca, cert, key)
} else {
Config::default()
};
// When we first create a client we receive a `Connect` structure which must be resolved before
// the client is actually connected and usable.
let client = Client::new_with_config(args.pd, config, RawApiV1, None).await?;
// Requests are created from the connected client. These calls return structures which
// implement `Future`. This means the `Future` must be resolved before the action ever takes
// place.
//
// Here we set the key `TiKV` to have the value `Rust` associated with it.
client.put(KEY.to_owned(), VALUE.to_owned()).await.unwrap(); // Returns a `tikv_client::Error` on failure.
println!("Put key {:?}, value {:?}.", KEY, VALUE);
// Unlike a standard Rust HashMap all calls take owned values. This is because under the hood
// protobufs must take ownership of the data. If we only took a borrow we'd need to internally
// clone it. This is against Rust API guidelines, so you must manage this yourself.
//
// Above, you saw we can use a `&'static str`, this is primarily for making examples short.
// This type is practical to use for real things, and usage forces an internal copy.
//
// It is best to pass a `Vec<u8>` in terms of explicitness and speed. `String`s and a few other
// types are supported as well, but it all ends up as `Vec<u8>` in the end.
let value: Option<Value> = client.get(KEY.to_owned()).await?;
assert_eq!(value, Some(Value::from(VALUE.to_owned())));
println!("Get key `{}` returned value {:?}.", KEY, value);
// You can also set the `ColumnFamily` used by the request.
// This is *advanced usage* and should have some special considerations.
client
.delete(KEY.to_owned())
.await
.expect("Could not delete value");
println!("Key: `{}` deleted", KEY);
// Here we check if the key has been deleted from the key-value store.
let value: Option<Value> = client
.get(KEY.to_owned())
.await
.expect("Could not get just deleted entry");
assert!(value.is_none());
// You can ask to write multiple key-values at the same time, it is much more
// performant because it is passed in one request to the key-value store.
let pairs = vec![
KvPair::from(("k1".to_owned(), "v1".to_owned())),
KvPair::from(("k2".to_owned(), "v2".to_owned())),
KvPair::from(("k3".to_owned(), "v3".to_owned())),
];
client.batch_put(pairs).await.expect("Could not put pairs");
// Same thing when you want to retrieve multiple values.
let keys = vec![Key::from("k1".to_owned()), Key::from("k2".to_owned())];
let values = client
.batch_get(keys.clone())
.await
.expect("Could not get values");
println!("Found values: {:?} for keys: {:?}", values, keys);
// Scanning a range of keys is also possible giving it two bounds
// it will returns all entries between these two.
let start = "k1";
let end = "k2";
let pairs = client
.scan((start..=end).into_owned(), 10)
.await
.expect("Could not scan");
let keys: Vec<_> = pairs.into_iter().map(|p| p.key().clone()).collect();
assert_eq!(
&keys,
&[Key::from("k1".to_owned()), Key::from("k2".to_owned()),]
);
println!("Scaning from {:?} to {:?} gives: {:?}", start, end, keys);
let k1 = "k1";
let k2 = "k2";
let k3 = "k3";
let batch_scan_keys = vec![
(k1.to_owned()..=k2.to_owned()),
(k2.to_owned()..=k3.to_owned()),
(k1.to_owned()..=k3.to_owned()),
];
let kv_pairs = client
.batch_scan(batch_scan_keys.to_owned(), 10)
.await
.expect("Could not batch scan");
let vals: Vec<_> = kv_pairs
.into_iter()
.map(|p| String::from_utf8(p.1).unwrap())
.collect();
assert_eq!(
&vals,
&[
"v1".to_owned(),
"v2".to_owned(),
"v2".to_owned(),
"v3".to_owned(),
"v1".to_owned(),
"v2".to_owned(),
"v3".to_owned()
]
);
println!(
"Scaning batch scan from {:?} gives: {:?}",
batch_scan_keys, vals
);
// Cleanly exit.
Ok(())
}