arrow_flight/sql/metadata/
catalogs.rs1use std::sync::Arc;
19
20use arrow_array::{RecordBatch, StringArray};
21use arrow_schema::{DataType, Field, Schema, SchemaRef};
22use once_cell::sync::Lazy;
23
24use crate::error::Result;
25use crate::sql::CommandGetCatalogs;
26
27pub struct GetCatalogsBuilder {
33    catalogs: Vec<String>,
34}
35
36impl CommandGetCatalogs {
37    pub fn into_builder(self) -> GetCatalogsBuilder {
39        self.into()
40    }
41}
42
43impl From<CommandGetCatalogs> for GetCatalogsBuilder {
44    fn from(_: CommandGetCatalogs) -> Self {
45        Self::new()
46    }
47}
48
49impl Default for GetCatalogsBuilder {
50    fn default() -> Self {
51        Self::new()
52    }
53}
54
55impl GetCatalogsBuilder {
56    pub fn new() -> Self {
58        Self {
59            catalogs: Vec::new(),
60        }
61    }
62
63    pub fn append(&mut self, catalog_name: impl Into<String>) {
65        self.catalogs.push(catalog_name.into());
66    }
67
68    pub fn build(self) -> Result<RecordBatch> {
71        let Self { mut catalogs } = self;
72        catalogs.sort_unstable();
73
74        let batch = RecordBatch::try_new(
75            Arc::clone(&GET_CATALOG_SCHEMA),
76            vec![Arc::new(StringArray::from_iter_values(catalogs)) as _],
77        )?;
78
79        Ok(batch)
80    }
81
82    pub fn schema(&self) -> SchemaRef {
86        get_catalogs_schema()
87    }
88}
89
90fn get_catalogs_schema() -> SchemaRef {
91    Arc::clone(&GET_CATALOG_SCHEMA)
92}
93
94static GET_CATALOG_SCHEMA: Lazy<SchemaRef> = Lazy::new(|| {
96    Arc::new(Schema::new(vec![Field::new(
97        "catalog_name",
98        DataType::Utf8,
99        false,
100    )]))
101});
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106
107    #[test]
108    fn test_catalogs_are_sorted() {
109        let batch = ["a_catalog", "c_catalog", "b_catalog"]
110            .into_iter()
111            .fold(GetCatalogsBuilder::new(), |mut builder, catalog| {
112                builder.append(catalog);
113                builder
114            })
115            .build()
116            .unwrap();
117        let catalogs = batch
118            .column(0)
119            .as_any()
120            .downcast_ref::<StringArray>()
121            .unwrap()
122            .iter()
123            .flatten()
124            .collect::<Vec<_>>();
125        assert!(catalogs.is_sorted());
126        assert_eq!(catalogs, ["a_catalog", "b_catalog", "c_catalog"]);
127    }
128}