-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsdk-connection-dotnet.cs
More file actions
120 lines (107 loc) · 3.75 KB
/
sdk-connection-dotnet.cs
File metadata and controls
120 lines (107 loc) · 3.75 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
/*
* Couchbase SDK connection singleton — .NET
* Copy and adapt for your application.
*
* Dependencies (NuGet):
* dotnet add package CouchbaseNetClient
*
* For ASP.NET Core, prefer AddCouchbase() in Program.cs (see comment at bottom).
*/
using System;
using System.Threading;
using System.Threading.Tasks;
using Couchbase;
using Couchbase.KeyValue;
namespace MyApp;
public static class CouchbaseConnection
{
// --- Configuration ---
private const string CbHost = "localhost"; // or "cb.xxxxx.cloud.couchbase.com" for Capella
private const string CbUser = "app-service-user";
private const string CbPassword = "AppSecret123!";
private const string CbBucket = "myapp";
private const string CbScope = "_default";
private const string CbCollection = "_default";
private static ICluster? _cluster;
private static ICouchbaseCollection? _collection;
private static readonly SemaphoreSlim _lock = new(1, 1);
/// <summary>Returns the singleton Collection, initializing the cluster on first call.</summary>
public static async Task<ICouchbaseCollection> GetCollectionAsync()
{
if (_collection is not null) return _collection;
await _lock.WaitAsync();
try
{
if (_collection is not null) return _collection;
await InitAsync();
}
finally
{
_lock.Release();
}
return _collection!;
}
/// <summary>Returns the singleton Cluster (needed for queries and transactions).</summary>
public static async Task<ICluster> GetClusterAsync()
{
await GetCollectionAsync(); // ensures cluster is initialized
return _cluster!;
}
private static async Task InitAsync()
{
// Use "couchbases://" for TLS (required for Capella, recommended for production)
_cluster = await Cluster.ConnectAsync($"couchbase://{CbHost}", options =>
{
options.WithCredentials(CbUser, CbPassword);
options.KvTimeout = TimeSpan.FromMilliseconds(2500);
options.QueryTimeout = TimeSpan.FromSeconds(75);
options.SearchTimeout = TimeSpan.FromSeconds(75);
options.BootstrapPollInterval = TimeSpan.FromSeconds(10);
});
await _cluster.WaitUntilReadyAsync(TimeSpan.FromSeconds(10));
var bucket = await _cluster.BucketAsync(CbBucket);
var scope = await bucket.ScopeAsync(CbScope);
_collection = await scope.CollectionAsync(CbCollection);
}
/// <summary>Call on application shutdown to release resources.</summary>
public static async Task CloseAsync()
{
if (_cluster is not null)
await _cluster.DisposeAsync();
}
}
/*
* --- Usage example ---
*
* var col = await CouchbaseConnection.GetCollectionAsync();
* var cluster = await CouchbaseConnection.GetClusterAsync();
*
* // KV upsert
* await col.UpsertAsync("doc_1", new { type = "example", value = 42 });
*
* // KV get
* var result = await col.GetAsync("doc_1");
* var doc = result.ContentAs<dynamic>();
*
* // SQL++ query
* var rows = await cluster.QueryAsync<dynamic>(
* "SELECT * FROM `myapp`._default._default WHERE type = $type LIMIT 5",
* options => options.Parameter("type", "example")
* );
* await foreach (var row in rows) Console.WriteLine(row);
*
* await CouchbaseConnection.CloseAsync();
*
*
* --- ASP.NET Core (preferred for web apps) ---
*
* // Program.cs
* builder.Services.AddCouchbase(options =>
* {
* options.ConnectionString = "couchbase://localhost";
* options.UserName = "app-service-user";
* options.Password = "AppSecret123!";
* });
*
* // Inject IBucketProvider or IClusterProvider into your services.
*/