dune_api/tables/
types.rs

1//! Types for the Tables (uploads) API
2
3use serde::{Deserialize, Serialize};
4
5/// Table column definition
6#[derive(Debug, Clone, Deserialize, Serialize)]
7pub struct TableColumn {
8    /// Column name
9    pub name: String,
10    /// Column type (varchar, integer, double, boolean, timestamp, etc.)
11    #[serde(rename = "type")]
12    pub column_type: String,
13    /// Whether the column is nullable
14    #[serde(default)]
15    pub nullable: bool,
16}
17
18impl TableColumn {
19    /// Create a new column definition
20    pub fn new(name: &str, column_type: &str) -> Self {
21        Self {
22            name: name.to_string(),
23            column_type: column_type.to_string(),
24            nullable: true,
25        }
26    }
27
28    /// Create a non-nullable column
29    pub fn not_null(mut self) -> Self {
30        self.nullable = false;
31        self
32    }
33}
34
35/// Table column info (from list response)
36#[derive(Debug, Clone, Deserialize, Serialize)]
37pub struct TableColumnInfo {
38    /// Column name
39    pub name: Option<String>,
40    /// Column type
41    #[serde(rename = "type")]
42    pub column_type: Option<String>,
43}
44
45/// Table owner info
46#[derive(Debug, Clone, Deserialize, Serialize)]
47pub struct TableOwner {
48    /// Owner handle
49    pub handle: Option<String>,
50    /// Owner type (user, team)
51    #[serde(rename = "type")]
52    pub owner_type: Option<String>,
53}
54
55/// Table list element
56#[derive(Debug, Clone, Deserialize, Serialize)]
57pub struct Table {
58    /// Full table name (catalog.schema.table)
59    pub full_name: Option<String>,
60    /// Table columns
61    #[serde(default)]
62    pub columns: Vec<TableColumnInfo>,
63    /// Whether the table is private
64    pub is_private: Option<bool>,
65    /// Owner information
66    pub owner: Option<TableOwner>,
67    /// Table size in bytes
68    pub table_size_bytes: Option<String>,
69    /// Creation timestamp
70    pub created_at: Option<String>,
71    /// Last update timestamp
72    pub updated_at: Option<String>,
73    /// Purge timestamp
74    pub purged_at: Option<String>,
75}
76
77/// Request to create a table
78#[derive(Debug, Clone, Serialize)]
79pub struct CreateTableRequest {
80    /// Namespace (your username or team handle)
81    pub namespace: String,
82    /// Table name
83    pub table_name: String,
84    /// Table schema (columns)
85    pub schema: Vec<TableColumn>,
86    /// Table description
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub description: Option<String>,
89    /// Whether the table is private
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub is_private: Option<bool>,
92}
93
94impl CreateTableRequest {
95    /// Create a new table request
96    pub fn new(namespace: &str, table_name: &str, schema: Vec<TableColumn>) -> Self {
97        Self {
98            namespace: namespace.to_string(),
99            table_name: table_name.to_string(),
100            schema,
101            description: None,
102            is_private: None,
103        }
104    }
105
106    /// Set the description
107    pub fn description(mut self, description: &str) -> Self {
108        self.description = Some(description.to_string());
109        self
110    }
111
112    /// Set as private
113    pub fn private(mut self, is_private: bool) -> Self {
114        self.is_private = Some(is_private);
115        self
116    }
117}
118
119/// Response from creating a table
120#[derive(Debug, Clone, Deserialize, Serialize)]
121pub struct CreateTableResponse {
122    /// Full table name
123    pub full_name: Option<String>,
124    /// Namespace
125    pub namespace: Option<String>,
126    /// Table name
127    pub table_name: Option<String>,
128    /// Whether table already existed
129    pub already_existed: Option<bool>,
130    /// Example query to use the table
131    pub example_query: Option<String>,
132    /// Message
133    pub message: Option<String>,
134}
135
136/// Request to upload CSV data
137#[derive(Debug, Clone, Serialize)]
138pub struct UploadCsvRequest {
139    /// Table name
140    pub table_name: String,
141    /// CSV data
142    pub data: String,
143    /// Description
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub description: Option<String>,
146    /// Whether the table is private
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub is_private: Option<bool>,
149}
150
151impl UploadCsvRequest {
152    /// Create a new CSV upload request
153    pub fn new(table_name: &str, csv_data: &str) -> Self {
154        Self {
155            table_name: table_name.to_string(),
156            data: csv_data.to_string(),
157            description: None,
158            is_private: None,
159        }
160    }
161}
162
163/// Response from CSV upload
164#[derive(Debug, Clone, Deserialize, Serialize)]
165pub struct UploadCsvResponse {
166    /// Whether upload was successful
167    pub success: Option<bool>,
168    /// Table name
169    pub table_name: Option<String>,
170}
171
172/// Response from inserting data
173#[derive(Debug, Clone, Deserialize, Serialize)]
174pub struct InsertResponse {
175    /// Table name
176    pub name: Option<String>,
177    /// Number of rows written
178    pub rows_written: Option<i64>,
179    /// Number of bytes written
180    pub bytes_written: Option<i64>,
181}
182
183/// Response from clearing a table
184#[derive(Debug, Clone, Deserialize, Serialize)]
185pub struct ClearTableResponse {
186    /// Success message
187    pub message: Option<String>,
188}
189
190/// Response from deleting a table
191#[derive(Debug, Clone, Deserialize, Serialize)]
192pub struct DeleteTableResponse {
193    /// Success message
194    pub message: Option<String>,
195}
196
197/// Response from listing tables
198#[derive(Debug, Clone, Deserialize, Serialize)]
199pub struct ListTablesResponse {
200    /// List of tables
201    #[serde(default)]
202    pub tables: Vec<Table>,
203    /// Next page offset
204    pub next_offset: Option<i64>,
205}
206
207/// Options for listing tables
208#[derive(Debug, Clone, Default)]
209pub struct ListTablesOptions {
210    /// Maximum number of results
211    pub limit: Option<u32>,
212    /// Pagination offset
213    pub offset: Option<i64>,
214}
215
216impl ListTablesOptions {
217    pub fn to_query_string(&self) -> String {
218        let mut params = Vec::new();
219        if let Some(limit) = self.limit {
220            params.push(format!("limit={}", limit));
221        }
222        if let Some(offset) = self.offset {
223            params.push(format!("offset={}", offset));
224        }
225        if params.is_empty() {
226            String::new()
227        } else {
228            format!("?{}", params.join("&"))
229        }
230    }
231}