This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 9cce4d31 feat(services/sftp): support copy and rename for sftp (#2263)
9cce4d31 is described below
commit 9cce4d31418567ed2fc8e7178f11a48ac9cbdede
Author: silver-ymz <[email protected]>
AuthorDate: Wed May 17 16:01:26 2023 +0800
feat(services/sftp): support copy and rename for sftp (#2263)
* feat(services/sftp): support copy and rename for sftp
Signed-off-by: silver-ymz <[email protected]>
* change copy and rename to partially support
Signed-off-by: silver-ymz <[email protected]>
* rename create dir for destination
Signed-off-by: silver-ymz <[email protected]>
* remove explanation of partial support
Signed-off-by: silver-ymz <[email protected]>
* remove read_can_seek
Signed-off-by: silver-ymz <[email protected]>
---------
Signed-off-by: silver-ymz <[email protected]>
---
core/Cargo.toml | 7 +-----
core/src/services/sftp/backend.rs | 49 ++++++++++++++++++++++++++++++++-------
2 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 3817a64b..6d1f0e99 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -135,12 +135,7 @@ services-s3 = [
"reqsign?/services-aws",
"reqsign?/reqwest_request",
]
-services-sftp = [
- "dep:openssh",
- "dep:openssh-sftp-client",
- "dep:dirs",
- "futures/executor",
-]
+services-sftp = ["dep:openssh", "dep:openssh-sftp-client", "dep:dirs"]
services-sled = ["dep:sled"]
services-supabase = []
services-vercel-artifacts = []
diff --git a/core/src/services/sftp/backend.rs
b/core/src/services/sftp/backend.rs
index 8f9b7be0..08c9d2cb 100644
--- a/core/src/services/sftp/backend.rs
+++ b/core/src/services/sftp/backend.rs
@@ -56,7 +56,7 @@ use crate::*;
/// - [x] create_dir
/// - [x] delete
/// - [ ] copy
-/// - [ ] rename
+/// - [x] rename
/// - [x] list
/// - [ ] ~~scan~~
/// - [ ] ~~presign~~
@@ -277,8 +277,10 @@ impl Accessor for SftpBackend {
stat: true,
read: true,
+ read_with_range: true,
write: true,
+ write_without_content_length: true,
create_dir: true,
delete: true,
@@ -286,6 +288,8 @@ impl Accessor for SftpBackend {
list_with_limit: true,
list_with_delimiter_slash: true,
+ rename: true,
+
..Default::default()
});
@@ -353,14 +357,7 @@ impl Accessor for SftpBackend {
Ok((RpRead::new(end - start), r))
}
- async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite,
Self::Writer)> {
- if args.content_length().is_none() {
- return Err(Error::new(
- ErrorKind::Unsupported,
- "write without content length is not supported",
- ));
- }
-
+ async fn write(&self, path: &str, _: OpWrite) -> Result<(RpWrite,
Self::Writer)> {
if let Some((dir, _)) = path.rsplit_once('/') {
self.create_dir(dir, OpCreateDir::default()).await?;
}
@@ -376,6 +373,40 @@ impl Accessor for SftpBackend {
Ok((RpWrite::new(), SftpWriter::new(file)))
}
+ async fn copy(&self, from: &str, to: &str, _: OpCopy) -> Result<RpCopy> {
+ let client = self.connect().await?;
+
+ let mut fs = client.fs();
+ fs.set_cwd(&self.root);
+
+ if let Some((dir, _)) = to.rsplit_once('/') {
+ self.create_dir(dir, OpCreateDir::default()).await?;
+ }
+
+ let src = fs.canonicalize(from).await?;
+ let dst = fs.canonicalize(to).await?;
+ let mut src_file = client.open(&src).await?;
+ let mut dst_file = client.create(dst).await?;
+
+ src_file.copy_all_to(&mut dst_file).await?;
+
+ Ok(RpCopy::default())
+ }
+
+ async fn rename(&self, from: &str, to: &str, _: OpRename) ->
Result<RpRename> {
+ let client = self.connect().await?;
+
+ let mut fs = client.fs();
+ fs.set_cwd(&self.root);
+
+ if let Some((dir, _)) = to.rsplit_once('/') {
+ self.create_dir(dir, OpCreateDir::default()).await?;
+ }
+ fs.rename(from, to).await?;
+
+ Ok(RpRename::default())
+ }
+
async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> {
let client = self.connect().await?;
let mut fs = client.fs();