clickhouse_client/schema/
query.rs

1//! DDL queries
2
3use crate::{error::Error, intf::Interface, query::Query, Client};
4
5use super::TableSchema;
6
7/// DDL query
8pub struct DdlQuery<'a, T>
9where
10    T: Interface,
11{
12    /// Client
13    client: &'a Client<T>,
14    /// Query
15    query: Query,
16}
17
18impl<T> Client<T>
19where
20    T: Interface,
21{
22    /// Prepares a DDL query
23    pub fn ddl(&self) -> DdlQuery<T> {
24        DdlQuery {
25            client: self,
26            query: Query {
27                db: self.db.clone(),
28                credentials: self.credentials.clone(),
29                ..Default::default()
30            },
31        }
32    }
33}
34
35impl<'a, T> DdlQuery<'a, T>
36where
37    T: Interface,
38{
39    /// Creates a DB
40    #[tracing::instrument(skip(self))]
41    pub async fn create_db(self, db: &str) -> Result<(), Error> {
42        let mut query = self
43            .query
44            .statement("CREATE DATABASE IF NOT EXISTS [??]")
45            .bind_str(db);
46        query.db = None;
47        self.client.send(query).await?;
48        Ok(())
49    }
50
51    /// Drops a DB
52    #[tracing::instrument(skip(self))]
53    pub async fn drop_db(self, db: &str) -> Result<(), Error> {
54        let mut query = self
55            .query
56            .statement("DROP DATABASE IF NOT EXISTS [??]")
57            .bind_str(db);
58        query.db = None;
59        self.client.send(query).await?;
60        Ok(())
61    }
62
63    /// Creates a table
64    #[tracing::instrument(skip(self))]
65    pub async fn create_table(self, schema: &TableSchema, engine: &str) -> Result<(), Error> {
66        let columns = schema
67            .columns
68            .iter()
69            .map(|col| format!("{} {}", col.id, col.ty))
70            .collect::<Vec<_>>();
71
72        let primary_keys = schema
73            .columns
74            .iter()
75            .filter_map(|col| {
76                if col.primary {
77                    Some(col.id.clone())
78                } else {
79                    None
80                }
81            })
82            .collect::<Vec<_>>();
83
84        let query = self
85            .query
86            .statement("CREATE TABLE IF NOT EXISTS [??] ([??]) ENGINE = [??] PRIMARY KEY ([??])")
87            .bind_str(&schema.name)
88            .bind_str(&columns.join(", "))
89            .bind_str(engine)
90            .bind_str(&primary_keys.join(", "));
91        self.client.send(query).await?;
92        Ok(())
93    }
94
95    /// Drops a table
96    #[tracing::instrument(skip(self))]
97    pub async fn drop_table(self, table: &str) -> Result<(), Error> {
98        let query = self
99            .query
100            .statement("DROP TABLE IF EXISTS [??]")
101            .bind_str(table);
102        self.client.send(query).await?;
103        Ok(())
104    }
105}