@@ -92,18 +92,36 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
9292
9393 // --- 3. Submit a query -----------------------------------------------
9494 //
95+ // Queries, results, and query runs are all scoped to a database via the
96+ // `X-Database-Id` header, so resolve one first. Prefer HOTDATA_DATABASE, else
97+ // fall back to the first database in the workspace; if there are none, skip
98+ // the query portion of the tour.
99+ let database_id = match resolve_database_id ( & client) . await ? {
100+ Some ( id) => id,
101+ None => {
102+ println ! (
103+ "No database available (set HOTDATA_DATABASE or create one). \
104+ Skipping the query portion of the tour."
105+ ) ;
106+ return Ok ( ( ) ) ;
107+ }
108+ } ;
109+ println ! ( "Using database {database_id}" ) ;
110+
95111 // POST /query returns rows inline *and* a result_id; persistence to the
96112 // result store then completes asynchronously.
97113 //
98- // `query` is the enhanced default: it retries HTTP 429 (`OVERLOADED`)
99- // transparently and, if the server truncates a large result, auto-follows it
100- // — paging the full row set into `response.rows` — bounded by the instance
101- // `QueryConfig` (default ceilings: 1M rows / 64 MiB). Exceed a ceiling and you
102- // get `QueryError::Result(ResultError::TooLarge { .. })` instead of an OOM.
114+ // `query_in` is the database-scoped form of the enhanced default `query`: it
115+ // retries HTTP 429 (`OVERLOADED`) transparently and, if the server truncates
116+ // a large result, auto-follows it — paging the full row set into
117+ // `response.rows` — bounded by the instance `QueryConfig` (default ceilings:
118+ // 1M rows / 64 MiB). Exceed a ceiling and you get
119+ // `QueryError::Result(ResultError::TooLarge { .. })` instead of an OOM.
103120 let response = client
104- . query ( QueryRequest :: new (
105- "select 1 as id, 'hello' as greeting" . to_string ( ) ,
106- ) )
121+ . query_in (
122+ QueryRequest :: new ( "select 1 as id, 'hello' as greeting" . to_string ( ) ) ,
123+ & database_id,
124+ )
107125 . await ?;
108126
109127 println ! (
@@ -112,11 +130,15 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
112130 ) ;
113131
114132 // Tuning the auto-follow behavior per call: clone the instance config and
115- // override just what you need. Here we opt out of auto-follow entirely —
116- // `query_preview` is the one-call shortcut for "give me only the inline
117- // preview" (handy when you'll page the full result yourself, e.g. as Arrow).
133+ // override just what you need. Here we opt out of auto-follow entirely, while
134+ // still scoping the query to the database via `query_with`.
135+ let preview_config = client . query_config ( ) . clone ( ) . with_auto_follow ( false ) ;
118136 let preview = client
119- . query_preview ( QueryRequest :: new ( "select 1 as id" . to_string ( ) ) )
137+ . query_with (
138+ QueryRequest :: new ( "select 1 as id" . to_string ( ) ) ,
139+ Some ( & database_id) ,
140+ & preview_config,
141+ )
120142 . await ?;
121143 println ! (
122144 "Preview: {} row(s){}" ,
@@ -151,24 +173,44 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
151173 // timeout polled every second.
152174 println ! ( "Awaiting result {result_id}..." ) ;
153175 let ready = client
154- . await_result ( & result_id, PollConfig :: default ( ) )
176+ . await_result ( & result_id, & database_id , PollConfig :: default ( ) )
155177 . await ?;
156178 println ! ( "Result status: {}" , ready. status) ;
157179
158180 // --- 5. Fetch the result as Arrow (feature-gated) --------------------
159- fetch_arrow ( & client, & result_id) . await ?;
181+ fetch_arrow ( & client, & database_id , & result_id) . await ?;
160182
161183 // --- 6. One-call query -> Arrow (feature-gated) ----------------------
162- one_shot_arrow ( & client) . await ?;
184+ one_shot_arrow ( & client, & database_id ) . await ?;
163185
164186 Ok ( ( ) )
165187}
166188
189+ /// Resolve a database to scope the query tour to: `HOTDATA_DATABASE` if set,
190+ /// otherwise the first database visible in the workspace (`None` if there are
191+ /// none).
192+ async fn resolve_database_id ( client : & Client ) -> Result < Option < String > , Box < dyn std:: error:: Error > > {
193+ if let Ok ( id) = std:: env:: var ( "HOTDATA_DATABASE" ) {
194+ if !id. is_empty ( ) {
195+ return Ok ( Some ( id) ) ;
196+ }
197+ }
198+ let databases = client. databases ( ) . list ( ) . await ?;
199+ Ok ( databases. databases . into_iter ( ) . next ( ) . map ( |db| db. id ) )
200+ }
201+
167202/// Fetch an already-ready result as Arrow record batches.
168203#[ cfg( feature = "arrow" ) ]
169- async fn fetch_arrow ( client : & Client , result_id : & str ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
204+ async fn fetch_arrow (
205+ client : & Client ,
206+ database_id : & str ,
207+ result_id : & str ,
208+ ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
170209 println ! ( "Fetching result {result_id} as Arrow..." ) ;
171- match client. get_result_arrow ( result_id, None , None ) . await {
210+ match client
211+ . get_result_arrow ( result_id, database_id, None , None )
212+ . await
213+ {
172214 Ok ( arrow) => print_arrow ( & arrow) ,
173215 // The Arrow error enum maps the result endpoint's status codes to named
174216 // variants, so callers react without string-matching on HTTP codes.
@@ -183,7 +225,10 @@ async fn fetch_arrow(client: &Client, result_id: &str) -> Result<(), Box<dyn std
183225/// Submit a fresh query and get its result as Arrow in a single call —
184226/// `query_to_arrow` runs the query, awaits `ready`, and decodes the stream.
185227#[ cfg( feature = "arrow" ) ]
186- async fn one_shot_arrow ( client : & Client ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
228+ async fn one_shot_arrow (
229+ client : & Client ,
230+ database_id : & str ,
231+ ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
187232 use std:: time:: Duration ;
188233
189234 println ! ( "One-call query_to_arrow..." ) ;
@@ -194,6 +239,7 @@ async fn one_shot_arrow(client: &Client) -> Result<(), Box<dyn std::error::Error
194239 let arrow = client
195240 . query_to_arrow (
196241 QueryRequest :: new ( "select 42 as answer" . to_string ( ) ) ,
242+ database_id,
197243 poll,
198244 None ,
199245 None ,
0 commit comments