Skip to content

Commit 8bcb625

Browse files
author
xuhui-lu
committed
Add sync API for raw client
Signed-off-by: xuhui-lu <luxuhui12345@126.com>
1 parent 4404c7e commit 8bcb625

File tree

3 files changed

+294
-2
lines changed

3 files changed

+294
-2
lines changed

src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub use crate::backoff::Backoff;
123123
#[doc(inline)]
124124
pub use crate::kv::{BoundRange, IntoOwnedRange, Key, KvPair, Value};
125125
#[doc(inline)]
126-
pub use crate::raw::{lowering as raw_lowering, Client as RawClient, ColumnFamily};
126+
pub use crate::raw::{
127+
lowering as raw_lowering, Client as RawClient, ColumnFamily, SyncClient as SyncRawClient,
128+
};
127129
#[doc(inline)]
128130
pub use crate::request::RetryOptions;
129131
#[doc(inline)]

src/raw/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
//!
1010
//! **Warning:** It is not advisable to use both raw and transactional functionality in the same keyspace.
1111
12-
pub use self::client::Client;
12+
pub use self::{client::Client, sync_client::SyncClient};
1313
use crate::Error;
1414
use std::{convert::TryFrom, fmt};
1515

1616
mod client;
1717
pub mod lowering;
1818
mod requests;
19+
mod sync_client;
1920

2021
/// A [`ColumnFamily`](ColumnFamily) is an optional parameter for [`raw::Client`](Client) requests.
2122
///

src/raw/sync_client.rs

