-
Notifications
You must be signed in to change notification settings - Fork 134
/
Copy pathraw.rs
145 lines (125 loc) · 5.18 KB
/
raw.rs
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
139
140
141
142
143
144
145
// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0.
#![type_length_limit = "8165158"]
mod common;
use tikv_client::Config;
use tikv_client::IntoOwnedRange;
use tikv_client::Key;
use tikv_client::KvPair;
use tikv_client::RawClient as Client;
use tikv_client::Result;
use tikv_client::Value;
use crate::common::parse_args;
const KEY: &str = "TiKV";
const VALUE: &str = "Rust";
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
// 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()
}
// This example uses the default keyspace, so api-v2 must be enabled on the server.
.with_default_keyspace();
// 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).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 {KEY:?}, value {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 `{KEY}` returned value {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: `{KEY}` deleted");
// 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: {values:?} for keys: {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!("Scanning from {start:?} to {end:?} gives: {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!("Scanning batch scan from {batch_scan_keys:?} gives: {vals:?}");
// Delete all keys in the whole range.
client.delete_range("".to_owned().."".to_owned()).await?;
Ok(())
}