Fauna .NET Driver 0.1.0-beta
 
Loading...
Searching...
No Matches
Client.cs
Go to the documentation of this file.
3using Fauna.Linq;
4using Fauna.Mapping;
6using System.Globalization;
7using System.Net;
8
9namespace Fauna;
10
14public class Client : BaseClient, IDisposable
15{
16 private const string QueryUriPath = "/query/1";
17
18 private readonly Configuration _config;
19 private readonly IConnection _connection;
20
21 private readonly MappingContext _defaultCtx = new();
22 private readonly Dictionary<Type, DataContext> _dbCtxs = new();
23
24 private bool _disposed;
25
26 internal override MappingContext MappingCtx { get => _defaultCtx; }
27
31 public long LastSeenTxn { get; private set; }
32
37 public Client(string secret) :
38 this(new Configuration(secret))
39 {
40 }
41
46 public Client(Configuration config)
47 {
48 _config = config;
49 _connection = new Connection(config);
50 }
51
57 public DB DataContext<DB>() where DB : DataContext
58 {
59 var dbCtxType = typeof(DB);
60 DataContext? ctx;
61 lock (_dbCtxs)
62 {
63 if (!_dbCtxs.TryGetValue(dbCtxType, out ctx))
64 {
65 var builder = new DataContextBuilder<DB>();
66 ctx = builder.Build(this);
67 _dbCtxs[dbCtxType] = ctx;
68 }
69 }
70
71 return (DB)ctx;
72 }
73
74 internal override async Task<QuerySuccess<T>> QueryAsyncInternal<T>(
75 Query query,
76 IDeserializer<T> deserializer,
78 QueryOptions? queryOptions,
79 CancellationToken cancel)
80 {
81 if (query == null)
82 {
83 throw new ArgumentNullException(nameof(query));
84 }
85
86 var finalOptions = QueryOptions.GetFinalQueryOptions(_config.DefaultQueryOptions, queryOptions);
87 var headers = GetRequestHeaders(finalOptions);
88
89 using var stream = new MemoryStream();
90 Serialize(stream, query, ctx);
91
92 using var httpResponse = await _connection.DoPostAsync(QueryUriPath, stream, headers, cancel);
93 var body = await httpResponse.Content.ReadAsStringAsync(cancel);
94 var res = QueryResponse.GetFromResponseBody<T>(ctx, deserializer, httpResponse.StatusCode, body);
95 switch (res)
96 {
97 case QuerySuccess<T> success:
99 return success;
100 case QueryFailure failure:
101 throw ExceptionFactory.FromQueryFailure(ctx, failure);
102 default:
103 throw ExceptionFactory.FromRawResponse(body, httpResponse);
104 }
105 }
106
107 private void Serialize(Stream stream, Query query, MappingContext ctx)
108 {
109 using var writer = new Utf8FaunaWriter(stream);
110 writer.WriteStartObject();
111 writer.WriteFieldName("query");
112 query.Serialize(ctx, writer);
113 writer.WriteEndObject();
114 writer.Flush();
115 }
116
117 private Dictionary<string, string> GetRequestHeaders(QueryOptions? queryOptions)
118 {
119 var headers = new Dictionary<string, string>
120 {
121
122 { Headers.Authorization, $"Bearer {_config.Secret}"},
123 { Headers.Format, "tagged" },
124 { Headers.Driver, "C#" }
125 };
126
127 if (LastSeenTxn > long.MinValue)
128 {
129 headers.Add(Headers.LastTxnTs, LastSeenTxn.ToString());
130 }
131
132 if (queryOptions != null)
133 {
134 if (queryOptions.QueryTimeout.HasValue)
135 {
136 headers.Add(
137 Headers.QueryTimeoutMs,
138 queryOptions.QueryTimeout.Value.TotalMilliseconds.ToString(CultureInfo.InvariantCulture));
139 }
140
141 if (queryOptions.QueryTags != null)
142 {
143 headers.Add(Headers.QueryTags, EncodeQueryTags(queryOptions.QueryTags));
144 }
145
146 if (!string.IsNullOrEmpty(queryOptions.TraceParent))
147 {
148 headers.Add(Headers.TraceParent, queryOptions.TraceParent);
149 }
150
151 if (queryOptions.Linearized != null)
152 {
153 headers.Add(Headers.Linearized, queryOptions.Linearized.ToString()!);
154 }
155
156 if (queryOptions.TypeCheck != null)
157 {
158 headers.Add(Headers.TypeCheck, queryOptions.TypeCheck.ToString()!);
159 }
160 }
161
162 return headers;
163 }
164
165 private static string EncodeQueryTags(Dictionary<string, string> tags)
166 {
167 return string.Join(",", tags.Select(entry => entry.Key + "=" + entry.Value));
168 }
169
170 private void Dispose(bool disposing)
171 {
172 if (_disposed) return;
173
174 if (disposing)
175 {
176 _connection.Dispose();
177 GC.SuppressFinalize(this);
178 }
179 _disposed = true;
180 }
181
185 public void Dispose()
186 {
187 Dispose(true);
188 GC.SuppressFinalize(this);
189 }
190
191 // A finalizer: https://stackoverflow.com/questions/151051/when-should-i-use-gc-suppressfinalize
192 ~Client()
193 {
194 Dispose(false);
195 }
196}
The base class for Client and DataContext.
Definition IClient.cs:345
Represents a client for interacting with a Fauna.
Definition Client.cs:15
Client(Configuration config)
Initializes a new instance of the Client class using client configuration.
Definition Client.cs:46
Client(string secret)
Initializes a new instance of the Client class using a secret key.
Definition Client.cs:37
long LastSeenTxn
Gets the timestamp of the last transaction seen by this client.
Definition Client.cs:31
DB DataContext< DB >()
Create and return a new database context which uses this client.
Definition Client.cs:57
void Dispose()
Disposes the resources used by the Client class.
Definition Client.cs:185
An HTTP Client wrapper.
Definition Connection.cs:10
Represents a failed query response.
Represents the abstract base class for constructing FQL queries.
Definition Query.cs:11
void Serialize(MappingContext ctx, Utf8FaunaWriter writer)
Serializes the query into the provided stream.
Represents the options for customizing Fauna queries.
string? TraceParent
Gets or sets the trace parent identifier for distributed tracing systems.
TimeSpan? QueryTimeout
Gets or sets the query timeout. It defines how long the client waits for a query to complete.
bool? TypeCheck
Gets or sets a value indicating whether type checking of the query is enabled or disabled before eval...
bool? Linearized
Gets or sets a value indicating whether the query runs as strictly serialized, affecting read-only tr...
Dictionary< string, string >? QueryTags
Gets or sets a string-encoded set of caller-defined tags for identifying the request in logs and resp...
Represents the response from a query executed.
long LastSeenTxn
Gets the last transaction seen by this query.
Represents a successful query response.
Provides functionality for writing data in a streaming manner to a buffer or a stream.
Represents an interface for connections to a Fauna database.
Definition IConnection.cs:7
Definition Client.cs:9
record Configuration
Configuration is a class used to configure a Fauna client. It encapsulates various settings such as t...