-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsdk-connection-rust.rs
More file actions
96 lines (82 loc) · 2.76 KB
/
sdk-connection-rust.rs
File metadata and controls
96 lines (82 loc) · 2.76 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
// Couchbase SDK connection singleton — Rust
// Copy and adapt for your application.
//
// Dependencies (Cargo.toml):
// couchbase = "1"
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
use couchbase::{
authenticator::{Authenticator, PasswordAuthenticator},
cluster::Cluster,
collection::Collection,
options::cluster_options::ClusterOptions,
};
use std::sync::OnceLock;
// --- Configuration ---
const CB_HOST: &str = "localhost"; // or "cb.xxxxx.cloud.couchbase.com" for Capella
const CB_USER: &str = "app-service-user";
const CB_PASSWORD: &str = "AppSecret123!";
const CB_BUCKET: &str = "myapp";
const CB_SCOPE: &str = "_default";
const CB_COLLECTION: &str = "_default";
// Use "couchbases://" for TLS (required for Capella, recommended for production)
const CB_SCHEME: &str = "couchbase";
static CLUSTER: OnceLock<Cluster> = OnceLock::new();
/// Returns the singleton Cluster, initializing it on first call.
/// Call once at application startup (e.g. in main before spawning tasks).
pub async fn get_cluster() -> &'static Cluster {
if let Some(c) = CLUSTER.get() {
return c;
}
let cluster = Cluster::connect(
&format!("{}://{}", CB_SCHEME, CB_HOST),
ClusterOptions::new(Authenticator::PasswordAuthenticator(
PasswordAuthenticator::new(CB_USER, CB_PASSWORD),
)),
)
.await
.expect("Couchbase connect failed");
let bucket = cluster.bucket(CB_BUCKET);
bucket
.wait_until_ready(None)
.await
.expect("Bucket not ready");
CLUSTER.set(cluster).ok();
CLUSTER.get().unwrap()
}
/// Convenience: returns the default Collection from the singleton Cluster.
pub async fn get_collection() -> Collection {
get_cluster()
.await
.bucket(CB_BUCKET)
.scope(CB_SCOPE)
.collection(CB_COLLECTION)
}
// --- Usage example ---
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let collection = get_collection().await;
let cluster = get_cluster().await;
// KV upsert
collection.upsert(
"doc_1",
serde_json::json!({"type": "example", "value": 42}),
None,
).await?;
// KV get
let result = collection.get("doc_1", None).await?;
let doc: serde_json::Value = result.content_as()?;
println!("{doc}");
// SQL++ query
let mut rows = cluster.query(
"SELECT * FROM `myapp`._default._default WHERE type = $type LIMIT 5",
couchbase::options::query_options::QueryOptions::new()
.add_named_parameter("type", "example")?,
).await?;
let mut stream = rows.rows();
while let Some(row) = stream.next().await {
let row: serde_json::Value = row?;
println!("{row}");
}
Ok(())
}