1717
1818use std:: fmt:: Debug ;
1919use std:: str:: FromStr ;
20+ use std:: sync:: Arc ;
2021
21- use sqlx:: MySqlPool ;
2222use sqlx:: mysql:: MySqlConnectOptions ;
2323use tokio:: sync:: OnceCell ;
2424
25- use crate :: raw:: adapters:: kv;
25+ use super :: config:: MysqlConfig ;
26+ use super :: core:: * ;
27+ use super :: deleter:: MysqlDeleter ;
28+ use super :: writer:: MysqlWriter ;
29+ use crate :: raw:: oio;
2630use crate :: raw:: * ;
27- use crate :: services:: MysqlConfig ;
2831use crate :: * ;
2932
3033#[ doc = include_str ! ( "docs.md" ) ]
@@ -142,7 +145,7 @@ impl Builder for MysqlBuilder {
142145
143146 let root = normalize_root ( self . config . root . unwrap_or_else ( || "/" . to_string ( ) ) . as_str ( ) ) ;
144147
145- Ok ( MySqlBackend :: new ( Adapter {
148+ Ok ( MysqlBackend :: new ( MysqlCore {
146149 pool : OnceCell :: new ( ) ,
147150 config,
148151 table,
@@ -154,96 +157,92 @@ impl Builder for MysqlBuilder {
154157}
155158
156159/// Backend for mysql service
157- pub type MySqlBackend = kv:: Backend < Adapter > ;
158-
159- #[ derive( Debug , Clone ) ]
160- pub struct Adapter {
161- pool : OnceCell < MySqlPool > ,
162- config : MySqlConnectOptions ,
163-
164- table : String ,
165- key_field : String ,
166- value_field : String ,
160+ #[ derive( Clone , Debug ) ]
161+ pub struct MysqlBackend {
162+ core : Arc < MysqlCore > ,
163+ root : String ,
164+ info : Arc < AccessorInfo > ,
167165}
168166
169- impl Adapter {
170- async fn get_client ( & self ) -> Result < & MySqlPool > {
171- self . pool
172- . get_or_try_init ( || async {
173- let pool = MySqlPool :: connect_with ( self . config . clone ( ) )
174- . await
175- . map_err ( parse_mysql_error) ?;
176- Ok ( pool)
177- } )
178- . await
167+ impl MysqlBackend {
168+ pub fn new ( core : MysqlCore ) -> Self {
169+ let info = AccessorInfo :: default ( ) ;
170+ info. set_scheme ( Scheme :: Mysql . into_static ( ) ) ;
171+ info. set_name ( & core. table ) ;
172+ info. set_root ( "/" ) ;
173+ info. set_native_capability ( Capability {
174+ read : true ,
175+ stat : true ,
176+ write : true ,
177+ write_can_empty : true ,
178+ delete : true ,
179+ shared : true ,
180+ ..Default :: default ( )
181+ } ) ;
182+
183+ Self {
184+ core : Arc :: new ( core) ,
185+ root : "/" . to_string ( ) ,
186+ info : Arc :: new ( info) ,
187+ }
179188 }
180- }
181189
182- impl kv:: Adapter for Adapter {
183- type Scanner = ( ) ;
184-
185- fn info ( & self ) -> kv:: Info {
186- kv:: Info :: new (
187- Scheme :: Mysql ,
188- & self . table ,
189- Capability {
190- read : true ,
191- write : true ,
192- delete : true ,
193- shared : true ,
194- ..Default :: default ( )
195- } ,
196- )
190+ fn with_normalized_root ( mut self , root : String ) -> Self {
191+ self . info . set_root ( & root) ;
192+ self . root = root;
193+ self
197194 }
195+ }
198196
199- async fn get ( & self , path : & str ) -> Result < Option < Buffer > > {
200- let pool = self . get_client ( ) . await ?;
201-
202- let value: Option < Vec < u8 > > = sqlx:: query_scalar ( & format ! (
203- "SELECT `{}` FROM `{}` WHERE `{}` = ? LIMIT 1" ,
204- self . value_field, self . table, self . key_field
205- ) )
206- . bind ( path)
207- . fetch_optional ( pool)
208- . await
209- . map_err ( parse_mysql_error) ?;
197+ impl Access for MysqlBackend {
198+ type Reader = Buffer ;
199+ type Writer = MysqlWriter ;
200+ type Lister = ( ) ;
201+ type Deleter = oio:: OneShotDeleter < MysqlDeleter > ;
210202
211- Ok ( value. map ( Buffer :: from) )
203+ fn info ( & self ) -> Arc < AccessorInfo > {
204+ self . info . clone ( )
212205 }
213206
214- async fn set ( & self , path : & str , value : Buffer ) -> Result < ( ) > {
215- let pool = self . get_client ( ) . await ? ;
207+ async fn stat ( & self , path : & str , _ : OpStat ) -> Result < RpStat > {
208+ let p = build_abs_path ( & self . root , path ) ;
216209
217- sqlx:: query ( & format ! (
218- r#"INSERT INTO `{}` (`{}`, `{}`) VALUES (?, ?)
219- ON DUPLICATE KEY UPDATE `{}` = VALUES({})"# ,
220- self . table, self . key_field, self . value_field, self . value_field, self . value_field
221- ) )
222- . bind ( path)
223- . bind ( value. to_vec ( ) )
224- . execute ( pool)
225- . await
226- . map_err ( parse_mysql_error) ?;
210+ if p == build_abs_path ( & self . root , "" ) {
211+ Ok ( RpStat :: new ( Metadata :: new ( EntryMode :: DIR ) ) )
212+ } else {
213+ let bs = self . core . get ( & p) . await ?;
214+ match bs {
215+ Some ( bs) => Ok ( RpStat :: new (
216+ Metadata :: new ( EntryMode :: FILE ) . with_content_length ( bs. len ( ) as u64 ) ,
217+ ) ) ,
218+ None => Err ( Error :: new ( ErrorKind :: NotFound , "kv not found in mysql" ) ) ,
219+ }
220+ }
221+ }
227222
228- Ok ( ( ) )
223+ async fn read ( & self , path : & str , args : OpRead ) -> Result < ( RpRead , Self :: Reader ) > {
224+ let p = build_abs_path ( & self . root , path) ;
225+ let bs = match self . core . get ( & p) . await ? {
226+ Some ( bs) => bs,
227+ None => return Err ( Error :: new ( ErrorKind :: NotFound , "kv not found in mysql" ) ) ,
228+ } ;
229+ Ok ( ( RpRead :: new ( ) , bs. slice ( args. range ( ) . to_range_as_usize ( ) ) ) )
229230 }
230231
231- async fn delete ( & self , path : & str ) -> Result < ( ) > {
232- let pool = self . get_client ( ) . await ?;
232+ async fn write ( & self , path : & str , _: OpWrite ) -> Result < ( RpWrite , Self :: Writer ) > {
233+ let p = build_abs_path ( & self . root , path) ;
234+ Ok ( ( RpWrite :: new ( ) , MysqlWriter :: new ( self . core . clone ( ) , p) ) )
235+ }
233236
234- sqlx:: query ( & format ! (
235- "DELETE FROM `{}` WHERE `{}` = ?" ,
236- self . table, self . key_field
237+ async fn delete ( & self ) -> Result < ( RpDelete , Self :: Deleter ) > {
238+ Ok ( (
239+ RpDelete :: default ( ) ,
240+ oio:: OneShotDeleter :: new ( MysqlDeleter :: new ( self . core . clone ( ) , self . root . clone ( ) ) ) ,
237241 ) )
238- . bind ( path)
239- . execute ( pool)
240- . await
241- . map_err ( parse_mysql_error) ?;
242-
243- Ok ( ( ) )
244242 }
245- }
246243
247- fn parse_mysql_error ( err : sqlx:: Error ) -> Error {
248- Error :: new ( ErrorKind :: Unexpected , "unhandled error from mysql" ) . set_source ( err)
244+ async fn list ( & self , path : & str , _: OpList ) -> Result < ( RpList , Self :: Lister ) > {
245+ let _ = build_abs_path ( & self . root , path) ;
246+ Ok ( ( RpList :: default ( ) , ( ) ) )
247+ }
249248}
0 commit comments