7
7
// the Business Source License, use of this software will be governed
8
8
// by the Apache License, Version 2.0.
9
9
10
- use std:: path:: PathBuf ;
10
+ use std:: path:: { Path , PathBuf } ;
11
11
use std:: sync:: Arc ;
12
12
13
13
use async_trait:: async_trait;
@@ -114,6 +114,18 @@ impl DatasetRepositoryLocalFs {
114
114
self . storage_strategy . get_dataset_path ( & dataset_handle) ,
115
115
) )
116
116
}
117
+
118
+ fn get_canonical_path_param ( dataset_path : & Path ) -> Result < ( PathBuf , String ) , InternalError > {
119
+ let canonical_dataset_path = std:: fs:: canonicalize ( dataset_path) . int_err ( ) ?;
120
+ let dataset_name_str = canonical_dataset_path
121
+ . file_name ( )
122
+ . unwrap ( )
123
+ . to_str ( )
124
+ . unwrap ( )
125
+ . to_string ( ) ;
126
+
127
+ Ok ( ( canonical_dataset_path, dataset_name_str) )
128
+ }
117
129
}
118
130
119
131
/////////////////////////////////////////////////////////////////////////////////////////
@@ -241,7 +253,21 @@ impl DatasetRepository for DatasetRepositoryLocalFs {
241
253
242
254
// It's okay to create a new dataset by this point
243
255
let dataset_id = seed_block. event . dataset_id . clone ( ) ;
244
- let dataset_handle = DatasetHandle :: new ( dataset_id, dataset_alias. clone ( ) ) ;
256
+ let dataset_handle = if let Some ( account_name) = & dataset_alias. account_name {
257
+ let ( _, canonical_account_name) = self
258
+ . storage_strategy
259
+ . resolve_account_dir ( account_name)
260
+ . int_err ( ) ?;
261
+ let canonical_dataset_alias = DatasetAlias :: new (
262
+ Some ( canonical_account_name) ,
263
+ dataset_alias. dataset_name . clone ( ) ,
264
+ ) ;
265
+
266
+ DatasetHandle :: new ( dataset_id, canonical_dataset_alias)
267
+ } else {
268
+ DatasetHandle :: new ( dataset_id, dataset_alias. clone ( ) )
269
+ } ;
270
+
245
271
let dataset_path = self . storage_strategy . get_dataset_path ( & dataset_handle) ;
246
272
let layout = DatasetLayout :: create ( & dataset_path) . int_err ( ) ?;
247
273
let dataset = Self :: build_dataset ( layout, self . event_bus . clone ( ) ) ;
@@ -430,6 +456,11 @@ trait DatasetStorageStrategy: Sync + Send {
430
456
dataset_handle : & DatasetHandle ,
431
457
new_name : & DatasetName ,
432
458
) -> Result < ( ) , InternalError > ;
459
+
460
+ fn resolve_account_dir (
461
+ & self ,
462
+ account_name : & AccountName ,
463
+ ) -> Result < ( PathBuf , AccountName ) , ResolveDatasetError > ;
433
464
}
434
465
435
466
#[ derive( thiserror:: Error , Debug ) ]
@@ -476,10 +507,11 @@ impl DatasetSingleTenantStorageStrategy {
476
507
& self ,
477
508
dataset_path : & PathBuf ,
478
509
dataset_alias : & DatasetAlias ,
479
- ) -> Result < DatasetSummary , ResolveDatasetError > {
510
+ ) -> Result < ( DatasetSummary , DatasetAlias ) , ResolveDatasetError > {
480
511
let layout = DatasetLayout :: new ( dataset_path) ;
481
512
let dataset = DatasetRepositoryLocalFs :: build_dataset ( layout, self . event_bus . clone ( ) ) ;
482
- dataset
513
+
514
+ let dataset_summary = dataset
483
515
. get_summary ( GetSummaryOpts :: default ( ) )
484
516
. await
485
517
. map_err ( |e| {
@@ -490,40 +522,31 @@ impl DatasetSingleTenantStorageStrategy {
490
522
} else {
491
523
ResolveDatasetError :: Internal ( e. int_err ( ) )
492
524
}
493
- } )
494
- }
525
+ } ) ?;
495
526
496
- async fn attempt_resolve_dataset_alias (
497
- & self ,
498
- dataset_alias : & DatasetAlias ,
499
- ) -> Result < DatasetHandle , ResolveDatasetError > {
500
- assert ! (
501
- !dataset_alias. is_multi_tenant( )
502
- || dataset_alias. account_name. as_ref( ) . unwrap( ) == DEFAULT_ACCOUNT_NAME ,
503
- "Multi-tenant refs shouldn't have reached down to here with earlier validations"
504
- ) ;
505
-
506
- let dataset_path = self . dataset_path_impl ( dataset_alias) ;
507
- if !dataset_path. exists ( ) {
508
- return Err ( ResolveDatasetError :: NotFound ( DatasetNotFoundError {
509
- dataset_ref : dataset_alias. as_local_ref ( ) ,
510
- } ) ) ;
511
- }
527
+ let ( _, canonical_dataset_name) =
528
+ DatasetRepositoryLocalFs :: get_canonical_path_param ( dataset_path) ?;
529
+ let canonical_dataset_alias = DatasetAlias {
530
+ dataset_name : DatasetName :: new_unchecked ( canonical_dataset_name. as_str ( ) ) ,
531
+ account_name : None ,
532
+ } ;
512
533
513
- self . resolve_dataset_handle ( & dataset_path, dataset_alias)
514
- . await
534
+ Ok ( ( dataset_summary, canonical_dataset_alias) )
515
535
}
516
536
517
537
async fn resolve_dataset_handle (
518
538
& self ,
519
539
dataset_path : & PathBuf ,
520
540
dataset_alias : & DatasetAlias ,
521
541
) -> Result < DatasetHandle , ResolveDatasetError > {
522
- let summary = self
542
+ let ( summary, canonical_dataset_alias ) = self
523
543
. attempt_resolving_summary_via_path ( dataset_path, dataset_alias)
524
544
. await ?;
525
545
526
- Ok ( DatasetHandle :: new ( summary. id , dataset_alias. clone ( ) ) )
546
+ Ok ( DatasetHandle :: new (
547
+ summary. id ,
548
+ canonical_dataset_alias. clone ( ) ,
549
+ ) )
527
550
}
528
551
}
529
552
@@ -550,7 +573,7 @@ impl DatasetStorageStrategy for DatasetSingleTenantStorageStrategy {
550
573
}
551
574
let dataset_name = DatasetName :: try_from( & dataset_dir_entry. file_name( ) ) . int_err( ) ?;
552
575
let dataset_alias = DatasetAlias :: new( None , dataset_name) ;
553
- match self . attempt_resolve_dataset_alias ( & dataset_alias) . await {
576
+ match self . resolve_dataset_handle ( & dataset_dir_entry . path ( ) , & dataset_alias) . await {
554
577
Ok ( hdl) => { yield hdl; Ok ( ( ) ) }
555
578
Err ( ResolveDatasetError :: NotFound ( _) ) => Ok ( ( ) ) ,
556
579
Err ( e) => Err ( e. int_err( ) )
@@ -623,12 +646,12 @@ impl DatasetStorageStrategy for DatasetSingleTenantStorageStrategy {
623
646
624
647
let dataset_path = self . dataset_path_impl ( & alias) ;
625
648
626
- let summary = self
649
+ let ( summary, canonical_dataset_alias ) = self
627
650
. attempt_resolving_summary_via_path ( & dataset_path, & alias)
628
651
. await ?;
629
652
630
653
if summary. id == * dataset_id {
631
- return Ok ( DatasetHandle :: new ( summary. id , alias ) ) ;
654
+ return Ok ( DatasetHandle :: new ( summary. id , canonical_dataset_alias ) ) ;
632
655
}
633
656
}
634
657
@@ -656,6 +679,16 @@ impl DatasetStorageStrategy for DatasetSingleTenantStorageStrategy {
656
679
std:: fs:: rename ( old_dataset_path, new_dataset_path) . int_err ( ) ?;
657
680
Ok ( ( ) )
658
681
}
682
+
683
+ fn resolve_account_dir (
684
+ & self ,
685
+ _account_name : & AccountName ,
686
+ ) -> Result < ( PathBuf , AccountName ) , ResolveDatasetError > {
687
+ Ok ( (
688
+ self . root . join ( DEFAULT_ACCOUNT_NAME ) ,
689
+ AccountName :: new_unchecked ( DEFAULT_ACCOUNT_NAME ) ,
690
+ ) )
691
+ }
659
692
}
660
693
661
694
/////////////////////////////////////////////////////////////////////////////////////////
@@ -772,32 +805,6 @@ impl DatasetMultiTenantStorageStrategy {
772
805
}
773
806
} )
774
807
}
775
-
776
- fn resolve_account_dir (
777
- & self ,
778
- account_name : & AccountName ,
779
- ) -> Result < PathBuf , ResolveDatasetError > {
780
- let account_dataset_dir_path = self . root . join ( account_name) ;
781
-
782
- if !account_dataset_dir_path. is_dir ( ) {
783
- let read_accout_dirs = std:: fs:: read_dir ( self . root . as_path ( ) ) . int_err ( ) ?;
784
-
785
- for read_accout_dir in read_accout_dirs {
786
- let account_dir_name = AccountName :: new_unchecked (
787
- read_accout_dir
788
- . int_err ( ) ?
789
- . file_name ( )
790
- . to_str ( )
791
- . unwrap_or ( "" ) ,
792
- ) ;
793
- if account_name == & account_dir_name {
794
- return Ok ( self . root . join ( account_dir_name) ) ;
795
- }
796
- }
797
- }
798
-
799
- Ok ( account_dataset_dir_path)
800
- }
801
808
}
802
809
803
810
#[ async_trait]
@@ -862,10 +869,14 @@ impl DatasetStorageStrategy for DatasetMultiTenantStorageStrategy {
862
869
dataset_alias : & DatasetAlias ,
863
870
) -> Result < DatasetHandle , ResolveDatasetError > {
864
871
let effective_account_name = self . effective_account_name ( dataset_alias) ;
865
- let account_dataset_dir_path = self . resolve_account_dir ( effective_account_name) ?;
872
+ let ( account_dataset_dir_path, _ ) = self . resolve_account_dir ( effective_account_name) ?;
866
873
867
874
if account_dataset_dir_path. is_dir ( ) {
868
- let read_dataset_dir = std:: fs:: read_dir ( account_dataset_dir_path) . int_err ( ) ?;
875
+ let read_dataset_dir = std:: fs:: read_dir ( account_dataset_dir_path) . map_err ( |_| {
876
+ ResolveDatasetError :: NotFound ( DatasetNotFoundError {
877
+ dataset_ref : dataset_alias. as_local_ref ( ) ,
878
+ } )
879
+ } ) ?;
869
880
870
881
for r_dataset_dir in read_dataset_dir {
871
882
let dataset_dir_entry = r_dataset_dir. int_err ( ) ?;
@@ -962,6 +973,39 @@ impl DatasetStorageStrategy for DatasetMultiTenantStorageStrategy {
962
973
963
974
Ok ( ( ) )
964
975
}
976
+
977
+ fn resolve_account_dir (
978
+ & self ,
979
+ account_name : & AccountName ,
980
+ ) -> Result < ( PathBuf , AccountName ) , ResolveDatasetError > {
981
+ let account_dataset_dir_path = self . root . join ( account_name) ;
982
+
983
+ if !account_dataset_dir_path. is_dir ( ) {
984
+ let read_accout_dirs = std:: fs:: read_dir ( self . root . as_path ( ) ) . int_err ( ) ?;
985
+
986
+ for read_accout_dir in read_accout_dirs {
987
+ let account_dir_name = AccountName :: new_unchecked (
988
+ read_accout_dir
989
+ . int_err ( ) ?
990
+ . file_name ( )
991
+ . to_str ( )
992
+ . unwrap_or ( "" ) ,
993
+ ) ;
994
+ if account_name == & account_dir_name {
995
+ return Ok ( ( self . root . join ( & account_dir_name) , account_dir_name) ) ;
996
+ }
997
+ }
998
+ return Ok ( ( account_dataset_dir_path, account_name. clone ( ) ) ) ;
999
+ }
1000
+
1001
+ let ( canonical_account_dataset_dir_path, canonical_account_name) =
1002
+ DatasetRepositoryLocalFs :: get_canonical_path_param ( & account_dataset_dir_path) ?;
1003
+
1004
+ Ok ( (
1005
+ canonical_account_dataset_dir_path,
1006
+ AccountName :: new_unchecked ( canonical_account_name. as_str ( ) ) ,
1007
+ ) )
1008
+ }
965
1009
}
966
1010
967
1011
/////////////////////////////////////////////////////////////////////////////////////////
0 commit comments