Skip to main content

edgebase_admin/
edgebase.rs

1use edgebase_core::http_client::HttpClient;
2use edgebase_core::table::TableRef;
3use edgebase_core::storage::StorageClient;
4use edgebase_core::Error;
5use crate::generated::admin_api_core::GeneratedAdminApi;
6use crate::admin_auth::AdminAuthClient;
7use crate::analytics::AnalyticsClient;
8use crate::kv::KvClient;
9use crate::d1::D1Client;
10use crate::functions::FunctionsClient;
11use crate::vectorize::VectorizeClient;
12use crate::push::PushClient;
13use serde::Serialize;
14use serde_json::Value;
15use std::sync::Arc;
16
17/// DB namespace block reference for table access (#133 §2).
18pub struct DbRef {
19    http: Arc<HttpClient>,
20    ns: String,
21    instance_id: Option<String>,
22}
23
24impl DbRef {
25    /// Get a [TableRef] for the named table.
26    pub fn table(&self, name: &str) -> TableRef {
27        TableRef::with_db(Arc::clone(&self.http), name, &self.ns, self.instance_id.as_deref())
28    }
29}
30
31
32/// Server-side EdgeBase client — requires Service Key.
33pub struct EdgeBase {
34    http: Arc<HttpClient>,
35}
36
37impl EdgeBase {
38    /// Create a server-side SDK instance.
39    pub fn server(base_url: &str, service_key: &str) -> Result<Self, Error> {
40        let http = HttpClient::new(base_url, service_key)?;
41        Ok(Self { http: Arc::new(http) })
42    }
43
44    /// Admin Auth operations (create/get/list/delete users).
45    pub fn admin_auth(&self) -> AdminAuthClient {
46        AdminAuthClient::new(Arc::clone(&self.http))
47    }
48
49    /// Select a DB block by namespace and optional instance ID (#133 §2).
50    pub fn db(&self, ns: &str, instance_id: Option<&str>) -> DbRef {
51        DbRef {
52            http: Arc::clone(&self.http),
53            ns: ns.to_string(),
54            instance_id: instance_id.map(|s| s.to_string()),
55        }
56    }
57
58    /// Storage operations.
59    pub fn storage(&self) -> StorageClient {
60        StorageClient::new(Arc::clone(&self.http))
61    }
62
63    /// Access a user-defined KV namespace.
64    pub fn kv(&self, namespace: &str) -> KvClient {
65        KvClient::new(Arc::clone(&self.http), namespace)
66    }
67
68    /// Access a user-defined D1 database.
69    pub fn d1(&self, database: &str) -> D1Client {
70        D1Client::new(Arc::clone(&self.http), database)
71    }
72
73    /// Access a user-defined Vectorize index.
74    pub fn vector(&self, index: &str) -> VectorizeClient {
75        VectorizeClient::new(Arc::clone(&self.http), index)
76    }
77
78    /// Push notification management.
79    pub fn push(&self) -> PushClient {
80        PushClient::new(Arc::clone(&self.http))
81    }
82
83    /// Call app functions with the admin service key.
84    pub fn functions(&self) -> FunctionsClient {
85        FunctionsClient::new(Arc::clone(&self.http))
86    }
87
88    /// Query analytics metrics and track custom events.
89    pub fn analytics(&self) -> AnalyticsClient {
90        AnalyticsClient::new(Arc::clone(&self.http))
91    }
92
93    fn core(&self) -> GeneratedAdminApi<'_> {
94        GeneratedAdminApi::new(&self.http)
95    }
96
97    /// Raw SQL query     /// namespace: DB namespace ('shared' | 'workspace' | ...), id: instance ID for dynamic DOs.
98    pub async fn sql<T: Serialize>(&self, namespace: &str, id: Option<&str>, query: &str, params: &[T]) -> Result<Value, Error> {
99        if query.trim().is_empty() {
100            return Err(Error::Api {
101                status: 400,
102                message: "Invalid sql() signature: query must be a non-empty string".to_string(),
103            });
104        }
105
106        let serialized_params = serde_json::to_value(params)?;
107        let mut body = serde_json::json!({
108            "namespace": namespace,
109            "sql": query,
110            "params": serialized_params,
111        });
112        if let Some(id_val) = id {
113            body["id"] = serde_json::Value::String(id_val.to_string());
114        }
115        self.core().execute_sql(&body).await
116    }
117
118    /// Server-side broadcast to a database-live channel.
119    pub async fn broadcast(&self, channel: &str, event: &str, payload: Value) -> Result<Value, Error> {
120        let body = serde_json::json!({
121            "channel": channel,
122            "event": event,
123            "payload": payload,
124        });
125        self.core().database_live_broadcast(&body).await
126    }
127
128}