clickhouse_arrow/client/options.rs
1use std::path::PathBuf;
2
3use tracing::warn;
4
5use super::CompressionMethod;
6use crate::native::protocol::ChunkedProtocolMode;
7use crate::prelude::Secret;
8
9/// Configuration options for a `ClickHouse` client connection and Arrow serialization.
10///
11/// The `ClientOptions` struct defines the settings used to establish a connection
12/// to a `ClickHouse` server and handle data serialization/deserialization with
13/// Apache Arrow. These options are typically set via [`ClientBuilder`] methods
14/// (e.g., [`ClientBuilder::with_username`], [`ClientBuilder::with_tls`]) or
15/// constructed directly for use with [`Client::connect`].
16///
17/// # Fields
18/// - `username`: The username for authenticating with `ClickHouse` (default: `"default"`).
19/// - `password`: The password for authentication, stored securely as a [`Secret`].
20/// - `default_database`: The default database for queries; if empty, uses `ClickHouse`'s
21/// `"default"` database.
22/// - `domain`: Optional domain for TLS verification; inferred from the destination if unset.
23/// - `ipv4_only`: If `true`, restricts address resolution to IPv4; if `false`, allows IPv6.
24/// - `cafile`: Optional path to a certificate authority file for TLS connections.
25/// - `use_tls`: If `true`, enables TLS for secure connections; if `false`, uses plain TCP.
26/// - `compression`: The compression method for data exchange (default: [`CompressionMethod::LZ4`]).
27/// - `arrow`: Optional Arrow-specific serialization options (see [`ArrowOptions`]).
28/// - `cloud`: Cloud-specific options for `ClickHouse` cloud instances (requires `cloud` feature).
29///
30/// # Examples
31/// ```rust,ignore
32/// use clickhouse_arrow::prelude::*;
33///
34/// let options = ClientOptions {
35/// username: "admin".to_string(),
36/// password: Secret::new("secret"),
37/// default_database: "my_db".to_string(),
38/// use_tls: true,
39/// ..ClientOptions::default()
40/// };
41///
42/// let client = Client::connect("localhost:9000", options, None, None)
43/// .await
44/// .unwrap();
45/// ```
46#[derive(Debug, Clone, PartialEq)]
47#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
48pub struct ClientOptions {
49 /// Username credential
50 pub username: String,
51 /// Password credential. [`Secret`] is used to minimize likelihood of exposure through logs
52 pub password: Secret,
53 /// Scope this client to a specifc database, otherwise 'default' is used
54 pub default_database: String,
55 /// For tls, provide the domain, otherwise it will be determined from the endpoint.
56 pub domain: Option<String>,
57 /// Whether any non-ipv4 socket addrs should be filtered out.
58 pub ipv4_only: bool,
59 /// Provide a path to a certificate authority to use for tls.
60 pub cafile: Option<PathBuf>,
61 /// Whether a connection should be made securely over tls.
62 pub use_tls: bool,
63 /// The compression to use when sending data to clickhouse.
64 pub compression: CompressionMethod,
65 /// Additional configuration not core to `ClickHouse` connections
66 #[cfg_attr(feature = "serde", serde(default))]
67 pub ext: Extension,
68}
69
70impl Default for ClientOptions {
71 fn default() -> Self {
72 ClientOptions {
73 username: "default".to_string(),
74 password: Secret::new(""),
75 default_database: String::new(),
76 domain: None,
77 ipv4_only: false,
78 cafile: None,
79 use_tls: false,
80 compression: CompressionMethod::default(),
81 ext: Extension::default(),
82 }
83 }
84}
85
86impl ClientOptions {
87 /// Create a new `ClientOptions` with default values.
88 #[must_use]
89 pub fn new() -> Self { Self::default() }
90
91 #[must_use]
92 pub fn with_username(mut self, username: impl Into<String>) -> Self {
93 self.username = username.into();
94 self
95 }
96
97 #[must_use]
98 pub fn with_password(mut self, password: impl Into<Secret>) -> Self {
99 self.password = password.into();
100 self
101 }
102
103 #[must_use]
104 pub fn with_default_database(mut self, default_database: impl Into<String>) -> Self {
105 self.default_database = default_database.into();
106 self
107 }
108
109 #[must_use]
110 pub fn with_domain(mut self, domain: impl Into<String>) -> Self {
111 self.domain = Some(domain.into());
112 self
113 }
114
115 #[must_use]
116 pub fn with_ipv4_only(mut self, ipv4_only: bool) -> Self {
117 self.ipv4_only = ipv4_only;
118 self
119 }
120
121 #[must_use]
122 pub fn with_cafile<P: AsRef<std::path::Path>>(mut self, cafile: P) -> Self {
123 self.cafile = Some(cafile.as_ref().into());
124 self
125 }
126
127 #[must_use]
128 pub fn with_use_tls(mut self, use_tls: bool) -> Self {
129 self.use_tls = use_tls;
130 self
131 }
132
133 #[must_use]
134 pub fn with_compression(mut self, compression: CompressionMethod) -> Self {
135 self.compression = compression;
136 self
137 }
138
139 #[must_use]
140 pub fn with_extension(mut self, ext: Extension) -> Self {
141 self.ext = ext;
142 self
143 }
144
145 #[must_use]
146 pub fn extend(mut self, ext: impl Fn(Extension) -> Extension) -> Self {
147 self.ext = ext(self.ext);
148 self
149 }
150}
151
152/// Extra configuration options for `ClickHouse`.
153///
154/// These options are separated to allow extending the configuration capabilities of a connection
155/// without breaking the core [`ClientOptions`] that are unlikely to ever change. For this reason,
156/// `Extensions` is `non_exhaustive` so the api can change without breaking existing
157/// implementations.
158#[non_exhaustive]
159#[derive(Debug, Default, Clone, PartialEq)]
160#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
161pub struct Extension {
162 /// Options specific to (de)serializing arrow data.
163 pub arrow: Option<ArrowOptions>,
164 /// Options specific to communicating with `ClickHouse` over their cloud offering.
165 #[cfg(feature = "cloud")]
166 pub cloud: CloudOptions,
167 /// Options related to server/client protocol send chunking.
168 /// This may be removed, as it may be defaulted.
169 #[cfg_attr(feature = "serde", serde(default))]
170 pub chunked_send: ChunkedProtocolMode,
171 /// Options related to server/client protocol recv chunking.
172 /// This may be removed, as it may be defaulted
173 #[cfg_attr(feature = "serde", serde(default))]
174 pub chunked_recv: ChunkedProtocolMode,
175 /// Related to `inner_pool`, how many 'inner clients' to spawn. Currently capped at 4.
176 #[cfg(feature = "inner_pool")]
177 #[cfg_attr(feature = "serde", serde(default))]
178 pub fast_mode_size: Option<u8>,
179}
180
181/// Configuration extensions for specialized `ClickHouse` client behavior.
182///
183/// This type provides additional configuration options beyond the standard
184/// client settings, including Arrow format options and cloud-specific settings.
185impl Extension {
186 #[must_use]
187 pub fn with_arrow(mut self, options: ArrowOptions) -> Self {
188 self.arrow = Some(options);
189 self
190 }
191
192 #[must_use]
193 pub fn with_set_arrow(mut self, f: impl Fn(ArrowOptions) -> ArrowOptions) -> Self {
194 self.arrow = Some(f(self.arrow.unwrap_or_default()));
195 self
196 }
197
198 #[must_use]
199 pub fn with_chunked_send_mode(mut self, mode: ChunkedProtocolMode) -> Self {
200 self.chunked_send = mode;
201 self
202 }
203
204 #[must_use]
205 pub fn with_chunked_recv_mode(mut self, mode: ChunkedProtocolMode) -> Self {
206 self.chunked_recv = mode;
207 self
208 }
209
210 #[cfg(feature = "cloud")]
211 #[must_use]
212 pub fn with_cloud(mut self, options: CloudOptions) -> Self {
213 self.cloud = options;
214 self
215 }
216
217 #[cfg(feature = "inner_pool")]
218 #[must_use]
219 pub fn with_fast_mode_size(mut self, size: u8) -> Self {
220 self.fast_mode_size = Some(size);
221 self
222 }
223}
224
225/// Configuration options for Arrow serialization and deserialization with `ClickHouse`.
226///
227/// The `ArrowOptions` struct defines settings that control how Apache Arrow data types
228/// are mapped to `ClickHouse` types during serialization (e.g., inserts), deserialization
229/// (e.g., queries), and schema creation (e.g., DDL operations). These options are used
230/// by [`ArrowClient`] and set via [`ClientBuilder::with_arrow_options`] or directly in
231/// [`ClientOptions`].
232///
233/// # Fields
234/// - `strings_as_strings`: If `true`, maps `ClickHouse` `String` to Arrow `Utf8`; if `false`, maps
235/// to `Binary` (default).
236/// - `use_date32_for_date`: If `true`, maps Arrow `Date32` to `ClickHouse` `Date32`; if `false`,
237/// maps to `Date` (default).
238/// - `strict_schema`: If `true`, enforces strict type mappings during serialization (inserts) and
239/// schema creation, causing errors on `ClickHouse` invariant violations (e.g.,
240/// `Nullable(LowCardinality(String))`); if `false`, attempts to correct violations (e.g., mapping
241/// to `LowCardinality(Nullable(String))`) (default).
242/// - `disable_strict_schema_ddl`: If `true`, prevents automatic strict mode during schema creation
243/// (via [`ArrowOptions::into_strict_ddl`]); if `false`, schema creation defaults to strict mode
244/// (default).
245/// - `nullable_array_default_empty`: If `true`, maps `Nullable(Array(...))` to `Array(...)` with
246/// `[]` for nulls during inserts and schema creation (if `disable_strict_schema_ddl = true`); if
247/// `false`, errors on `Nullable(Array(...))` (default).
248///
249/// # Notes
250/// - During schema creation, options are converted to strict mode (via
251/// [`ArrowOptions::into_strict_ddl`]) unless `disable_strict_schema_ddl` is `true`. Strict mode
252/// sets `strict_schema = true` and effectively enforces `nullable_array_default_empty = false`,
253/// ensuring non-nullable arrays.
254/// - When `strict_schema` is `false`, violations like `Nullable(LowCardinality(String))` are
255/// corrected, but arrays are handled per `nullable_array_default_empty` for inserts, while
256/// nullable arrays are ignored during schema creation.
257/// - If `strict_schema = true` and `nullable_array_default_empty = true`, non-array violations
258/// (e.g., `LowCardinality`) error, but arrays map to `[]` for nulls during insert. This is useful
259/// in cases where the arrow `Schema` is used to create the table, but arrays may come from
260/// different `RecordBatch`es.
261/// - This struct is `#[non_exhaustive]`, so future fields may be added (e.g., for new `ClickHouse`
262/// types or serialization options). Use [`ArrowOptions::new`] or [`ArrowOptions::default`] to
263/// construct instances.
264///
265/// # Examples
266/// ```rust,ignore
267/// use clickhouse_arrow::prelude::*;
268///
269/// let arrow_options = ArrowOptions::new()
270/// .with_strings_as_strings(true)
271/// .with_strict_schema(true)
272/// .with_nullable_array_default_empty(false);
273/// let options = ClientOptions {
274/// arrow: Some(arrow_options),
275/// ..ClientOptions::default()
276/// };
277/// ```
278#[expect(clippy::struct_excessive_bools)]
279#[non_exhaustive]
280#[derive(Debug, Clone, Copy, PartialEq, Eq)]
281#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
282pub struct ArrowOptions {
283 pub(crate) strings_as_strings: bool,
284 pub(crate) use_date32_for_date: bool,
285 pub(crate) strict_schema: bool,
286 pub(crate) disable_strict_schema_ddl: bool,
287 pub(crate) nullable_array_default_empty: bool,
288}
289
290impl Default for ArrowOptions {
291 /// Creates an `ArrowOptions` instance with default values.
292 ///
293 /// The default configuration uses relaxed type mappings suitable for most
294 /// `ClickHouse` and `Arrow` use cases:
295 /// - `ClickHouse` `String` maps to Arrow `Binary`.
296 /// - Arrow `Date32` maps to `ClickHouse` `Date`.
297 /// - Type mappings are relaxed, correcting `ClickHouse` invariant violations (e.g., mapping
298 /// `Nullable(LowCardinality(String))` to `LowCardinality(Nullable(String))`).
299 /// - Schema creation defaults to strict mode (via [`ArrowOptions::into_strict_ddl`]).
300 /// - `Nullable(Array(...))` defaults to `Array(...)` with `[]` for nulls.
301 ///
302 /// Use this as a starting point and customize with methods like
303 /// [`ArrowOptions::with_strings_as_strings`].
304 ///
305 /// # Returns
306 /// An [`ArrowOptions`] instance with default settings.
307 ///
308 /// # Examples
309 /// ```rust,ignore
310 /// use clickhouse_arrow::arrow::ArrowOptions;
311 ///
312 /// let arrow_options = ArrowOptions::default();
313 /// println!("Nullable array default empty: {}", arrow_options.nullable_array_default_empty); // true
314 /// ```
315 fn default() -> Self { Self::new() }
316}
317
318impl ArrowOptions {
319 /// Creates a new `ArrowOptions` instance with default values.
320 ///
321 /// This method is equivalent to [`ArrowOptions::default`], initializing fields for
322 /// relaxed type mappings. Use this to start configuring Arrow
323 /// serialization/deserialization options for `ClickHouse`.
324 ///
325 /// # Returns
326 /// A new [`ArrowOptions`] instance with default settings.
327 ///
328 /// # Examples
329 /// ```rust,ignore
330 /// use clickhouse_arrow::arrow::ArrowOptions;
331 ///
332 /// let arrow_options = ArrowOptions::new();
333 /// println!("Nullable array default empty: {}", arrow_options.nullable_array_default_empty); // true
334 /// ```
335 pub const fn new() -> Self {
336 Self {
337 strings_as_strings: false,
338 use_date32_for_date: false,
339 strict_schema: false,
340 disable_strict_schema_ddl: false,
341 nullable_array_default_empty: true,
342 }
343 }
344
345 /// Creates an `ArrowOptions` instance with strict type mapping settings.
346 ///
347 /// This method configures options for strict type mappings, where `ClickHouse`
348 /// invariant violations (e.g., `Nullable(LowCardinality(String))` or
349 /// `Nullable(Array(...))`) cause errors during serialization (inserts) and schema
350 /// creation. It sets `strict_schema` to `true` and `nullable_array_default_empty` to
351 /// `false`, leaving other fields as `false`. Use this for operations where
352 /// `ClickHouse` invariants must be strictly enforced.
353 ///
354 /// # Returns
355 /// An [`ArrowOptions`] instance with strict settings.
356 ///
357 /// # Examples
358 /// ```rust,ignore
359 /// use clickhouse_arrow::arrow::ArrowOptions;
360 ///
361 /// let arrow_options = ArrowOptions::strict();
362 /// println!("Strict schema: {}", arrow_options.strict_schema); // true
363 /// ```
364 pub const fn strict() -> Self {
365 Self {
366 strings_as_strings: false,
367 use_date32_for_date: false,
368 strict_schema: true,
369 disable_strict_schema_ddl: false,
370 nullable_array_default_empty: false,
371 }
372 }
373
374 /// Converts the options to strict mode for schema creation, unless disabled.
375 ///
376 /// This method returns a new [`ArrowOptions`] with strict settings (equivalent to
377 /// [`ArrowOptions::strict`]) unless `disable_strict_schema_ddl` is `true`. If
378 /// `disable_strict_schema_ddl` is `true`, the original options are returned
379 /// unchanged. This method is called automatically during schema creation to enforce
380 /// `ClickHouse` invariants, including non-nullable arrays, unless explicitly disabled.
381 ///
382 /// # Returns
383 /// A new [`ArrowOptions`] instance with strict settings or the original options.
384 ///
385 /// # Examples
386 /// ```rust,ignore
387 /// use clickhouse_arrow::arrow::ArrowOptions;
388 ///
389 /// let options_strict_off = ArrowOptions::new()
390 /// .with_disable_strict_schema_ddl(true)
391 /// .into_strict_ddl();
392 /// assert!(!options_strict_off.strict_schema);
393 /// assert!(options_strict_off.nullable_array_default_empty);
394 ///
395 /// let options_strict = ArrowOptions::new()
396 /// .with_disable_strict_schema_ddl(false) // Default
397 /// .into_strict_ddl();
398 /// assert!(options_strict.strict_schema);
399 /// assert!(!options_strict.nullable_array_default_empty);
400 /// ```
401 #[must_use]
402 pub fn into_strict_ddl(self) -> Self {
403 if self.disable_strict_schema_ddl {
404 return self;
405 }
406
407 Self {
408 strings_as_strings: self.strings_as_strings,
409 use_date32_for_date: self.use_date32_for_date,
410 ..Self::strict()
411 }
412 }
413
414 /// Sets whether `ClickHouse` `String` types are deserialized as Arrow `Utf8`.
415 ///
416 /// By default, `ClickHouse` `String` types map to Arrow `Binary`. When this option
417 /// is enabled (`true`), they map to Arrow `Utf8`, which is more suitable for text
418 /// data. Use this to control serialization/deserialization behavior for string
419 /// columns.
420 ///
421 /// # Parameters
422 /// - `enabled`: If `true`, maps [`crate::Type::String`] to
423 /// [`arrow::datatypes::DataType::Utf8`]; if `false`, maps to
424 /// [`arrow::datatypes::DataType::Binary`].
425 ///
426 /// # Returns
427 /// A new [`ArrowOptions`] with the updated setting.
428 ///
429 /// # Examples
430 /// ```rust,ignore
431 /// use clickhouse_arrow::prelude::*;
432 ///
433 /// let arrow_options = ArrowOptions::new()
434 /// .with_strings_as_strings(true);
435 /// println!("Strings as strings: {}", arrow_options.strings_as_strings); // true
436 /// ```
437 #[must_use]
438 pub fn with_strings_as_strings(mut self, enabled: bool) -> Self {
439 self.strings_as_strings = enabled;
440 self
441 }
442
443 /// Sets whether Arrow `Date32` is mapped to `ClickHouse` `Date` or `Date32`.
444 ///
445 /// By default, Arrow `Date32` maps to `ClickHouse` `Date` (days since 1970-01-01).
446 /// When this option is enabled (`true`), it maps to `ClickHouse` `Date32` (days
447 /// since 1900-01-01). Use this to control date serialization/deserialization
448 /// behavior.
449 ///
450 /// # Parameters
451 /// - `enabled`: If `true`, maps `Date32` to `ClickHouse` `Date32`; if `false`, maps to `Date`.
452 ///
453 /// # Returns
454 /// A new [`ArrowOptions`] with the updated setting.
455 ///
456 /// # Examples
457 /// ```rust,ignore
458 /// use clickhouse_arrow::prelude::*;
459 ///
460 /// let arrow_options = ArrowOptions::new()
461 /// .with_use_date32_for_date(true);
462 /// println!("Use Date32 for Date: {}", arrow_options.use_date32_for_date); // true
463 /// ```
464 #[must_use]
465 pub fn with_use_date32_for_date(mut self, enabled: bool) -> Self {
466 self.use_date32_for_date = enabled;
467 self
468 }
469
470 /// Sets whether type mappings are strict during serialization and schema creation.
471 ///
472 /// By default, type mappings are relaxed, allowing `ClickHouse` invariant violations
473 /// (e.g., `Nullable(LowCardinality(String))`) to be corrected automatically (e.g.,
474 /// mapping to `LowCardinality(Nullable(String))`). When this option is enabled
475 /// (`true`), non-array violations cause errors during serialization (inserts) and
476 /// schema creation. Array violations are controlled by
477 /// [`ArrowOptions::with_nullable_array_default_empty`]. Schema creation defaults to
478 /// strict mode unless [`ArrowOptions::with_disable_strict_schema_ddl`] is enabled.
479 ///
480 /// # Parameters
481 /// - `enabled`: If `true`, enforces strict type mappings for non-array types; if `false`,
482 /// allows relaxed corrections.
483 ///
484 /// # Returns
485 /// A new [`ArrowOptions`] with the updated setting.
486 ///
487 /// # Examples
488 /// ```rust,ignore
489 /// use clickhouse_arrow::arrow::ArrowOptions;
490 ///
491 /// let arrow_options = ArrowOptions::new()
492 /// .with_strict_schema(true);
493 /// println!("Strict schema: {}", arrow_options.strict_schema); // true
494 /// ```
495 #[must_use]
496 pub fn with_strict_schema(mut self, enabled: bool) -> Self {
497 self.strict_schema = enabled;
498 self
499 }
500
501 /// Sets whether strict mode is disabled during schema creation.
502 ///
503 /// By default, schema creation (e.g., DDL operations) uses strict type mappings (via
504 /// [`ArrowOptions::into_strict_ddl`]), enforcing `ClickHouse` invariants and causing
505 /// errors on violations, including `Nullable(Array(...))`. When this option is
506 /// enabled (`true`), strict mode is disabled for schema creation, using the user’s
507 /// `strict_schema` and `nullable_array_default_empty` settings.
508 ///
509 /// # Parameters
510 /// - `enabled`: If `true`, disables strict mode for schema creation; if `false`, enables strict
511 /// mode.
512 ///
513 /// # Returns
514 /// A new [`ArrowOptions`] with the updated setting.
515 ///
516 /// # Examples
517 /// ```rust,ignore
518 /// use clickhouse_arrow::arrow::ArrowOptions;
519 ///
520 /// let arrow_options = ArrowOptions::new()
521 /// .with_disable_strict_schema_ddl(true);
522 /// assert!(arrow_options.disable_strict_schema_ddl);
523 /// ```
524 #[must_use]
525 pub fn with_disable_strict_schema_ddl(mut self, enabled: bool) -> Self {
526 self.disable_strict_schema_ddl = enabled;
527 self
528 }
529
530 /// Sets whether `Nullable(Array(...))` types default to empty arrays during inserts and are
531 /// coerced to non-nullable during DDL.
532 ///
533 /// By default, `Nullable(Array(...))` types are mapped to `Array(...)` with `[]` for
534 /// nulls during serialization (inserts) and schema creation (if
535 /// `disable_strict_schema_ddl = true`). When this option is disabled (`false`),
536 /// `Nullable(Array(...))` causes errors, enforcing non-nullable arrays. Schema
537 /// creation defaults to non-nullable arrays unless
538 /// [`ArrowOptions::with_disable_strict_schema_ddl`] is enabled.
539 ///
540 /// # Parameters
541 /// - `enabled`: If `true`, maps `Nullable(Array(...))` to `Array(...)` with `[]` for nulls; if
542 /// `false`, errors on `Nullable(Array(...))`.
543 ///
544 /// # Returns
545 /// A new [`ArrowOptions`] with the updated setting.
546 ///
547 /// # Examples
548 /// ```rust,ignore
549 /// use clickhouse_arrow::arrow::ArrowOptions;
550 ///
551 /// let arrow_options = ArrowOptions::new()
552 /// .with_nullable_array_default_empty(false);
553 /// assert!(!arrow_options.nullable_array_default_empty);
554 /// ```
555 #[must_use]
556 pub fn with_nullable_array_default_empty(mut self, enabled: bool) -> Self {
557 self.nullable_array_default_empty = enabled;
558 self
559 }
560
561 /// Sets an Arrow option by name and value.
562 ///
563 /// This method updates a specific option identified by `name` to the given boolean
564 /// `value`. Currently supported names are:
565 /// - `"strings_as_strings"`: Maps `ClickHouse` `String` to Arrow `Utf8`.
566 /// - `"use_date32_for_date"`: Maps Arrow `Date32` to `ClickHouse` `Date32`.
567 /// - `"strict_schema"`: Enforces strict type mappings for non-array types.
568 /// - `"disable_strict_schema_ddl"`: Disables strict mode for schema creation.
569 /// - `"nullable_array_default_empty"`: Maps `Nullable(Array(...))` to `Array(...)` with `[]`
570 /// for nulls.
571 ///
572 /// If an unrecognized name is provided, a warning is logged, and the options are
573 /// returned unchanged. Use this for dynamic configuration or when options are
574 /// specified as key-value pairs.
575 ///
576 /// # Parameters
577 /// - `name`: The name of the option to set.
578 /// - `value`: The boolean value to set for the option.
579 ///
580 /// # Returns
581 /// A new [`ArrowOptions`] with the updated setting.
582 ///
583 /// # Examples
584 /// ```rust,ignore
585 /// use clickhouse_arrow::arrow::ArrowOptions;
586 ///
587 /// let arrow_options = ArrowOptions::new()
588 /// .with_setting("strings_as_strings", true)
589 /// .with_setting("nullable_array_default_empty", false);
590 /// assert!(arrow_options.strings_as_strings);
591 /// assert!(!arrow_options.nullable_array_default_empty);
592 /// ```
593 #[must_use]
594 pub fn with_setting(self, name: &str, value: bool) -> Self {
595 match name {
596 "strings_as_strings" => self.with_strings_as_strings(value),
597 "use_date32_for_date" => self.with_use_date32_for_date(value),
598 "strict_schema" => self.with_strict_schema(value),
599 "disable_strict_schema_ddl" => self.with_disable_strict_schema_ddl(value),
600 "nullable_array_default_empty" => self.with_nullable_array_default_empty(value),
601 k => {
602 warn!("Unrecognized option for ArrowOptions: {k}");
603 self
604 }
605 }
606 }
607}
608
609impl<'a, S, I> From<I> for ArrowOptions
610where
611 S: AsRef<str> + 'a,
612 I: Iterator<Item = &'a (S, bool)> + 'a,
613{
614 /// Creates an `ArrowOptions` instance from an iterator of key-value pairs.
615 ///
616 /// This method constructs an [`ArrowOptions`] by applying settings from an iterator
617 /// of `(key, value)` pairs, where `key` is a string (e.g., `"strict_schema"`) and
618 /// `value` is a boolean. It uses [`ArrowOptions::with_setting`] to apply each
619 /// setting. Unrecognized keys trigger a warning but do not cause an error.
620 ///
621 /// See currently supported keys by inspecting [`ArrowOptions::with_setting`].
622 ///
623 /// # Parameters
624 /// - `value`: An iterator of `(key, value)` pairs, where `key` is a string-like type and
625 /// `value` is a boolean.
626 ///
627 /// # Returns
628 /// An [`ArrowOptions`] instance with the applied settings.
629 ///
630 /// # Examples
631 /// ```rust,ignore
632 /// use clickhouse_arrow::arrow::ArrowOptions;
633 ///
634 /// let settings = vec![("strings_as_strings", true), ("nullable_array_default_empty", false)];
635 /// let arrow_options: ArrowOptions = settings.iter().collect();
636 /// assert!(arrow_options.strings_as_strings);
637 /// assert!(!arrow_options.nullable_array_default_empty);
638 /// ```
639 fn from(value: I) -> Self {
640 let mut options = ArrowOptions::default();
641 for (k, v) in value {
642 options = options.with_setting(k.as_ref(), *v);
643 }
644 options
645 }
646}
647
648impl<'a> FromIterator<(&'a str, bool)> for ArrowOptions {
649 /// Creates an `ArrowOptions` instance from an iterator of string-boolean pairs.
650 ///
651 /// This method constructs an [`ArrowOptions`] by applying settings from an iterator
652 /// of `(key, value)` pairs, where `key` is a string slice (e.g., `"strict_schema"`)
653 /// and `value` is a boolean. It uses [`ArrowOptions::with_setting`] to apply each
654 /// setting. Unrecognized keys trigger a warning but do not cause an error.
655 ///
656 /// See currently supported keys by inspecting [`ArrowOptions::with_setting`].
657 ///
658 /// # Parameters
659 /// - `iter`: An iterator of `(key, value)` pairs, where `key` is a string slice and `value` is
660 /// a boolean.
661 ///
662 /// # Returns
663 /// An [`ArrowOptions`] instance with the applied settings.
664 ///
665 /// # Examples
666 /// ```rust,ignore
667 /// use clickhouse_arrow::arrow::ArrowOptions;
668 ///
669 /// let settings = vec![("strings_as_strings", true), ("nullable_array_default_empty", false)];
670 /// let arrow_options = ArrowOptions::from_iter(settings);
671 /// assert!(arrow_options.strings_as_strings);
672 /// assert!(!arrow_options.nullable_array_default_empty);
673 /// ```
674 fn from_iter<I: IntoIterator<Item = (&'a str, bool)>>(iter: I) -> Self {
675 let mut options = ArrowOptions::default();
676 for (k, v) in iter {
677 options = options.with_setting(k, v);
678 }
679 options
680 }
681}
682
683/// Configuration options for connecting to `ClickHouse` cloud instances.
684///
685/// The `CloudOptions` struct defines settings specific to `ClickHouse` cloud
686/// deployments, used within [`ClientOptions`]. These options control the behavior
687/// of cloud wakeup pings to ensure the instance is active before connecting.
688///
689/// # Fields
690/// - `timeout`: Optional timeout (in seconds) for the cloud wakeup ping; if `None`, uses a default
691/// timeout.
692/// - `wakeup`: If `true`, sends a wakeup ping before connecting; if `false`, skips the ping.
693///
694/// # Feature
695/// Requires the `cloud` feature to be enabled.
696///
697/// # Examples
698/// ```rust,ignore
699/// use clickhouse_arrow::prelude::*;
700///
701/// let cloud_options = CloudOptions {
702/// timeout: Some(10),
703/// wakeup: true,
704/// };
705/// let options = ClientOptions {
706/// cloud: cloud_options,
707/// ..ClientOptions::default()
708/// };
709/// ```
710#[derive(Debug, Clone, Copy, Default, PartialEq)]
711#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
712pub struct CloudOptions {
713 #[cfg_attr(feature = "serde", serde(default))]
714 pub timeout: Option<u64>,
715 #[cfg_attr(feature = "serde", serde(default))]
716 pub wakeup: bool,
717}