This is an automated email from the ASF dual-hosted git repository.
xyji 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 64b61c7c6 Add opendal_metadata_last_modified and
opendal_operator_create_dir (#3515)
64b61c7c6 is described below
commit 64b61c7c657932596e9e23dc0a31d699e37faba5
Author: Enwei Jiao <[email protected]>
AuthorDate: Wed Nov 8 06:07:43 2023 +0800
Add opendal_metadata_last_modified and opendal_operator_create_dir (#3515)
* Add opendal_metadata_last_modified and opendal_operator_create_dir for C
binding
* Fix comments
* Make clippy happy
---
bindings/c/include/opendal.h | 53 ++++++++++++++++++++++++++++++++++++++++++++
bindings/c/src/metadata.rs | 20 +++++++++++++++++
bindings/c/src/operator.rs | 50 +++++++++++++++++++++++++++++++++++++++++
bindings/c/tests/bdd.cpp | 15 +++++++++++++
4 files changed, 138 insertions(+)
diff --git a/bindings/c/include/opendal.h b/bindings/c/include/opendal.h
index 55586cd83..5d9962518 100644
--- a/bindings/c/include/opendal.h
+++ b/bindings/c/include/opendal.h
@@ -772,6 +772,21 @@ bool opendal_metadata_is_file(const struct
opendal_metadata *self);
*/
bool opendal_metadata_is_dir(const struct opendal_metadata *self);
+/**
+ * \brief Return the last_modified of the metadata, in milliseconds
+ *
+ * # Example
+ * ```C
+ * // ... previously you wrote "Hello, World!" to path "/testpath"
+ * opendal_result_stat s = opendal_operator_stat(ptr, "/testpath");
+ * assert(s.error == NULL);
+ *
+ * opendal_metadata *meta = s.meta;
+ * assert(opendal_metadata_last_modified_ms(meta) != -1);
+ * ```
+ */
+int64_t opendal_metadata_last_modified_ms(const struct opendal_metadata *self);
+
/**
* \brief Free the heap-allocated operator pointed by opendal_operator.
*
@@ -1149,6 +1164,44 @@ struct opendal_result_stat opendal_operator_stat(const
struct opendal_operator *
struct opendal_result_list opendal_operator_list(const struct opendal_operator
*op,
const char *path);
+/**
+ * \brief Blockingly create the directory in `path`.
+ *
+ * Create the directory in `path` blockingly by `op_ptr`.
+ * Error is NULL if successful, otherwise it contains the error code and error
message.
+ *
+ * @param ptr The opendal_operator created previously
+ * @param path The designated directory you want to create
+ * @see opendal_operator
+ * @see opendal_error
+ * @return NULL if succeeds, otherwise it contains the error code and error
message.
+ *
+ * # Example
+ *
+ * Following is an example
+ * ```C
+ * //...prepare your opendal_operator, named ptr for example
+ *
+ * // create your directory
+ * opendal_error *error = opendal_operator_create_dir(ptr, "/testdir/");
+ *
+ * // Assert that this succeeds
+ * assert(error == NULL);
+ * ```
+ *
+ * # Safety
+ *
+ * It is **safe** under the cases below
+ * * The memory pointed to by `path` must contain a valid nul terminator at
the end of
+ * the string.
+ *
+ * # Panic
+ *
+ * * If the `path` points to NULL, this function panics, i.e. exits with
information
+ */
+struct opendal_error *opendal_operator_create_dir(const struct
opendal_operator *op,
+ const char *path);
+
/**
* \brief Get information of underlying accessor.
*
diff --git a/bindings/c/src/metadata.rs b/bindings/c/src/metadata.rs
index a28d72d7b..1e532e3de 100644
--- a/bindings/c/src/metadata.rs
+++ b/bindings/c/src/metadata.rs
@@ -111,4 +111,24 @@ impl opendal_metadata {
// The use-after-free is undefined behavior
unsafe { (*self.inner).is_dir() }
}
+
+ /// \brief Return the last_modified of the metadata, in milliseconds
+ ///
+ /// # Example
+ /// ```C
+ /// // ... previously you wrote "Hello, World!" to path "/testpath"
+ /// opendal_result_stat s = opendal_operator_stat(ptr, "/testpath");
+ /// assert(s.error == NULL);
+ ///
+ /// opendal_metadata *meta = s.meta;
+ /// assert(opendal_metadata_last_modified_ms(meta) != -1);
+ /// ```
+ #[no_mangle]
+ pub extern "C" fn opendal_metadata_last_modified_ms(&self) -> i64 {
+ let mtime = unsafe { (*self.inner).last_modified() };
+ match mtime {
+ None => -1,
+ Some(time) => time.timestamp_millis(),
+ }
+ }
}
diff --git a/bindings/c/src/operator.rs b/bindings/c/src/operator.rs
index 4f6406236..2fc102229 100644
--- a/bindings/c/src/operator.rs
+++ b/bindings/c/src/operator.rs
@@ -628,3 +628,53 @@ pub unsafe extern "C" fn opendal_operator_list(
},
}
}
+
+/// \brief Blockingly create the directory in `path`.
+///
+/// Create the directory in `path` blockingly by `op_ptr`.
+/// Error is NULL if successful, otherwise it contains the error code and
error message.
+///
+/// @param ptr The opendal_operator created previously
+/// @param path The designated directory you want to create
+/// @see opendal_operator
+/// @see opendal_error
+/// @return NULL if succeeds, otherwise it contains the error code and error
message.
+///
+/// # Example
+///
+/// Following is an example
+/// ```C
+/// //...prepare your opendal_operator, named ptr for example
+///
+/// // create your directory
+/// opendal_error *error = opendal_operator_create_dir(ptr, "/testdir/");
+///
+/// // Assert that this succeeds
+/// assert(error == NULL);
+/// ```
+///
+/// # Safety
+///
+/// It is **safe** under the cases below
+/// * The memory pointed to by `path` must contain a valid nul terminator at
the end of
+/// the string.
+///
+/// # Panic
+///
+/// * If the `path` points to NULL, this function panics, i.e. exits with
information
+#[no_mangle]
+pub unsafe extern "C" fn opendal_operator_create_dir(
+ op: *const opendal_operator,
+ path: *const c_char,
+) -> *mut opendal_error {
+ if path.is_null() {
+ panic!("The path given is pointing at NULL");
+ }
+
+ let op = (*op).as_ref();
+ let path = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() };
+ match op.create_dir(path) {
+ Ok(_) => std::ptr::null_mut(),
+ Err(e) => opendal_error::new(e),
+ }
+}
diff --git a/bindings/c/tests/bdd.cpp b/bindings/c/tests/bdd.cpp
index fd33a0125..ee307cc19 100644
--- a/bindings/c/tests/bdd.cpp
+++ b/bindings/c/tests/bdd.cpp
@@ -77,8 +77,12 @@ TEST_F(OpendalBddTest, FeatureTest)
// The blocking file "test" content length must be 13
EXPECT_EQ(opendal_metadata_content_length(meta), 13);
+
+ // the blocking file "test" last modified time must not be -1
+ EXPECT_FALSE(opendal_metadata_last_modified_ms(meta) != -1);
opendal_metadata_free(meta);
+
// The blocking file "test" must have content "Hello, World!"
struct opendal_result_read r = opendal_operator_read(this->p,
this->path.c_str());
EXPECT_EQ(r.error, nullptr);
@@ -111,6 +115,17 @@ TEST_F(OpendalBddTest, FeatureTest)
EXPECT_EQ(error, nullptr);
opendal_bytes_free(r.data);
+
+ // The directory "tmpdir/" should exist and should be a directory
+ error = opendal_operator_create_dir(this->p, "tmpdir/");
+ EXPECT_EQ(error, nullptr);
+ auto stat = opendal_operator_stat(this->p, "tmpdir/");
+ EXPECT_EQ(stat.error, nullptr);
+ EXPECT_TRUE(opendal_metadata_is_dir(stat.meta));
+ EXPECT_FALSE(opendal_metadata_is_file(stat.meta));
+ opendal_metadata_free(stat.meta);
+ error = opendal_operator_delete(this->p, "tmpdir/");
+ EXPECT_EQ(error, nullptr);
}
int main(int argc, char** argv)