@@ -5,20 +5,19 @@ use crate::JwstStorageError;
55use bytes:: Bytes ;
66use futures:: Stream ;
77use jwst:: { BlobMetadata , BlobStorage , BucketBlobStorage , JwstResult } ;
8+ use jwst_storage_migration:: Migrator ;
9+ use opendal:: services:: S3 ;
810use opendal:: Operator ;
911use sea_orm:: { DatabaseConnection , EntityTrait } ;
12+ use sea_orm_migration:: MigratorTrait ;
1013use std:: collections:: HashMap ;
1114use std:: sync:: Arc ;
1215
13- #[ allow( unused) ]
1416pub ( super ) type BucketBlobModel = <BucketBlobs as EntityTrait >:: Model ;
15- #[ allow( unused) ]
1617type BucketBlobActiveModel = entities:: bucket_blobs:: ActiveModel ;
17- #[ allow( unused) ]
1818type BucketBlobColumn = <BucketBlobs as EntityTrait >:: Column ;
1919
2020#[ derive( Clone ) ]
21- #[ allow( unused) ]
2221pub struct BlobBucketDBStorage {
2322 bucket : Arc < Bucket > ,
2423 pub ( super ) pool : DatabaseConnection ,
@@ -31,17 +30,53 @@ impl AsRef<DatabaseConnection> for BlobBucketDBStorage {
3130 }
3231}
3332
34- #[ allow( unused) ]
3533impl BlobBucketDBStorage {
34+ #[ allow( unused) ]
3635 pub async fn init_with_pool (
3736 pool : DatabaseConnection ,
3837 bucket : Arc < Bucket > ,
38+ bucket_storage : Option < BucketStorage > ,
3939 ) -> JwstStorageResult < Self > {
40- todo ! ( )
40+ Migrator :: up ( & pool, None ) . await ?;
41+ Ok ( Self {
42+ bucket,
43+ pool,
44+ bucket_storage : bucket_storage. unwrap_or ( BucketStorage :: new ( ) ?) ,
45+ } )
4146 }
4247
43- pub async fn init_pool ( database : & str ) -> JwstStorageResult < Self > {
44- todo ! ( )
48+ #[ allow( unused) ]
49+ pub async fn init_pool (
50+ database : & str ,
51+ bucket_storage : Option < BucketStorage > ,
52+ ) -> JwstStorageResult < Self > {
53+ let is_sqlite = is_sqlite ( database) ;
54+ let pool = create_connection ( database, is_sqlite) . await ?;
55+
56+ Self :: init_with_pool ( pool, get_bucket ( is_sqlite) , bucket_storage) . await
57+ }
58+
59+ #[ allow( unused) ]
60+ async fn all ( & self , workspace : & str ) -> Result < Vec < BucketBlobModel > , DbErr > {
61+ BucketBlobs :: find ( )
62+ . filter ( BucketBlobColumn :: Workspace . eq ( workspace) )
63+ . all ( & self . pool )
64+ . await
65+ }
66+
67+ #[ allow( unused) ]
68+ async fn count ( & self , workspace : & str ) -> Result < u64 , DbErr > {
69+ BucketBlobs :: find ( )
70+ . filter ( BucketBlobColumn :: Workspace . eq ( workspace) )
71+ . count ( & self . pool )
72+ . await
73+ }
74+
75+ async fn exists ( & self , workspace : & str , hash : & str ) -> Result < bool , DbErr > {
76+ BucketBlobs :: find_by_id ( ( workspace. into ( ) , hash. into ( ) ) )
77+ . count ( & self . pool )
78+ . await
79+ . map ( |c| c > 0 )
4580 }
4681
4782 pub ( super ) async fn metadata (
@@ -60,13 +95,6 @@ impl BlobBucketDBStorage {
6095 . and_then ( |r| r. ok_or ( JwstBlobError :: BlobNotFound ( hash. into ( ) ) ) )
6196 }
6297
63- async fn exists ( & self , workspace : & str , hash : & str ) -> Result < bool , DbErr > {
64- BucketBlobs :: find_by_id ( ( workspace. into ( ) , hash. into ( ) ) )
65- . count ( & self . pool )
66- . await
67- . map ( |c| c > 0 )
68- }
69-
7098 pub ( super ) async fn get_blobs_size ( & self , workspace : & str ) -> Result < Option < i64 > , DbErr > {
7199 BucketBlobs :: find ( )
72100 . filter ( BucketBlobColumn :: Workspace . eq ( workspace) )
@@ -115,7 +143,29 @@ pub struct BucketStorage {
115143 pub ( super ) op : Operator ,
116144}
117145
118- // TODO Builder for BucketStorage;
146+ impl BucketStorage {
147+ #[ allow( unused) ]
148+ pub fn new ( ) -> JwstStorageResult < Self > {
149+ let access_key = dotenvy:: var ( "BUCKET_ACCESS_TOKEN" ) ?;
150+ let secret_access_key = dotenvy:: var ( "BUCKET_SECRET_TOKEN" ) ?;
151+ let endpoint = dotenvy:: var ( "BUCKET_ENDPOINT" ) ?;
152+ let bucket = dotenvy:: var ( "BUCKET_NAME" ) ;
153+ let root = dotenvy:: var ( "BUCKET_ROOT" ) ;
154+
155+ let mut builder = S3 :: default ( ) ;
156+
157+ builder. bucket ( bucket. unwrap_or ( "default_bucket" . to_string ( ) ) . as_str ( ) ) ;
158+ builder. root ( root. unwrap_or ( "default_root" . to_string ( ) ) . as_str ( ) ) ;
159+ builder. endpoint ( endpoint. as_str ( ) ) ;
160+ builder. access_key_id ( access_key. as_str ( ) ) ;
161+ builder. secret_access_key ( secret_access_key. as_str ( ) ) ;
162+
163+ Ok ( Self {
164+ op : Operator :: new ( builder) ?. finish ( ) ,
165+ } )
166+ }
167+ }
168+
119169// TODO add retry layer
120170
121171#[ allow( unused_variables) ]
@@ -250,3 +300,23 @@ impl BlobStorage<JwstStorageError> for BlobBucketDBStorage {
250300 return Ok ( size. unwrap_or ( 0 ) ) ;
251301 }
252302}
303+
304+ #[ cfg( test) ]
305+ mod tests {
306+ use super :: * ;
307+ use crate :: storage:: blobs:: utils:: BucketStorageBuilder ;
308+
309+ #[ tokio:: test]
310+ #[ ignore = "need to config bucket auth" ]
311+ async fn test_init_bucket_storage ( ) {
312+ let bucket_storage = BucketStorageBuilder :: new ( )
313+ . bucket ( "bucket" )
314+ . root ( "root" )
315+ . build ( )
316+ . unwrap ( ) ;
317+
318+ BlobBucketDBStorage :: init_pool ( "sqlite::memory:" , Some ( bucket_storage) )
319+ . await
320+ . unwrap ( ) ;
321+ }
322+ }
0 commit comments