@@ -8,35 +8,96 @@ use object_store::local::LocalFileSystem;
88use object_store:: memory:: InMemory ;
99use object_store:: path:: Path ;
1010use object_store:: prefix:: PrefixObjectStore ;
11- use object_store:: { ClientOptions , DynObjectStore , Result as ObjectStoreResult } ;
11+ use object_store:: {
12+ ClientOptions , DynObjectStore , Error as ObjectStoreError , Result as ObjectStoreResult ,
13+ RetryConfig ,
14+ } ;
1215use url:: Url ;
1316
14- use crate :: settings :: AzureConfig ;
17+ use crate :: config :: { aws :: S3Config , azure :: AzureConfig , google :: GoogleConfig } ;
1518
16- pub enum ObjectStoreImpl {
19+ enum ObjectStoreKind {
20+ Local ,
21+ InMemory ,
22+ S3 ,
23+ Google ,
24+ Azure ,
25+ }
26+
27+ impl ObjectStoreKind {
28+ pub fn parse_url ( url : & Url ) -> ObjectStoreResult < Self > {
29+ match url. scheme ( ) {
30+ "file" => Ok ( ObjectStoreKind :: Local ) ,
31+ "memory" => Ok ( ObjectStoreKind :: InMemory ) ,
32+ "az" | "abfs" | "abfss" | "azure" | "wasb" | "adl" => Ok ( ObjectStoreKind :: Azure ) ,
33+ "s3" | "s3a" => Ok ( ObjectStoreKind :: S3 ) ,
34+ "gs" => Ok ( ObjectStoreKind :: Google ) ,
35+ "https" => {
36+ let host = url. host_str ( ) . unwrap_or_default ( ) ;
37+ if host. contains ( "amazonaws.com" ) {
38+ Ok ( ObjectStoreKind :: S3 )
39+ } else if host. contains ( "dfs.core.windows.net" )
40+ || host. contains ( "blob.core.windows.net" )
41+ {
42+ Ok ( ObjectStoreKind :: Azure )
43+ } else {
44+ Err ( ObjectStoreError :: NotImplemented )
45+ }
46+ }
47+ _ => Err ( ObjectStoreError :: NotImplemented ) ,
48+ }
49+ }
50+ }
51+
52+ enum ObjectStoreImpl {
1753 Local ( LocalFileSystem ) ,
54+ InMemory ( InMemory ) ,
1855 Azrue ( MicrosoftAzure ) ,
1956 S3 ( AmazonS3 ) ,
2057 Gcp ( GoogleCloudStorage ) ,
21- InMemory ( InMemory ) ,
2258}
2359
24- pub struct StorageBuilder {
60+ impl ObjectStoreImpl {
61+ pub fn into_prefix ( self , prefix : Path ) -> Arc < DynObjectStore > {
62+ match self {
63+ ObjectStoreImpl :: Local ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
64+ ObjectStoreImpl :: InMemory ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
65+ ObjectStoreImpl :: Azrue ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
66+ ObjectStoreImpl :: S3 ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
67+ ObjectStoreImpl :: Gcp ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
68+ }
69+ }
70+
71+ pub fn into_store ( self ) -> Arc < DynObjectStore > {
72+ match self {
73+ ObjectStoreImpl :: Local ( store) => Arc :: new ( store) ,
74+ ObjectStoreImpl :: InMemory ( store) => Arc :: new ( store) ,
75+ ObjectStoreImpl :: Azrue ( store) => Arc :: new ( store) ,
76+ ObjectStoreImpl :: S3 ( store) => Arc :: new ( store) ,
77+ ObjectStoreImpl :: Gcp ( store) => Arc :: new ( store) ,
78+ }
79+ }
80+ }
81+
82+ #[ derive( Debug , Clone ) ]
83+ pub struct ObjectStoreBuilder {
2584 url : String ,
2685 prefix : Option < Path > ,
2786 path_as_prefix : bool ,
2887 options : HashMap < String , String > ,
29- client_options : ClientOptions ,
88+ client_options : Option < ClientOptions > ,
89+ retry_config : Option < RetryConfig > ,
3090}
3191
32- impl StorageBuilder {
92+ impl ObjectStoreBuilder {
3393 pub fn new ( url : impl Into < String > ) -> Self {
3494 Self {
3595 url : url. into ( ) ,
3696 prefix : None ,
3797 path_as_prefix : false ,
3898 options : Default :: default ( ) ,
39- client_options : Default :: default ( ) ,
99+ client_options : None ,
100+ retry_config : None ,
40101 }
41102 }
42103
@@ -55,39 +116,60 @@ impl StorageBuilder {
55116 self
56117 }
57118
119+ pub fn with_path_as_prefix ( mut self , path_as_prefix : bool ) -> Self {
120+ self . path_as_prefix = path_as_prefix;
121+ self
122+ }
123+
124+ pub fn with_client_options ( mut self , options : ClientOptions ) -> Self {
125+ self . client_options = Some ( options) ;
126+ self
127+ }
128+
129+ pub fn with_retry_config ( mut self , retry_config : RetryConfig ) -> Self {
130+ self . retry_config = Some ( retry_config) ;
131+ self
132+ }
133+
58134 pub fn build ( mut self ) -> ObjectStoreResult < Arc < DynObjectStore > > {
59- let url = Url :: parse ( & self . url ) . unwrap ( ) ;
60- let root_store = match url. scheme ( ) {
61- "file" => ObjectStoreImpl :: Local ( LocalFileSystem :: new ( ) ) ,
62- "memory" => ObjectStoreImpl :: InMemory ( InMemory :: new ( ) ) ,
63- "az" | "abfs" | "abfss" | "azure" | "wasb" | "adl" => {
64- let mut builder = AzureConfig :: get_builder ( & url, & self . options ) ?;
65- builder = builder. with_client_options ( self . client_options ) ;
135+ let url = Url :: parse ( & self . url ) . map_err ( |err| ObjectStoreError :: Generic {
136+ store : "Generic" ,
137+ source : Box :: new ( err) ,
138+ } ) ?;
139+ let root_store = match ObjectStoreKind :: parse_url ( & url) . unwrap ( ) {
140+ ObjectStoreKind :: Local => ObjectStoreImpl :: Local ( LocalFileSystem :: new ( ) ) ,
141+ ObjectStoreKind :: InMemory => ObjectStoreImpl :: InMemory ( InMemory :: new ( ) ) ,
142+ ObjectStoreKind :: Azure => {
143+ let mut builder = AzureConfig :: get_builder ( & self . url , & self . options ) ?;
144+ builder = builder
145+ . with_client_options ( self . client_options . unwrap_or_default ( ) )
146+ . with_retry ( self . retry_config . unwrap_or_default ( ) ) ;
66147 ObjectStoreImpl :: Azrue ( builder. build ( ) ?)
67148 }
68- "s3" | "s3a" => todo ! ( ) ,
69- "gs" => todo ! ( ) ,
70- "https" => todo ! ( ) ,
71- _ => todo ! ( ) ,
149+ ObjectStoreKind :: S3 => {
150+ let mut builder = S3Config :: get_builder ( & self . url , & self . options ) ?;
151+ builder = builder
152+ . with_client_options ( self . client_options . unwrap_or_default ( ) )
153+ . with_retry ( self . retry_config . unwrap_or_default ( ) ) ;
154+ ObjectStoreImpl :: S3 ( builder. build ( ) ?)
155+ }
156+ ObjectStoreKind :: Google => {
157+ let mut builder = GoogleConfig :: get_builder ( & self . url , & self . options ) ?;
158+ builder = builder
159+ . with_client_options ( self . client_options . unwrap_or_default ( ) )
160+ . with_retry ( self . retry_config . unwrap_or_default ( ) ) ;
161+ ObjectStoreImpl :: Gcp ( builder. build ( ) ?)
162+ }
72163 } ;
73164
74165 if self . path_as_prefix && !url. path ( ) . is_empty ( ) && self . prefix . is_none ( ) {
75166 self . prefix = Some ( Path :: from ( url. path ( ) ) )
76167 }
77168
78- let store: Arc < DynObjectStore > = if let Some ( prefix) = self . prefix {
79- match root_store {
80- ObjectStoreImpl :: Local ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
81- ObjectStoreImpl :: InMemory ( store) => Arc :: new ( PrefixObjectStore :: new ( store, prefix) ) ,
82- _ => todo ! ( ) ,
83- }
169+ if let Some ( prefix) = self . prefix {
170+ Ok ( root_store. into_prefix ( prefix) )
84171 } else {
85- match root_store {
86- ObjectStoreImpl :: Local ( store) => Arc :: new ( store) ,
87- ObjectStoreImpl :: InMemory ( store) => Arc :: new ( store) ,
88- _ => todo ! ( ) ,
89- }
90- } ;
91- Ok ( store)
172+ Ok ( root_store. into_store ( ) )
173+ }
92174 }
93175}
0 commit comments