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// TODO: Remove - make the properties public!
226/// Configuration options for Arrow serialization and deserialization with `ClickHouse`.
227///
228/// The `ArrowOptions` struct defines settings that control how Apache Arrow data types
229/// are mapped to `ClickHouse` types during serialization (e.g., inserts), deserialization
230/// (e.g., queries), and schema creation (e.g., DDL operations). These options are used
231/// by [`ArrowClient`] and set via [`ClientBuilder::with_arrow_options`] or directly in
232/// [`ClientOptions`].
233///
234/// # Fields
235/// - `strings_as_strings`: If `true`, maps `ClickHouse` `String` to Arrow `Utf8`; if `false`, maps
236/// to `Binary` (default).
237/// - `use_date32_for_date`: If `true`, maps Arrow `Date32` to `ClickHouse` `Date32`; if `false`,
238/// maps to `Date` (default).
239/// - `strict_schema`: If `true`, enforces strict type mappings during serialization (inserts) and
240/// schema creation, causing errors on `ClickHouse` invariant violations (e.g.,
241/// `Nullable(LowCardinality(String))`); if `false`, attempts to correct violations (e.g., mapping
242/// to `LowCardinality(Nullable(String))`) (default).
243/// - `disable_strict_schema_ddl`: If `true`, prevents automatic strict mode during schema creation
244/// (via [`ArrowOptions::into_strict_ddl`]); if `false`, schema creation defaults to strict mode
245/// (default).
246/// - `nullable_array_default_empty`: If `true`, maps `Nullable(Array(...))` to `Array(...)` with
247/// `[]` for nulls during inserts and schema creation (if `disable_strict_schema_ddl = true`); if
248/// `false`, errors on `Nullable(Array(...))` (default).
249///
250/// # Notes
251/// - During schema creation, options are converted to strict mode (via
252/// [`ArrowOptions::into_strict_ddl`]) unless `disable_strict_schema_ddl` is `true`. Strict mode
253/// sets `strict_schema = true` and effectively enforces `nullable_array_default_empty = false`,
254/// ensuring non-nullable arrays.
255/// - When `strict_schema` is `false`, violations like `Nullable(LowCardinality(String))` are
256/// corrected, but arrays are handled per `nullable_array_default_empty` for inserts, while
257/// nullable arrays are ignored during schema creation.
258/// - If `strict_schema = true` and `nullable_array_default_empty = true`, non-array violations
259/// (e.g., `LowCardinality`) error, but arrays map to `[]` for nulls during insert. This is useful
260/// in cases where the arrow `Schema` is used to create the table, but arrays may come from
261/// different `RecordBatch`es.
262/// - This struct is `#[non_exhaustive]`, so future fields may be added (e.g., for new `ClickHouse`
263/// types or serialization options). Use [`ArrowOptions::new`] or [`ArrowOptions::default`] to
264/// construct instances.
265///
266/// # Examples
267/// ```rust,ignore
268/// use clickhouse_arrow::prelude::*;
269///
270/// let arrow_options = ArrowOptions::new()
271/// .with_strings_as_strings(true)
272/// .with_strict_schema(true)
273/// .with_nullable_array_default_empty(false);
274/// let options = ClientOptions {
275/// arrow: Some(arrow_options),
276/// ..ClientOptions::default()
277/// };
278/// ```
279#[expect(clippy::struct_excessive_bools)]
280#[non_exhaustive]
281#[derive(Debug, Clone, Copy, PartialEq, Eq)]
282#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
283pub struct ArrowOptions {
284 pub strings_as_strings: bool,
285 pub use_date32_for_date: bool,
286 pub strict_schema: bool,
287 pub disable_strict_schema_ddl: bool,
288 pub nullable_array_default_empty: bool,
289}
290
291impl Default for ArrowOptions {
292 /// Creates an `ArrowOptions` instance with default values.
293 ///
294 /// The default configuration uses relaxed type mappings suitable for most
295 /// `ClickHouse` and `Arrow` use cases:
296 /// - `ClickHouse` `String` maps to Arrow `Binary`.
297 /// - Arrow `Date32` maps to `ClickHouse` `Date`.
298 /// - Type mappings are relaxed, correcting `ClickHouse` invariant violations (e.g., mapping
299 /// `Nullable(LowCardinality(String))` to `LowCardinality(Nullable(String))`).
300 /// - Schema creation defaults to strict mode (via [`ArrowOptions::into_strict_ddl`]).
301 /// - `Nullable(Array(...))` defaults to `Array(...)` with `[]` for nulls.
302 ///
303 /// Use this as a starting point and customize with methods like
304 /// [`ArrowOptions::with_strings_as_strings`].
305 ///
306 /// # Returns
307 /// An [`ArrowOptions`] instance with default settings.
308 ///
309 /// # Examples
310 /// ```rust,ignore
311 /// use clickhouse_arrow::arrow::ArrowOptions;
312 ///
313 /// let arrow_options = ArrowOptions::default();
314 /// println!("Nullable array default empty: {}", arrow_options.nullable_array_default_empty); // true
315 /// ```
316 fn default() -> Self { Self::new() }
317}
318
319impl ArrowOptions {
320 /// Creates a new `ArrowOptions` instance with default values.
321 ///
322 /// This method is equivalent to [`ArrowOptions::default`], initializing fields for
323 /// relaxed type mappings. Use this to start configuring Arrow
324 /// serialization/deserialization options for `ClickHouse`.
325 ///
326 /// # Returns
327 /// A new [`ArrowOptions`] instance with default settings.
328 ///
329 /// # Examples
330 /// ```rust,ignore
331 /// use clickhouse_arrow::arrow::ArrowOptions;
332 ///
333 /// let arrow_options = ArrowOptions::new();
334 /// println!("Nullable array default empty: {}", arrow_options.nullable_array_default_empty); // true
335 /// ```
336 pub const fn new() -> Self {
337 Self {
338 strings_as_strings: false,
339 use_date32_for_date: false,
340 strict_schema: false,
341 disable_strict_schema_ddl: false,
342 nullable_array_default_empty: true,
343 }
344 }
345
346 /// Creates an `ArrowOptions` instance with strict type mapping settings.
347 ///
348 /// This method configures options for strict type mappings, where `ClickHouse`
349 /// invariant violations (e.g., `Nullable(LowCardinality(String))` or
350 /// `Nullable(Array(...))`) cause errors during serialization (inserts) and schema
351 /// creation. It sets `strict_schema` to `true` and `nullable_array_default_empty` to
352 /// `false`, leaving other fields as `false`. Use this for operations where
353 /// `ClickHouse` invariants must be strictly enforced.
354 ///
355 /// # Returns
356 /// An [`ArrowOptions`] instance with strict settings.
357 ///
358 /// # Examples
359 /// ```rust,ignore
360 /// use clickhouse_arrow::arrow::ArrowOptions;
361 ///
362 /// let arrow_options = ArrowOptions::strict();
363 /// println!("Strict schema: {}", arrow_options.strict_schema); // true
364 /// ```
365 pub const fn strict() -> Self {
366 Self {
367 strings_as_strings: false,
368 use_date32_for_date: false,
369 strict_schema: true,
370 disable_strict_schema_ddl: false,
371 nullable_array_default_empty: false,
372 }
373 }
374
375 /// Converts the options to strict mode for schema creation, unless disabled.
376 ///
377 /// This method returns a new [`ArrowOptions`] with strict settings (equivalent to
378 /// [`ArrowOptions::strict`]) unless `disable_strict_schema_ddl` is `true`. If
379 /// `disable_strict_schema_ddl` is `true`, the original options are returned
380 /// unchanged. This method is called automatically during schema creation to enforce
381 /// `ClickHouse` invariants, including non-nullable arrays, unless explicitly disabled.
382 ///
383 /// # Returns
384 /// A new [`ArrowOptions`] instance with strict settings or the original options.
385 ///
386 /// # Examples
387 /// ```rust,ignore
388 /// use clickhouse_arrow::arrow::ArrowOptions;
389 ///
390 /// let options_strict_off = ArrowOptions::new()
391 /// .with_disable_strict_schema_ddl(true)
392 /// .into_strict_ddl();
393 /// assert!(!options_strict_off.strict_schema);
394 /// assert!(options_strict_off.nullable_array_default_empty);
395 ///
396 /// let options_strict = ArrowOptions::new()
397 /// .with_disable_strict_schema_ddl(false) // Default
398 /// .into_strict_ddl();
399 /// assert!(options_strict.strict_schema);
400 /// assert!(!options_strict.nullable_array_default_empty);
401 /// ```
402 #[must_use]
403 pub fn into_strict_ddl(self) -> Self {
404 if self.disable_strict_schema_ddl {
405 return self;
406 }
407
408 Self {
409 strings_as_strings: self.strings_as_strings,
410 use_date32_for_date: self.use_date32_for_date,
411 ..Self::strict()
412 }
413 }
414
415 /// Sets whether `ClickHouse` `String` types are deserialized as Arrow `Utf8`.
416 ///
417 /// By default, `ClickHouse` `String` types map to Arrow `Binary`. When this option
418 /// is enabled (`true`), they map to Arrow `Utf8`, which is more suitable for text
419 /// data. Use this to control serialization/deserialization behavior for string
420 /// columns.
421 ///
422 /// # Parameters
423 /// - `enabled`: If `true`, maps [`crate::Type::String`] to
424 /// [`arrow::datatypes::DataType::Utf8`]; if `false`, maps to
425 /// [`arrow::datatypes::DataType::Binary`].
426 ///
427 /// # Returns
428 /// A new [`ArrowOptions`] with the updated setting.
429 ///
430 /// # Examples
431 /// ```rust,ignore
432 /// use clickhouse_arrow::prelude::*;
433 ///
434 /// let arrow_options = ArrowOptions::new()
435 /// .with_strings_as_strings(true);
436 /// println!("Strings as strings: {}", arrow_options.strings_as_strings); // true
437 /// ```
438 #[must_use]
439 pub fn with_strings_as_strings(mut self, enabled: bool) -> Self {
440 self.strings_as_strings = enabled;
441 self
442 }
443
444 /// Sets whether Arrow `Date32` is mapped to `ClickHouse` `Date` or `Date32`.
445 ///
446 /// By default, Arrow `Date32` maps to `ClickHouse` `Date` (days since 1970-01-01).
447 /// When this option is enabled (`true`), it maps to `ClickHouse` `Date32` (days
448 /// since 1900-01-01). Use this to control date serialization/deserialization
449 /// behavior.
450 ///
451 /// # Parameters
452 /// - `enabled`: If `true`, maps `Date32` to `ClickHouse` `Date32`; if `false`, maps to `Date`.
453 ///
454 /// # Returns
455 /// A new [`ArrowOptions`] with the updated setting.
456 ///
457 /// # Examples
458 /// ```rust,ignore
459 /// use clickhouse_arrow::prelude::*;
460 ///
461 /// let arrow_options = ArrowOptions::new()
462 /// .with_use_date32_for_date(true);
463 /// println!("Use Date32 for Date: {}", arrow_options.use_date32_for_date); // true
464 /// ```
465 #[must_use]
466 pub fn with_use_date32_for_date(mut self, enabled: bool) -> Self {
467 self.use_date32_for_date = enabled;
468 self
469 }
470
471 /// Sets whether type mappings are strict during serialization and schema creation.
472 ///
473 /// By default, type mappings are relaxed, allowing `ClickHouse` invariant violations
474 /// (e.g., `Nullable(LowCardinality(String))`) to be corrected automatically (e.g.,
475 /// mapping to `LowCardinality(Nullable(String))`). When this option is enabled
476 /// (`true`), non-array violations cause errors during serialization (inserts) and
477 /// schema creation. Array violations are controlled by
478 /// [`ArrowOptions::with_nullable_array_default_empty`]. Schema creation defaults to
479 /// strict mode unless [`ArrowOptions::with_disable_strict_schema_ddl`] is enabled.
480 ///
481 /// # Parameters
482 /// - `enabled`: If `true`, enforces strict type mappings for non-array types; if `false`,
483 /// allows relaxed corrections.
484 ///
485 /// # Returns
486 /// A new [`ArrowOptions`] with the updated setting.
487 ///
488 /// # Examples
489 /// ```rust,ignore
490 /// use clickhouse_arrow::arrow::ArrowOptions;
491 ///
492 /// let arrow_options = ArrowOptions::new()
493 /// .with_strict_schema(true);
494 /// println!("Strict schema: {}", arrow_options.strict_schema); // true
495 /// ```
496 #[must_use]
497 pub fn with_strict_schema(mut self, enabled: bool) -> Self {
498 self.strict_schema = enabled;
499 self
500 }
501
502 /// Sets whether strict mode is disabled during schema creation.
503 ///
504 /// By default, schema creation (e.g., DDL operations) uses strict type mappings (via
505 /// [`ArrowOptions::into_strict_ddl`]), enforcing `ClickHouse` invariants and causing
506 /// errors on violations, including `Nullable(Array(...))`. When this option is
507 /// enabled (`true`), strict mode is disabled for schema creation, using the user’s
508 /// `strict_schema` and `nullable_array_default_empty` settings.
509 ///
510 /// # Parameters
511 /// - `enabled`: If `true`, disables strict mode for schema creation; if `false`, enables strict
512 /// mode.
513 ///
514 /// # Returns
515 /// A new [`ArrowOptions`] with the updated setting.
516 ///
517 /// # Examples
518 /// ```rust,ignore
519 /// use clickhouse_arrow::arrow::ArrowOptions;
520 ///
521 /// let arrow_options = ArrowOptions::new()
522 /// .with_disable_strict_schema_ddl(true);
523 /// assert!(arrow_options.disable_strict_schema_ddl);
524 /// ```
525 #[must_use]
526 pub fn with_disable_strict_schema_ddl(mut self, enabled: bool) -> Self {
527 self.disable_strict_schema_ddl = enabled;
528 self
529 }
530
531 /// Sets whether `Nullable(Array(...))` types default to empty arrays during inserts and are
532 /// coerced to non-nullable during DDL.
533 ///
534 /// By default, `Nullable(Array(...))` types are mapped to `Array(...)` with `[]` for
535 /// nulls during serialization (inserts) and schema creation (if
536 /// `disable_strict_schema_ddl = true`). When this option is disabled (`false`),
537 /// `Nullable(Array(...))` causes errors, enforcing non-nullable arrays. Schema
538 /// creation defaults to non-nullable arrays unless
539 /// [`ArrowOptions::with_disable_strict_schema_ddl`] is enabled.
540 ///
541 /// # Parameters
542 /// - `enabled`: If `true`, maps `Nullable(Array(...))` to `Array(...)` with `[]` for nulls; if
543 /// `false`, errors on `Nullable(Array(...))`.
544 ///
545 /// # Returns
546 /// A new [`ArrowOptions`] with the updated setting.
547 ///
548 /// # Examples
549 /// ```rust,ignore
550 /// use clickhouse_arrow::arrow::ArrowOptions;
551 ///
552 /// let arrow_options = ArrowOptions::new()
553 /// .with_nullable_array_default_empty(false);
554 /// assert!(!arrow_options.nullable_array_default_empty);
555 /// ```
556 #[must_use]
557 pub fn with_nullable_array_default_empty(mut self, enabled: bool) -> Self {
558 self.nullable_array_default_empty = enabled;
559 self
560 }
561
562 /// Sets an Arrow option by name and value.
563 ///
564 /// This method updates a specific option identified by `name` to the given boolean
565 /// `value`. Currently supported names are:
566 /// - `"strings_as_strings"`: Maps `ClickHouse` `String` to Arrow `Utf8`.
567 /// - `"use_date32_for_date"`: Maps Arrow `Date32` to `ClickHouse` `Date32`.
568 /// - `"strict_schema"`: Enforces strict type mappings for non-array types.
569 /// - `"disable_strict_schema_ddl"`: Disables strict mode for schema creation.
570 /// - `"nullable_array_default_empty"`: Maps `Nullable(Array(...))` to `Array(...)` with `[]`
571 /// for nulls.
572 ///
573 /// If an unrecognized name is provided, a warning is logged, and the options are
574 /// returned unchanged. Use this for dynamic configuration or when options are
575 /// specified as key-value pairs.
576 ///
577 /// # Parameters
578 /// - `name`: The name of the option to set.
579 /// - `value`: The boolean value to set for the option.
580 ///
581 /// # Returns
582 /// A new [`ArrowOptions`] with the updated setting.
583 ///
584 /// # Examples
585 /// ```rust,ignore
586 /// use clickhouse_arrow::arrow::ArrowOptions;
587 ///
588 /// let arrow_options = ArrowOptions::new()
589 /// .with_setting("strings_as_strings", true)
590 /// .with_setting("nullable_array_default_empty", false);
591 /// assert!(arrow_options.strings_as_strings);
592 /// assert!(!arrow_options.nullable_array_default_empty);
593 /// ```
594 #[must_use]
595 pub fn with_setting(self, name: &str, value: bool) -> Self {
596 match name {
597 "strings_as_strings" => self.with_strings_as_strings(value),
598 "use_date32_for_date" => self.with_use_date32_for_date(value),
599 "strict_schema" => self.with_strict_schema(value),
600 "disable_strict_schema_ddl" => self.with_disable_strict_schema_ddl(value),
601 "nullable_array_default_empty" => self.with_nullable_array_default_empty(value),
602 k => {
603 warn!("Unrecognized option for ArrowOptions: {k}");
604 self
605 }
606 }
607 }
608}
609
610impl<'a, S, I> From<I> for ArrowOptions
611where
612 S: AsRef<str> + 'a,
613 I: Iterator<Item = &'a (S, bool)> + 'a,
614{
615 /// Creates an `ArrowOptions` instance from an iterator of key-value pairs.
616 ///
617 /// This method constructs an [`ArrowOptions`] by applying settings from an iterator
618 /// of `(key, value)` pairs, where `key` is a string (e.g., `"strict_schema"`) and
619 /// `value` is a boolean. It uses [`ArrowOptions::with_setting`] to apply each
620 /// setting. Unrecognized keys trigger a warning but do not cause an error.
621 ///
622 /// See currently supported keys by inspecting [`ArrowOptions::with_setting`].
623 ///
624 /// # Parameters
625 /// - `value`: An iterator of `(key, value)` pairs, where `key` is a string-like type and
626 /// `value` is a boolean.
627 ///
628 /// # Returns
629 /// An [`ArrowOptions`] instance with the applied settings.
630 ///
631 /// # Examples
632 /// ```rust,ignore
633 /// use clickhouse_arrow::arrow::ArrowOptions;
634 ///
635 /// let settings = vec![("strings_as_strings", true), ("nullable_array_default_empty", false)];
636 /// let arrow_options: ArrowOptions = settings.iter().collect();
637 /// assert!(arrow_options.strings_as_strings);
638 /// assert!(!arrow_options.nullable_array_default_empty);
639 /// ```
640 fn from(value: I) -> Self {
641 let mut options = ArrowOptions::default();
642 for (k, v) in value {
643 options = options.with_setting(k.as_ref(), *v);
644 }
645 options
646 }
647}
648
649impl<'a> FromIterator<(&'a str, bool)> for ArrowOptions {
650 /// Creates an `ArrowOptions` instance from an iterator of string-boolean pairs.
651 ///
652 /// This method constructs an [`ArrowOptions`] by applying settings from an iterator
653 /// of `(key, value)` pairs, where `key` is a string slice (e.g., `"strict_schema"`)
654 /// and `value` is a boolean. It uses [`ArrowOptions::with_setting`] to apply each
655 /// setting. Unrecognized keys trigger a warning but do not cause an error.
656 ///
657 /// See currently supported keys by inspecting [`ArrowOptions::with_setting`].
658 ///
659 /// # Parameters
660 /// - `iter`: An iterator of `(key, value)` pairs, where `key` is a string slice and `value` is
661 /// a boolean.
662 ///
663 /// # Returns
664 /// An [`ArrowOptions`] instance with the applied settings.
665 ///
666 /// # Examples
667 /// ```rust,ignore
668 /// use clickhouse_arrow::arrow::ArrowOptions;
669 ///
670 /// let settings = vec![("strings_as_strings", true), ("nullable_array_default_empty", false)];
671 /// let arrow_options = ArrowOptions::from_iter(settings);
672 /// assert!(arrow_options.strings_as_strings);
673 /// assert!(!arrow_options.nullable_array_default_empty);
674 /// ```
675 fn from_iter<I: IntoIterator<Item = (&'a str, bool)>>(iter: I) -> Self {
676 let mut options = ArrowOptions::default();
677 for (k, v) in iter {
678 options = options.with_setting(k, v);
679 }
680 options
681 }
682}
683
684/// Configuration options for connecting to `ClickHouse` cloud instances.
685///
686/// The `CloudOptions` struct defines settings specific to `ClickHouse` cloud
687/// deployments, used within [`ClientOptions`]. These options control the behavior
688/// of cloud wakeup pings to ensure the instance is active before connecting.
689///
690/// # Fields
691/// - `timeout`: Optional timeout (in seconds) for the cloud wakeup ping; if `None`, uses a default
692/// timeout.
693/// - `wakeup`: If `true`, sends a wakeup ping before connecting; if `false`, skips the ping.
694///
695/// # Feature
696/// Requires the `cloud` feature to be enabled.
697///
698/// # Examples
699/// ```rust,ignore
700/// use clickhouse_arrow::prelude::*;
701///
702/// let cloud_options = CloudOptions {
703/// timeout: Some(10),
704/// wakeup: true,
705/// };
706/// let options = ClientOptions {
707/// cloud: cloud_options,
708/// ..ClientOptions::default()
709/// };
710/// ```
711#[derive(Debug, Clone, Copy, Default, PartialEq)]
712#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
713pub struct CloudOptions {
714 #[cfg_attr(feature = "serde", serde(default))]
715 pub timeout: Option<u64>,
716 #[cfg_attr(feature = "serde", serde(default))]
717 pub wakeup: bool,
718}