databend_client/
response.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::error_code::ErrorCode;
16use crate::session::SessionState;
17use serde::{Deserialize, Serialize};
18use std::collections::BTreeMap;
19
20#[derive(Deserialize, Debug, Default)]
21pub struct QueryStats {
22    #[serde(flatten)]
23    pub progresses: Progresses,
24    pub running_time_ms: f64,
25}
26
27#[derive(Deserialize, Debug, Default)]
28pub struct Progresses {
29    pub scan_progress: ProgressValues,
30    pub write_progress: ProgressValues,
31    pub result_progress: ProgressValues,
32    // make it optional for backward compatibility
33    pub total_scan: Option<ProgressValues>,
34    #[serde(default)]
35    pub spill_progress: SpillProgress,
36}
37
38impl Progresses {
39    pub fn has_progress(&self) -> bool {
40        self.scan_progress.bytes > 0
41            || self.scan_progress.rows > 0
42            || self.write_progress.bytes > 0
43            || self.write_progress.rows > 0
44            || self.result_progress.bytes > 0
45            || self.result_progress.rows > 0
46            || self
47                .total_scan
48                .as_ref()
49                .is_some_and(|v| v.bytes > 0 || v.rows > 0)
50    }
51}
52
53#[derive(Debug, Deserialize, Default)]
54pub struct ProgressValues {
55    pub rows: usize,
56    pub bytes: usize,
57}
58
59#[derive(Debug, Clone, Deserialize, Serialize, Default)]
60pub struct SpillProgress {
61    pub file_nums: usize,
62    pub bytes: usize,
63}
64
65#[derive(Serialize, Deserialize, Debug, Clone)]
66pub struct SchemaField {
67    pub name: String,
68    #[serde(rename = "type")]
69    pub data_type: String,
70}
71
72#[derive(Deserialize, Debug)]
73pub struct QueryResponse {
74    pub id: String,
75    pub node_id: Option<String>,
76    pub session_id: Option<String>,
77    pub session: Option<SessionState>,
78    pub schema: Vec<SchemaField>,
79    pub data: Vec<Vec<Option<String>>>,
80    pub state: String,
81    pub settings: Option<BTreeMap<String, String>>,
82    pub error: Option<ErrorCode>,
83    // make it optional for backward compatibility
84    pub warnings: Option<Vec<String>>,
85    pub stats: QueryStats,
86    pub result_timeout_secs: Option<u64>,
87    // pub affect: Option<QueryAffect>,
88    pub stats_uri: Option<String>,
89    pub final_uri: Option<String>,
90    pub next_uri: Option<String>,
91    pub kill_uri: Option<String>,
92}
93
94#[derive(Deserialize, Debug)]
95pub struct LoadResponse {
96    pub id: String,
97    pub stats: ProgressValues,
98}
99
100#[cfg(test)]
101mod test {
102    use std::collections::BTreeMap;
103
104    use super::*;
105
106    #[test]
107    fn deserialize_session_config() {
108        let session_json = r#"{"database":"default","settings":{}}"#;
109        let session_config: SessionState = serde_json::from_str(session_json).unwrap();
110        assert_eq!(session_config.database, Some("default".to_string()));
111        assert_eq!(session_config.settings, Some(BTreeMap::default()));
112        assert_eq!(session_config.role, None);
113        assert_eq!(session_config.secondary_roles, None);
114
115        let session_json = r#"{"database":"default","settings":{},"role": "role1", "secondary_roles": [], "unknown_field": 1}"#;
116        let session_config: SessionState = serde_json::from_str(session_json).unwrap();
117        assert_eq!(session_config.database, Some("default".to_string()));
118        assert_eq!(session_config.settings, Some(BTreeMap::default()));
119        assert_eq!(session_config.role, Some("role1".to_string()));
120        assert_eq!(session_config.secondary_roles, Some(vec![]));
121    }
122}