+289
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2+
3+
use crate::{
4+
config::Config, raw::client::Client, BoundRange, ColumnFamily, Key, KvPair, Result, Value,
5+
};
6+
use slog::{Drain, Logger};
7+
use futures::executor::block_on;
8+
use std::u32;
9+
10+
#[derive(Clone)]
11+
pub struct SyncClient {
12+
client: Client,
13+
}
14+
15+
impl SyncClient {
16+
/// The synchronous version of RawClient
17+
///
18+
/// # Examples
19+
///
20+
/// ```rust,no_run
21+
/// # use tikv_client::SyncRawClient;
22+
/// let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
23+
/// ```
24+
pub fn new<S: Into<String>>(pd_endpoints: Vec<S>, logger: Option<Logger>) -> Result<SyncClient> {
25+
Self::new_with_config(pd_endpoints, Config::default(), logger)
26+
}
27+
28+
/// Create a raw [`SyncClient`] with a custom configuration, and connect to the TiKV cluster.
29+
///
30+
/// # Examples
31+
///
32+
/// ```rust,no_run
33+
/// # use tikv_client::{Config, SyncRawClient};
34+
/// # use std::time::Duration;
35+
/// let client = SyncRawClient::new_with_config(
36+
/// vec!["192.168.0.100"],
37+
/// Config::default().with_timeout(Duration::from_secs(60)),
38+
/// None,
39+
/// ).unwrap();
40+
/// ```
41+
pub fn new_with_config<S: Into<String>>(
42+
pd_endpoints: Vec<S>,
43+
config: Config,
44+
logger: Option<Logger>,
45+
) -> Result<SyncClient> {
46+
let client = block_on(Client::new_with_config(pd_endpoints, config, logger)).unwrap();
47+
Ok(SyncClient { client: client })
48+
}
49+
50+
pub fn with_cf(&self, cf: ColumnFamily) -> SyncClient {
51+
SyncClient {
52+
client: self.client.with_cf(cf),
53+
}
54+
}
55+
56+
pub fn with_atomic_for_cas(&self) -> SyncClient {
57+
SyncClient {
58+
client: self.client.with_atomic_for_cas(),
59+
}
60+
}
61+
62+
/// Create a new 'get' request.
63+
///
64+
/// Once resolved this request will result in the fetching of the value associated with the
65+
/// given key.
66+
///
67+
/// Retuning `Ok(None)` indicates the key does not exist in TiKV.
68+
///
69+
/// # Examples
70+
/// ```rust,no_run
71+
/// # use tikv_client::{Value, Config, SyncRawClient};
72+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
73+
/// let key = "TiKV".to_owned();
74+
/// let req = client.get(key);
75+
/// let result: Option<Value> = req.unwrap();
76+
/// ```
77+
pub fn get(&self, key: impl Into<Key>) -> Result<Option<Value>> {
78+
block_on(self.client.get(key))
79+
}
80+
81+
/// Create a new 'batch get' request.
82+
///
83+
/// Once resolved this request will result in the fetching of the values associated with the
84+
/// given keys.
85+
///
86+
/// Non-existent entries will not appear in the result. The order of the keys is not retained in the result.
87+
///
88+
/// # Examples
89+
/// ```rust,no_run
90+
/// # use tikv_client::{KvPair, Config, SyncRawClient};
91+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
92+
/// let keys = vec!["TiKV".to_owned(), "TiDB".to_owned()];
93+
/// let req = client.batch_get(keys);
94+
/// let result: Vec<KvPair> = req.unwrap();
95+
/// ```
96+
pub fn batch_get(&self, keys: impl IntoIterator<Item = impl Into<Key>>) -> Result<Vec<KvPair>> {
97+
block_on(self.client.batch_get(keys))
98+
}
99+
100+
/// Create a new 'put' request.
101+
///
102+
/// Once resolved this request will result in the setting of the value associated with the given key.
103+
///
104+
/// # Examples
105+
/// ```rust,no_run
106+
/// # use tikv_client::{Key, Value, Config, SyncRawClient};
107+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
108+
/// let key = "TiKV".to_owned();
109+
/// let val = "TiKV".to_owned();
110+
/// let req = client.put(key, val);
111+
/// let result: () = req.unwrap();
112+
/// ```
113+
pub fn put(&self, key: impl Into<Key>, value: impl Into<Value>) -> Result<()> {
114+
block_on(self.client.put(key, value))
115+
}
116+
117+
/// Create a new 'batch put' request.
118+
///
119+
/// Once resolved this request will result in the setting of the values associated with the given keys.
120+
///
121+
/// # Examples
122+
/// ```rust,no_run
123+
/// # use tikv_client::{Result, KvPair, Key, Value, Config, SyncRawClient, IntoOwnedRange};
124+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
125+
/// let kvpair1 = ("PD".to_owned(), "Go".to_owned());
126+
/// let kvpair2 = ("TiKV".to_owned(), "Rust".to_owned());
127+
/// let iterable = vec![kvpair1, kvpair2];
128+
/// let req = client.batch_put(iterable);
129+
/// let result: () = req.unwrap();
130+
/// ```
131+
pub fn batch_put(&self, pairs: impl IntoIterator<Item = impl Into<KvPair>>) -> Result<()> {
132+
block_on(self.client.batch_put(pairs))
133+
}
134+
135+
/// Create a new 'delete' request.
136+
///
137+
/// Once resolved this request will result in the deletion of the given key.
138+
///
139+
/// It does not return an error if the key does not exist in TiKV.
140+
///
141+
/// # Examples
142+
/// ```rust,no_run
143+
/// # use tikv_client::{Key, Config, SyncRawClient};
144+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
145+
/// let key = "TiKV".to_owned();
146+
/// let req = client.delete(key);
147+
/// let result: () = req.unwrap();
148+
/// ```
149+
pub fn delete(&self, key: impl Into<Key>) -> Result<()> {
150+
block_on(self.client.delete(key))
151+
}
152+
153+
/// Create a new 'batch delete' request.
154+
///
155+
/// Once resolved this request will result in the deletion of the given keys.
156+
///
157+
/// It does not return an error if some of the keys do not exist and will delete the others.
158+
///
159+
/// # Examples
160+
/// ```rust,no_run
161+
/// # use tikv_client::{Config, SyncRawClient};
162+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
163+
/// let keys = vec!["TiKV".to_owned(), "TiDB".to_owned()];
164+
/// let req = client.batch_delete(keys);
165+
/// let result: () = req.unwrap();
166+
/// ```
167+
pub fn batch_delete(&self, keys: impl IntoIterator<Item = impl Into<Key>>) -> Result<()> {
168+
block_on(self.client.batch_delete(keys))
169+
}
170+
171+
/// Create a new 'delete range' request.
172+
///
173+
/// Once resolved this request will result in the deletion of all keys lying in the given range.
174+
///
175+
/// # Examples
176+
/// ```rust,no_run
177+
/// # use tikv_client::{Key, Config, SyncRawClient, IntoOwnedRange};
178+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
179+
/// let inclusive_range = "TiKV"..="TiDB";
180+
/// let req = client.delete_range(inclusive_range.into_owned());
181+
/// let result: () = req.unwrap();
182+
/// ```
183+
pub fn delete_range(&self, range: impl Into<BoundRange>) -> Result<()> {
184+
block_on(self.client.delete_range(range))
185+
}
186+
187+
/// Create a new 'scan' request.
188+
///
189+
/// Once resolved this request will result in a `Vec` of key-value pairs that lies in the specified range.
190+
///
191+
/// If the number of eligible key-value pairs are greater than `limit`,
192+
/// only the first `limit` pairs are returned, ordered by the key.
193+
///
194+
///
195+
/// # Examples
196+
/// ```rust,no_run
197+
/// # use tikv_client::{KvPair, Config, SyncRawClient, IntoOwnedRange};
198+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
199+
/// let inclusive_range = "TiKV"..="TiDB";
200+
/// let req = client.scan(inclusive_range.into_owned(), 2);
201+
/// let result: Vec<KvPair> = req.unwrap();
202+
/// ```
203+
pub fn scan(&self, range: impl Into<BoundRange>, limit: u32) -> Result<Vec<KvPair>> {
204+
block_on(self.client.scan(range, limit))
205+
}
206+
207+
/// Create a new 'scan' request that only returns the keys.
208+
///
209+
/// Once resolved this request will result in a `Vec` of keys that lies in the specified range.
210+
///
211+
/// If the number of eligible keys are greater than `limit`,
212+
/// only the first `limit` pairs are returned, ordered by the key.
213+
///
214+
///
215+
/// # Examples
216+
/// ```rust,no_run
217+
/// # use tikv_client::{Key, Config, SyncRawClient, IntoOwnedRange};
218+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
219+
/// let inclusive_range = "TiKV"..="TiDB";
220+
/// let req = client.scan_keys(inclusive_range.into_owned(), 2);
221+
/// let result: Vec<Key> = req.unwrap();
222+
/// ```
223+
pub fn scan_keys(&self, range: impl Into<BoundRange>, limit: u32) -> Result<Vec<Key>> {
224+
block_on(self.client.scan_keys(range, limit))
225+
}
226+
227+
/// Create a new 'batch scan' request.
228+
///
229+
/// Once resolved this request will result in a set of scanners over the given keys.
230+
///
231+
/// **Warning**: This method is experimental. The `each_limit` parameter does not work as expected.
232+
/// It does not limit the number of results returned of each range,
233+
/// instead it limits the number of results in each region of each range.
234+
/// As a result, you may get **more than** `each_limit` key-value pairs for each range.
235+
/// But you should not miss any entries.
236+
///
237+
/// # Examples
238+
/// ```rust,no_run
239+
/// # use tikv_client::{Key, Config, SyncRawClient, IntoOwnedRange};
240+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
241+
/// let inclusive_range1 = "TiDB"..="TiKV";
242+
/// let inclusive_range2 = "TiKV"..="TiSpark";
243+
/// let iterable = vec![inclusive_range1.into_owned(), inclusive_range2.into_owned()];
244+
/// let result = client.batch_scan(iterable, 2);
245+
/// ```
246+
pub fn batch_scan(
247+
&self,
248+
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
249+
each_limit: u32,
250+
) -> Result<Vec<KvPair>> {
251+
block_on(self.client.batch_scan(ranges, each_limit))
252+
}
253+
254+
/// Create a new 'batch scan' request that only returns the keys.
255+
///
256+
/// Once resolved this request will result in a set of scanners over the given keys.
257+
///
258+
/// **Warning**: This method is experimental.
259+
/// The `each_limit` parameter does not limit the number of results returned of each range,
260+
/// instead it limits the number of results in each region of each range.
261+
/// As a result, you may get **more than** `each_limit` key-value pairs for each range,
262+
/// but you should not miss any entries.
263+
///
264+
/// # Examples
265+
/// ```rust,no_run
266+
/// # use tikv_client::{Key, Config, SyncRawClient, IntoOwnedRange};
267+
/// # let client = SyncRawClient::new(vec!["192.168.0.100"], None).unwrap();
268+
/// let inclusive_range1 = "TiDB"..="TiKV";
269+
/// let inclusive_range2 = "TiKV"..="TiSpark";
270+
/// let iterable = vec![inclusive_range1.into_owned(), inclusive_range2.into_owned()];
271+
/// let result = client.batch_scan(iterable, 2);
272+
/// ```
273+
pub fn batch_scan_keys(
274+
&self,
275+
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
276+
each_limit: u32,
277+
) -> Result<Vec<Key>> {
278+
block_on(self.client.batch_scan_keys(ranges, each_limit))
279+
}
280+
281+
pub fn compare_and_swap(
282+
&self,
283+
key: impl Into<Key>,
284+
previous_value: impl Into<Option<Value>>,
285+
new_value: impl Into<Value>,
286+
) -> Result<(Option<Value>, bool)> {
287+
block_on(self.client.compare_and_swap(key, previous_value, new_value))
288+
}
289+
}

0 commit comments

Comments
 (0)