dune_api/tables/
api.rs

1//! Tables API implementation
2
3use super::types::*;
4use crate::client::Client;
5use crate::error::{self, Error, Result};
6
7/// Tables (uploads) API
8pub struct TablesApi<'a> {
9    client: &'a Client,
10}
11
12impl<'a> TablesApi<'a> {
13    pub(crate) fn new(client: &'a Client) -> Self {
14        Self { client }
15    }
16
17    /// Create a new table
18    pub async fn create(&self, request: &CreateTableRequest) -> Result<CreateTableResponse> {
19        let url = format!("{}/v1/datasets", self.client.base_url());
20        let response = self.client.http().post(&url).json(request).send().await?;
21
22        if response.status().is_success() {
23            Ok(response.json().await?)
24        } else {
25            let status = response.status().as_u16();
26            let message = response.text().await.unwrap_or_default();
27            Err(Error::api(status, message))
28        }
29    }
30
31    /// Upload CSV data to create or update a table
32    pub async fn upload_csv(&self, request: &UploadCsvRequest) -> Result<UploadCsvResponse> {
33        let url = format!("{}/v1/uploads/csv", self.client.base_url());
34        let response = self.client.http().post(&url).json(request).send().await?;
35
36        if response.status().is_success() {
37            Ok(response.json().await?)
38        } else {
39            let status = response.status().as_u16();
40            let message = response.text().await.unwrap_or_default();
41            Err(Error::api(status, message))
42        }
43    }
44
45    /// List all tables
46    pub async fn list(&self) -> Result<ListTablesResponse> {
47        self.list_with_options(&ListTablesOptions::default()).await
48    }
49
50    /// List tables with options
51    pub async fn list_with_options(
52        &self,
53        options: &ListTablesOptions,
54    ) -> Result<ListTablesResponse> {
55        let url = format!(
56            "{}/v1/uploads{}",
57            self.client.base_url(),
58            options.to_query_string()
59        );
60        let response = self.client.http().get(&url).send().await?;
61
62        if response.status().is_success() {
63            Ok(response.json().await?)
64        } else {
65            let status = response.status().as_u16();
66            let message = response.text().await.unwrap_or_default();
67            Err(Error::api(status, message))
68        }
69    }
70
71    /// Get a specific table
72    pub async fn get(&self, namespace: &str, table_name: &str) -> Result<Table> {
73        let url = format!(
74            "{}/v1/datasets/{}/{}",
75            self.client.base_url(),
76            namespace,
77            table_name
78        );
79        let response = self.client.http().get(&url).send().await?;
80
81        if response.status().is_success() {
82            Ok(response.json().await?)
83        } else if response.status() == 404 {
84            Err(error::not_found(format!(
85                "Table {}/{}",
86                namespace, table_name
87            )))
88        } else {
89            let status = response.status().as_u16();
90            let message = response.text().await.unwrap_or_default();
91            Err(Error::api(status, message))
92        }
93    }
94
95    /// Insert rows into a table
96    ///
97    /// Data should be a JSON array of objects, where each object represents a row.
98    pub async fn insert(
99        &self,
100        namespace: &str,
101        table_name: &str,
102        data: &serde_json::Value,
103    ) -> Result<InsertResponse> {
104        let url = format!(
105            "{}/v1/uploads/{}/{}/insert",
106            self.client.base_url(),
107            namespace,
108            table_name
109        );
110        let response = self.client.http().post(&url).json(data).send().await?;
111
112        if response.status().is_success() {
113            Ok(response.json().await?)
114        } else if response.status() == 404 {
115            Err(error::not_found(format!(
116                "Table {}/{}",
117                namespace, table_name
118            )))
119        } else {
120            let status = response.status().as_u16();
121            let message = response.text().await.unwrap_or_default();
122            Err(Error::api(status, message))
123        }
124    }
125
126    /// Clear all data from a table
127    pub async fn clear(&self, namespace: &str, table_name: &str) -> Result<ClearTableResponse> {
128        let url = format!(
129            "{}/v1/uploads/{}/{}/clear",
130            self.client.base_url(),
131            namespace,
132            table_name
133        );
134        let response = self.client.http().post(&url).send().await?;
135
136        if response.status().is_success() {
137            Ok(response.json().await?)
138        } else if response.status() == 404 {
139            Err(error::not_found(format!(
140                "Table {}/{}",
141                namespace, table_name
142            )))
143        } else {
144            let status = response.status().as_u16();
145            let message = response.text().await.unwrap_or_default();
146            Err(Error::api(status, message))
147        }
148    }
149
150    /// Delete a table
151    pub async fn delete(&self, namespace: &str, table_name: &str) -> Result<DeleteTableResponse> {
152        let url = format!(
153            "{}/v1/uploads/{}/{}",
154            self.client.base_url(),
155            namespace,
156            table_name
157        );
158        let response = self.client.http().delete(&url).send().await?;
159
160        if response.status().is_success() {
161            Ok(response.json().await?)
162        } else if response.status() == 404 {
163            Err(error::not_found(format!(
164                "Table {}/{}",
165                namespace, table_name
166            )))
167        } else {
168            let status = response.status().as_u16();
169            let message = response.text().await.unwrap_or_default();
170            Err(Error::api(status, message))
171        }
172    }
173}