@@ -220,13 +220,12 @@ fn upload_from_stdin(
220220 ( id, ft. format )
221221}
222222
223- pub fn create (
223+ fn create_dataset (
224224 workspace_id : & str ,
225- label : Option < & str > ,
225+ label : & str ,
226226 table_name : Option < & str > ,
227- file : Option < & str > ,
228- upload_id : Option < & str > ,
229- source_format : & str ,
227+ source : serde_json:: Value ,
228+ on_failure : Option < Box < dyn FnOnce ( ) > > ,
230229) {
231230 let profile_config = match config:: load ( "default" ) {
232231 Ok ( c) => c,
@@ -244,62 +243,13 @@ pub fn create(
244243 }
245244 } ;
246245
247- let label_derived;
248- let label: & str = match label {
249- Some ( l) => l,
250- None => match file {
251- Some ( path) => {
252- label_derived = Path :: new ( path)
253- . file_stem ( )
254- . and_then ( |s| s. to_str ( ) )
255- . unwrap_or ( "dataset" )
256- . to_string ( ) ;
257- & label_derived
258- }
259- None => {
260- if upload_id. is_some ( ) {
261- eprintln ! ( "error: no label provided. Use --label to name the dataset." ) ;
262- std:: process:: exit ( 1 ) ;
263- }
264- match stdin_redirect_filename ( ) {
265- Some ( name) => {
266- label_derived = name;
267- & label_derived
268- }
269- None => {
270- eprintln ! ( "error: no label provided. Use --label to name the dataset." ) ;
271- std:: process:: exit ( 1 ) ;
272- }
273- }
274- }
275- } ,
276- } ;
277-
278- let client = reqwest:: blocking:: Client :: new ( ) ;
279-
280- let ( upload_id, format, upload_id_was_uploaded) : ( String , & str , bool ) = if let Some ( id) = upload_id {
281- ( id. to_string ( ) , source_format, false )
282- } else {
283- let ( id, fmt) = match file {
284- Some ( path) => upload_from_file ( & client, & api_key, workspace_id, & profile_config. api_url , path) ,
285- None => {
286- use std:: io:: IsTerminal ;
287- if std:: io:: stdin ( ) . is_terminal ( ) {
288- eprintln ! ( "error: no input data. Use --file <path>, --upload-id <id>, or pipe data via stdin." ) ;
289- std:: process:: exit ( 1 ) ;
290- }
291- upload_from_stdin ( & client, & api_key, workspace_id, & profile_config. api_url )
292- }
293- } ;
294- ( id, fmt, true )
295- } ;
296-
297- let source = json ! ( { "upload_id" : upload_id, "format" : format } ) ;
298246 let mut body = json ! ( { "label" : label, "source" : source } ) ;
299247 if let Some ( tn) = table_name {
300248 body[ "table_name" ] = json ! ( tn) ;
301249 }
250+
302251 let url = format ! ( "{}/datasets" , profile_config. api_url) ;
252+ let client = reqwest:: blocking:: Client :: new ( ) ;
303253
304254 let resp = match client
305255 . post ( & url)
@@ -318,15 +268,8 @@ pub fn create(
318268 if !resp. status ( ) . is_success ( ) {
319269 use crossterm:: style:: Stylize ;
320270 eprintln ! ( "{}" , crate :: util:: api_error( resp. text( ) . unwrap_or_default( ) ) . red( ) ) ;
321- // Only show the resume hint when the upload_id came from a fresh upload
322- if upload_id_was_uploaded {
323- eprintln ! (
324- "{}" ,
325- format!(
326- "Resume dataset creation without re-uploading by passing --upload-id {upload_id}"
327- )
328- . yellow( )
329- ) ;
271+ if let Some ( f) = on_failure {
272+ f ( ) ;
330273 }
331274 std:: process:: exit ( 1 ) ;
332275 }
@@ -346,12 +289,13 @@ pub fn create(
346289 println ! ( "full_name: datasets.main.{}" , dataset. table_name) ;
347290}
348291
349- fn create_from_source (
292+ pub fn create_from_upload (
350293 workspace_id : & str ,
351- source : serde_json:: Value ,
352294 label : Option < & str > ,
353295 table_name : Option < & str > ,
354- label_required_hint : & str ,
296+ file : Option < & str > ,
297+ upload_id : Option < & str > ,
298+ source_format : & str ,
355299) {
356300 let profile_config = match config:: load ( "default" ) {
357301 Ok ( c) => c,
@@ -369,55 +313,72 @@ fn create_from_source(
369313 }
370314 } ;
371315
372- let label = match label {
316+ let label_derived;
317+ let label: & str = match label {
373318 Some ( l) => l,
374- None => {
375- eprintln ! ( "error: --label is required when using {label_required_hint}" ) ;
376- std:: process:: exit ( 1 ) ;
377- }
319+ None => match file {
320+ Some ( path) => {
321+ label_derived = Path :: new ( path)
322+ . file_stem ( )
323+ . and_then ( |s| s. to_str ( ) )
324+ . unwrap_or ( "dataset" )
325+ . to_string ( ) ;
326+ & label_derived
327+ }
328+ None => {
329+ if upload_id. is_some ( ) {
330+ eprintln ! ( "error: no label provided. Use --label to name the dataset." ) ;
331+ std:: process:: exit ( 1 ) ;
332+ }
333+ match stdin_redirect_filename ( ) {
334+ Some ( name) => {
335+ label_derived = name;
336+ & label_derived
337+ }
338+ None => {
339+ eprintln ! ( "error: no label provided. Use --label to name the dataset." ) ;
340+ std:: process:: exit ( 1 ) ;
341+ }
342+ }
343+ }
344+ } ,
378345 } ;
379346
380- let mut body = json ! ( { "label" : label, "source" : source } ) ;
381- if let Some ( tn) = table_name {
382- body[ "table_name" ] = json ! ( tn) ;
383- }
384-
385- let url = format ! ( "{}/datasets" , profile_config. api_url) ;
386347 let client = reqwest:: blocking:: Client :: new ( ) ;
387348
388- let resp = match client
389- . post ( & url)
390- . header ( "Authorization" , format ! ( "Bearer {api_key}" ) )
391- . header ( "X-Workspace-Id" , workspace_id)
392- . json ( & body)
393- . send ( )
394- {
395- Ok ( r) => r,
396- Err ( e) => {
397- eprintln ! ( "error connecting to API: {e}" ) ;
398- std:: process:: exit ( 1 ) ;
399- }
349+ let ( upload_id, format, upload_id_was_uploaded) : ( String , & str , bool ) = if let Some ( id) = upload_id {
350+ ( id. to_string ( ) , source_format, false )
351+ } else {
352+ let ( id, fmt) = match file {
353+ Some ( path) => upload_from_file ( & client, & api_key, workspace_id, & profile_config. api_url , path) ,
354+ None => {
355+ use std:: io:: IsTerminal ;
356+ if std:: io:: stdin ( ) . is_terminal ( ) {
357+ eprintln ! ( "error: no input data. Use --file <path>, --upload-id <id>, or pipe data via stdin." ) ;
358+ std:: process:: exit ( 1 ) ;
359+ }
360+ upload_from_stdin ( & client, & api_key, workspace_id, & profile_config. api_url )
361+ }
362+ } ;
363+ ( id, fmt, true )
400364 } ;
401365
402- if !resp. status ( ) . is_success ( ) {
403- use crossterm:: style:: Stylize ;
404- eprintln ! ( "{}" , crate :: util:: api_error( resp. text( ) . unwrap_or_default( ) ) . red( ) ) ;
405- std:: process:: exit ( 1 ) ;
406- }
366+ let source = json ! ( { "upload_id" : upload_id, "format" : format } ) ;
407367
408- let dataset: CreateResponse = match resp. json ( ) {
409- Ok ( v) => v,
410- Err ( e) => {
411- eprintln ! ( "error parsing response: {e}" ) ;
412- std:: process:: exit ( 1 ) ;
413- }
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 ;
372+ eprintln ! (
373+ "{}" ,
374+ format!( "Resume dataset creation without re-uploading by passing --upload-id {uid}" ) . yellow( )
375+ ) ;
376+ } ) )
377+ } else {
378+ None
414379 } ;
415380
416- use crossterm:: style:: Stylize ;
417- println ! ( "{}" , "Dataset created" . green( ) ) ;
418- println ! ( "id: {}" , dataset. id) ;
419- println ! ( "label: {}" , dataset. label) ;
420- println ! ( "full_name: datasets.main.{}" , dataset. table_name) ;
381+ create_dataset ( workspace_id, label, table_name, source, on_failure) ;
421382}
422383
423384pub fn create_from_query (
@@ -426,7 +387,14 @@ pub fn create_from_query(
426387 label : Option < & str > ,
427388 table_name : Option < & str > ,
428389) {
429- create_from_source ( workspace_id, json ! ( { "sql" : sql } ) , label, table_name, "--sql" ) ;
390+ let label = match label {
391+ Some ( l) => l,
392+ None => {
393+ eprintln ! ( "error: --label is required when using --sql" ) ;
394+ std:: process:: exit ( 1 ) ;
395+ }
396+ } ;
397+ create_dataset ( workspace_id, label, table_name, json ! ( { "sql" : sql } ) , None ) ;
430398}
431399
432400pub fn create_from_saved_query (
@@ -435,7 +403,14 @@ pub fn create_from_saved_query(
435403 label : Option < & str > ,
436404 table_name : Option < & str > ,
437405) {
438- create_from_source ( workspace_id, json ! ( { "saved_query_id" : query_id } ) , label, table_name, "--query-id" ) ;
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 ) ;
439414}
440415
441416pub fn list ( workspace_id : & str , limit : Option < u32 > , offset : Option < u32 > , format : & str ) {
0 commit comments