@@ -220,7 +220,76 @@ fn upload_from_stdin(
220220 ( id, ft. format )
221221}
222222
223- pub fn create (
223+ fn create_dataset (
224+ workspace_id : & str ,
225+ label : & str ,
226+ table_name : Option < & str > ,
227+ source : serde_json:: Value ,
228+ on_failure : Option < Box < dyn FnOnce ( ) > > ,
229+ ) {
230+ let profile_config = match config:: load ( "default" ) {
231+ Ok ( c) => c,
232+ Err ( e) => {
233+ eprintln ! ( "{e}" ) ;
234+ std:: process:: exit ( 1 ) ;
235+ }
236+ } ;
237+
238+ let api_key = match & profile_config. api_key {
239+ Some ( key) if key != "PLACEHOLDER" => key. clone ( ) ,
240+ _ => {
241+ eprintln ! ( "error: not authenticated. Run 'hotdata auth login' to log in." ) ;
242+ std:: process:: exit ( 1 ) ;
243+ }
244+ } ;
245+
246+ let mut body = json ! ( { "label" : label, "source" : source } ) ;
247+ if let Some ( tn) = table_name {
248+ body[ "table_name" ] = json ! ( tn) ;
249+ }
250+
251+ let url = format ! ( "{}/datasets" , profile_config. api_url) ;
252+ let client = reqwest:: blocking:: Client :: new ( ) ;
253+
254+ let resp = match client
255+ . post ( & url)
256+ . header ( "Authorization" , format ! ( "Bearer {api_key}" ) )
257+ . header ( "X-Workspace-Id" , workspace_id)
258+ . json ( & body)
259+ . send ( )
260+ {
261+ Ok ( r) => r,
262+ Err ( e) => {
263+ eprintln ! ( "error connecting to API: {e}" ) ;
264+ std:: process:: exit ( 1 ) ;
265+ }
266+ } ;
267+
268+ if !resp. status ( ) . is_success ( ) {
269+ use crossterm:: style:: Stylize ;
270+ eprintln ! ( "{}" , crate :: util:: api_error( resp. text( ) . unwrap_or_default( ) ) . red( ) ) ;
271+ if let Some ( f) = on_failure {
272+ f ( ) ;
273+ }
274+ std:: process:: exit ( 1 ) ;
275+ }
276+
277+ let dataset: CreateResponse = match resp. json ( ) {
278+ Ok ( v) => v,
279+ Err ( e) => {
280+ eprintln ! ( "error parsing response: {e}" ) ;
281+ std:: process:: exit ( 1 ) ;
282+ }
283+ } ;
284+
285+ use crossterm:: style:: Stylize ;
286+ println ! ( "{}" , "Dataset created" . green( ) ) ;
287+ println ! ( "id: {}" , dataset. id) ;
288+ println ! ( "label: {}" , dataset. label) ;
289+ println ! ( "full_name: datasets.main.{}" , dataset. table_name) ;
290+ }
291+
292+ pub fn create_from_upload (
224293 workspace_id : & str ,
225294 label : Option < & str > ,
226295 table_name : Option < & str > ,
@@ -295,56 +364,53 @@ pub fn create(
295364 } ;
296365
297366 let source = json ! ( { "upload_id" : upload_id, "format" : format } ) ;
298- let mut body = json ! ( { "label" : label, "source" : source } ) ;
299- if let Some ( tn) = table_name {
300- body[ "table_name" ] = json ! ( tn) ;
301- }
302-
303- let url = format ! ( "{}/datasets" , profile_config. api_url) ;
304-
305- let resp = match client
306- . post ( & url)
307- . header ( "Authorization" , format ! ( "Bearer {api_key}" ) )
308- . header ( "X-Workspace-Id" , workspace_id)
309- . json ( & body)
310- . send ( )
311- {
312- Ok ( r) => r,
313- Err ( e) => {
314- eprintln ! ( "error connecting to API: {e}" ) ;
315- std:: process:: exit ( 1 ) ;
316- }
317- } ;
318367
319- if !resp. status ( ) . is_success ( ) {
320- use crossterm:: style:: Stylize ;
321- eprintln ! ( "{}" , crate :: util:: api_error( resp. text( ) . unwrap_or_default( ) ) . red( ) ) ;
322- // Only show the resume hint when the upload_id came from a fresh upload
323- if upload_id_was_uploaded {
368+ let on_failure: Option < Box < dyn FnOnce ( ) > > = if upload_id_was_uploaded {
369+ let uid = upload_id. clone ( ) ;
370+ Some ( Box :: new ( move || {
371+ use crossterm:: style:: Stylize ;
324372 eprintln ! (
325373 "{}" ,
326- format!(
327- "Resume dataset creation without re-uploading by passing --upload-id {upload_id}"
328- )
329- . yellow( )
374+ format!( "Resume dataset creation without re-uploading by passing --upload-id {uid}" ) . yellow( )
330375 ) ;
331- }
332- std:: process:: exit ( 1 ) ;
333- }
376+ } ) )
377+ } else {
378+ None
379+ } ;
334380
335- let dataset: CreateResponse = match resp. json ( ) {
336- Ok ( v) => v,
337- Err ( e) => {
338- eprintln ! ( "error parsing response: {e}" ) ;
381+ create_dataset ( workspace_id, label, table_name, source, on_failure) ;
382+ }
383+
384+ pub fn create_from_query (
385+ workspace_id : & str ,
386+ sql : & str ,
387+ label : Option < & str > ,
388+ table_name : Option < & str > ,
389+ ) {
390+ let label = match label {
391+ Some ( l) => l,
392+ None => {
393+ eprintln ! ( "error: --label is required when using --sql" ) ;
339394 std:: process:: exit ( 1 ) ;
340395 }
341396 } ;
397+ create_dataset ( workspace_id, label, table_name, json ! ( { "sql" : sql } ) , None ) ;
398+ }
342399
343- use crossterm:: style:: Stylize ;
344- println ! ( "{}" , "Dataset created" . green( ) ) ;
345- println ! ( "id: {}" , dataset. id) ;
346- println ! ( "label: {}" , dataset. label) ;
347- println ! ( "full_name: datasets.main.{}" , dataset. table_name) ;
400+ pub fn create_from_saved_query (
401+ workspace_id : & str ,
402+ query_id : & str ,
403+ label : Option < & str > ,
404+ table_name : Option < & str > ,
405+ ) {
406+ let label = match label {
407+ Some ( l) => l,
408+ None => {
409+ eprintln ! ( "error: --label is required when using --query-id" ) ;
410+ std:: process:: exit ( 1 ) ;
411+ }
412+ } ;
413+ create_dataset ( workspace_id, label, table_name, json ! ( { "saved_query_id" : query_id } ) , None ) ;
348414}
349415
350416pub fn list ( workspace_id : & str , limit : Option < u32 > , offset : Option < u32 > , format : & str ) {
0 commit comments