From 475cc11dcfb245a62a6115d1234bef8965009711 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Sun, 16 Apr 2023 11:44:07 +0800 Subject: [PATCH 1/5] docs: Add OpenDAL VISION Signed-off-by: Xuanwo --- .asf.yaml | 2 +- bindings/c/include/opendal.h | 160 ++++++++++++++++----------------- core/README.md | 2 +- core/src/lib.rs | 2 +- website/docs/index.md | 76 ++++++++++++++++ website/docs/overview.md | 4 - website/{ => docs}/sidebars.js | 27 +----- website/docs/vision.md | 54 +++++++++++ website/docusaurus.config.js | 6 +- 9 files changed, 218 insertions(+), 115 deletions(-) create mode 100644 website/docs/index.md delete mode 100644 website/docs/overview.md rename website/{ => docs}/sidebars.js (59%) create mode 100644 website/docs/vision.md diff --git a/.asf.yaml b/.asf.yaml index c6ff7d558325..730f0b352f4e 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -17,7 +17,7 @@ # NOTE: All configurations could be found here: https://cwiki.apache.org/confluence/display/INFRA/Git+-+.asf.yaml+features github: - description: "Apache OpenDAL: Access data freely, painlessly, and efficiently." + description: "Apache OpenDAL: access data freely." homepage: https://opendal.apache.org labels: - rust diff --git a/bindings/c/include/opendal.h b/bindings/c/include/opendal.h index e177cb71c1eb..f4ad4704f6ed 100644 --- a/bindings/c/include/opendal.h +++ b/bindings/c/include/opendal.h @@ -17,66 +17,66 @@ * under the License. */ + #ifndef _OPENDAL_H #define _OPENDAL_H -#include -#include #include +#include +#include /* The error code for opendal APIs in C binding */ typedef enum opendal_code { - /* - All is well - */ - OPENDAL_OK, - /* - General error - */ - OPENDAL_ERROR, - /* - returning it back. For example, s3 returns an internal service error. - */ - OPENDAL_UNEXPECTED, - /* - Underlying service doesn't support this operation. - */ - OPENDAL_UNSUPPORTED, - /* - The config for backend is invalid. - */ - OPENDAL_CONFIG_INVALID, - /* - The given path is not found. - */ - OPENDAL_NOT_FOUND, - /* - The given path doesn't have enough permission for this operation - */ - OPENDAL_PERMISSION_DENIED, - /* - The given path is a directory. - */ - OPENDAL_IS_A_DIRECTORY, - /* - The given path is not a directory. - */ - OPENDAL_NOT_A_DIRECTORY, - /* - The given path already exists thus we failed to the specified operation on - it. - */ - OPENDAL_ALREADY_EXISTS, - /* - Requests that sent to this path is over the limit, please slow down. - */ - OPENDAL_RATE_LIMITED, - /* - The given file paths are same. - */ - OPENDAL_IS_SAME_FILE, + /* + All is well + */ + OPENDAL_OK, + /* + General error + */ + OPENDAL_ERROR, + /* + returning it back. For example, s3 returns an internal service error. + */ + OPENDAL_UNEXPECTED, + /* + Underlying service doesn't support this operation. + */ + OPENDAL_UNSUPPORTED, + /* + The config for backend is invalid. + */ + OPENDAL_CONFIG_INVALID, + /* + The given path is not found. + */ + OPENDAL_NOT_FOUND, + /* + The given path doesn't have enough permission for this operation + */ + OPENDAL_PERMISSION_DENIED, + /* + The given path is a directory. + */ + OPENDAL_IS_A_DIRECTORY, + /* + The given path is not a directory. + */ + OPENDAL_NOT_A_DIRECTORY, + /* + The given path already exists thus we failed to the specified operation on it. + */ + OPENDAL_ALREADY_EXISTS, + /* + Requests that sent to this path is over the limit, please slow down. + */ + OPENDAL_RATE_LIMITED, + /* + The given file paths are same. + */ + OPENDAL_IS_SAME_FILE, } opendal_code; /* @@ -121,7 +121,7 @@ typedef struct BlockingOperator BlockingOperator; to check its validity by native boolean operator. e.g. you could check by (!ptr) on a [`opendal_operator_ptr`] */ -typedef const struct BlockingOperator* opendal_operator_ptr; +typedef const struct BlockingOperator *opendal_operator_ptr; /* The [`opendal_bytes`] type is a C-compatible substitute for [`Vec`] @@ -130,8 +130,8 @@ typedef const struct BlockingOperator* opendal_operator_ptr; to free the heap memory to avoid memory leak. */ typedef struct opendal_bytes { - const uint8_t* data; - uintptr_t len; + const uint8_t *data; + uintptr_t len; } opendal_bytes; /* @@ -141,8 +141,8 @@ typedef struct opendal_bytes { and the error code is NOT OPENDAL_OK. */ typedef struct opendal_result_read { - struct opendal_bytes* data; - enum opendal_code code; + struct opendal_bytes *data; + enum opendal_code code; } opendal_result_read; /* @@ -151,8 +151,8 @@ typedef struct opendal_result_read { corresponding error code. */ typedef struct opendal_result_is_exist { - bool is_exist; - enum opendal_code code; + bool is_exist; + enum opendal_code code; } opendal_result_is_exist; #ifdef __cplusplus @@ -160,19 +160,17 @@ extern "C" { #endif // __cplusplus /* - Returns a result type [`opendal_result_op`], with operator_ptr. If the - construction succeeds the error is nullptr, otherwise it contains the error - information. + Returns a result type [`opendal_result_op`], with operator_ptr. If the construction succeeds + the error is nullptr, otherwise it contains the error information. # Safety It is [safe] under two cases below - * The memory pointed to by `scheme` must contain a valid nul terminator at the - end of the string. - * The `scheme` points to NULL, this function simply returns you a null - opendal_operator_ptr + * The memory pointed to by `scheme` must contain a valid nul terminator at the end of + the string. + * The `scheme` points to NULL, this function simply returns you a null opendal_operator_ptr */ -opendal_operator_ptr opendal_operator_new(const char* scheme); +opendal_operator_ptr opendal_operator_new(const char *scheme); /* Free the allocated operator pointed by [`opendal_operator_ptr`] @@ -180,22 +178,22 @@ opendal_operator_ptr opendal_operator_new(const char* scheme); void opendal_operator_free(opendal_operator_ptr op_ptr); /* - Write the data into the path blockingly by operator, returns the error code - OPENDAL_OK if succeeds, others otherwise + Write the data into the path blockingly by operator, returns the error code OPENDAL_OK + if succeeds, others otherwise # Safety It is [safe] under two cases below - * The memory pointed to by `path` must contain a valid nul terminator at the - end of the string. + * 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 */ enum opendal_code opendal_operator_blocking_write(opendal_operator_ptr op_ptr, - const char* path, - struct opendal_bytes bytes); + const char *path, + struct opendal_bytes bytes); /* Read the data out from path into a [`Bytes`] blockingly by operator, returns @@ -205,15 +203,15 @@ enum opendal_code opendal_operator_blocking_write(opendal_operator_ptr op_ptr, # Safety It is [safe] under two cases below - * The memory pointed to by `path` must contain a valid nul terminator at the - end of the string. + * 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 */ -struct opendal_result_read opendal_operator_blocking_read( - opendal_operator_ptr op_ptr, const char* path); +struct opendal_result_read opendal_operator_blocking_read(opendal_operator_ptr op_ptr, + const char *path); /* Check whether the path exists. @@ -226,20 +224,20 @@ struct opendal_result_read opendal_operator_blocking_read( # Safety It is [safe] under two cases below - * The memory pointed to by `path` must contain a valid nul terminator at the - end of the string. + * 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 */ -struct opendal_result_is_exist opendal_operator_is_exist( - opendal_operator_ptr op_ptr, const char* path); +struct opendal_result_is_exist opendal_operator_is_exist(opendal_operator_ptr op_ptr, + const char *path); /* Frees the heap memory used by the [`opendal_bytes`] */ -void opendal_bytes_free(const struct opendal_bytes* self); +void opendal_bytes_free(const struct opendal_bytes *self); #ifdef __cplusplus } // extern "C" diff --git a/core/README.md b/core/README.md index 7640e64e30ad..8bbce48e84ea 100644 --- a/core/README.md +++ b/core/README.md @@ -8,7 +8,7 @@ [chat]: https://img.shields.io/discord/1081052318650339399 [discord]: https://discord.gg/XQy8yGR2dg -**Open** **D**ata **A**ccess **L**ayer: Access data freely, painlessly, and efficiently +**Open** **D**ata **A**ccess **L**ayer: access data freely. - Documentation: [stable](https://docs.rs/opendal/) | [main](https://opendal.apache.org/docs/rust/opendal/) - [Release notes](https://docs.rs/opendal/latest/opendal/docs/changelog/index.html) diff --git a/core/src/lib.rs b/core/src/lib.rs index b5df5aea0593..bc361738f3d4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -//! OpenDAL is the Open Data Access Layer to **freely**, **painlessly**, and **efficiently** access data. +//! OpenDAL is the Open Data Access Layer to **freely** access data. //! //! - Documentation: All docs are carried byself, visit [`docs`] for more. //! - Services: All supported services could be found at [`services`]. diff --git a/website/docs/index.md b/website/docs/index.md new file mode 100644 index 000000000000..2d4a32957009 --- /dev/null +++ b/website/docs/index.md @@ -0,0 +1,76 @@ +--- +title: Overview +sidebar_position: 1 +--- + +**Open** **D**ata **A**ccess **L**ayer: Access data freely. + +![](https://user-images.githubusercontent.com/5351546/222356748-14276998-501b-4d2a-9b09-b8cff3018204.png) + +## Quickstart + +### Rust + +```rust +use opendal::Result; +use opendal::layers::LoggingLayer; +use opendal::services; +use opendal::Operator; + +#[tokio::main] +async fn main() -> Result<()> { + // Pick a builder and configure it. + let mut builder = services::S3::default(); + builder.bucket("test"); + + // Init an operator + let op = Operator::new(builder)? + // Init with logging layer enabled. + .layer(LoggingLayer::default()) + .finish(); + + // Write data + op.write("hello.txt", "Hello, World!").await?; + + // Read data + let bs = op.read("hello.txt").await?; + + // Fetch metadata + let meta = op.stat("hello.txt").await?; + let mode = meta.mode(); + let length = meta.content_length(); + + // Delete + op.delete("hello.txt").await?; + + Ok(()) +} +``` + +### Python + +```python +import asyncio + +async def main(): + op = opendal.AsyncOperator("fs", root="/tmp") + await op.write("test.txt", b"Hello World") + print(await op.read("test.txt")) + +asyncio.run(main()) +``` + +### Node.js + +```js +import { Operator } from "opendal"; + +async function main() { + const op = new Operator("fs", { root: "/tmp" }); + await op.write("test", "Hello, World!"); + const bs = await op.read("test"); + console.log(new TextDecoder().decode(bs)); + const meta = await op.stat("test"); + console.log(`contentLength: ${meta.contentLength}`); +} +``` diff --git a/website/docs/overview.md b/website/docs/overview.md deleted file mode 100644 index 42956286a828..000000000000 --- a/website/docs/overview.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -sidebar_position: 1 -title: Overview ---- diff --git a/website/sidebars.js b/website/docs/sidebars.js similarity index 59% rename from website/sidebars.js rename to website/docs/sidebars.js index 850844c264d1..7704508adcea 100644 --- a/website/sidebars.js +++ b/website/docs/sidebars.js @@ -17,36 +17,11 @@ * under the License. */ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - // @ts-check /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { - // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], - */ + docs: [{ type: 'autogenerated', dirName: '.' }], }; module.exports = sidebars; diff --git a/website/docs/vision.md b/website/docs/vision.md new file mode 100644 index 000000000000..babf26518197 --- /dev/null +++ b/website/docs/vision.md @@ -0,0 +1,54 @@ +--- +title: Vision +sidebar_position: 2 +--- + +OpenDAL VISION: **access data freely**. + +### Free from services + +OpenDAL must enable users to access various storage services ranging from `s3` to `dropbox` via it's own native API. It should provide a unified API for accessing all these services. + +- Add support for google drive: Good, it allows users to access and manage their data on the google drive. +- Add support for oss via native API: Good, users can utilize Aliyun's RAM support. +- Add support for [supabase storage](https://supabase.com/docs/guides/storage): Good, users can visit supabase sotrage now! + + +- Add support for gcs via XML API: Bad, gcs has native JSON API which more powerful +- Add support for MySQL/PostgreSQL: Bad, relational DBMS provides data types such as BLOB, but they are often not used as a storage service. + +### Free from implementations + +OpenDAL needs to separate the various implementation details of services and enables users to write identical logic for different services. + +- Add a new capability to indicate whether or not `presign` is supported: Good, users can now write logic based on the `can_presign` option. +- Add a `default_storage_class` configuration for the S3 service: Good, configuration is specific to the s3 service. +- Add an option for `content_type` in the `write` operation: Good, it aligns with HTTP standards. + + +- Add a new option in read for `storage_class`: Bad, as different services could have varying values for this parameter. + +### Free to integrate + +OpenDAL needs to be integrated with different systems. + +- Add python binding: Good, users from `python` can use OpenDAL. +- Add object_store integration: Good, users of `object_store` can adopt OpenDAL. + + +- Rewrite OpenDAL in Golang: Good idea itself, but not related to OpenDAL. + +### Free to zero cost + +OpenDAL needs to implement features in zero cost way which means: + +- Users don't need to pay cost for not used features. +- Users can't write better implementation for used features. + +For examples: + +- Add `layer` support: Good, users can add logging/metrics/tracing in zero cost way. +- Implement `seek` for Reader: Good, users can't write better `seek` support, they all need to pay the same cost. + + +- Add `Arc` for metadata: Bad, users may only need to use metadata once and never clone it. For those who do want this feature, they can add `Arc` themselves diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 29eb75b3b848..680abdb2d501 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -50,7 +50,7 @@ const config = { /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { - sidebarPath: require.resolve('./sidebars.js'), + sidebarPath: require.resolve('./docs/sidebars.js'), editUrl: 'https://github.com/apache/incubator-opendal/website/', showLastUpdateAuthor: true, @@ -90,6 +90,10 @@ const config = { position: 'right', label: 'Documentation', items: [ + { + type: 'html', + value: 'General' + }, { type: 'html', value: 'Rust' From e3cbf28a1e47f9e1efa66e2529815f57be05a5af Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Sun, 16 Apr 2023 11:48:26 +0800 Subject: [PATCH 2/5] Format c binding Signed-off-by: Xuanwo --- bindings/c/include/opendal.h | 127 +++++++++++++++++------------------ 1 file changed, 63 insertions(+), 64 deletions(-) diff --git a/bindings/c/include/opendal.h b/bindings/c/include/opendal.h index f4ad4704f6ed..21d9ba4ec146 100644 --- a/bindings/c/include/opendal.h +++ b/bindings/c/include/opendal.h @@ -17,66 +17,65 @@ * under the License. */ - #ifndef _OPENDAL_H #define _OPENDAL_H -#include -#include #include +#include +#include /* The error code for opendal APIs in C binding */ typedef enum opendal_code { - /* - All is well - */ - OPENDAL_OK, - /* - General error - */ - OPENDAL_ERROR, - /* - returning it back. For example, s3 returns an internal service error. - */ - OPENDAL_UNEXPECTED, - /* - Underlying service doesn't support this operation. - */ - OPENDAL_UNSUPPORTED, - /* - The config for backend is invalid. - */ - OPENDAL_CONFIG_INVALID, - /* - The given path is not found. - */ - OPENDAL_NOT_FOUND, - /* - The given path doesn't have enough permission for this operation - */ - OPENDAL_PERMISSION_DENIED, - /* - The given path is a directory. - */ - OPENDAL_IS_A_DIRECTORY, - /* - The given path is not a directory. - */ - OPENDAL_NOT_A_DIRECTORY, - /* - The given path already exists thus we failed to the specified operation on it. - */ - OPENDAL_ALREADY_EXISTS, - /* - Requests that sent to this path is over the limit, please slow down. - */ - OPENDAL_RATE_LIMITED, - /* - The given file paths are same. - */ - OPENDAL_IS_SAME_FILE, + /* + All is well + */ + OPENDAL_OK, + /* + General error + */ + OPENDAL_ERROR, + /* + returning it back. For example, s3 returns an internal service error. + */ + OPENDAL_UNEXPECTED, + /* + Underlying service doesn't support this operation. + */ + OPENDAL_UNSUPPORTED, + /* + The config for backend is invalid. + */ + OPENDAL_CONFIG_INVALID, + /* + The given path is not found. + */ + OPENDAL_NOT_FOUND, + /* + The given path doesn't have enough permission for this operation + */ + OPENDAL_PERMISSION_DENIED, + /* + The given path is a directory. + */ + OPENDAL_IS_A_DIRECTORY, + /* + The given path is not a directory. + */ + OPENDAL_NOT_A_DIRECTORY, + /* + The given path already exists thus we failed to the specified operation on it. + */ + OPENDAL_ALREADY_EXISTS, + /* + Requests that sent to this path is over the limit, please slow down. + */ + OPENDAL_RATE_LIMITED, + /* + The given file paths are same. + */ + OPENDAL_IS_SAME_FILE, } opendal_code; /* @@ -121,7 +120,7 @@ typedef struct BlockingOperator BlockingOperator; to check its validity by native boolean operator. e.g. you could check by (!ptr) on a [`opendal_operator_ptr`] */ -typedef const struct BlockingOperator *opendal_operator_ptr; +typedef const struct BlockingOperator* opendal_operator_ptr; /* The [`opendal_bytes`] type is a C-compatible substitute for [`Vec`] @@ -130,8 +129,8 @@ typedef const struct BlockingOperator *opendal_operator_ptr; to free the heap memory to avoid memory leak. */ typedef struct opendal_bytes { - const uint8_t *data; - uintptr_t len; + const uint8_t* data; + uintptr_t len; } opendal_bytes; /* @@ -141,8 +140,8 @@ typedef struct opendal_bytes { and the error code is NOT OPENDAL_OK. */ typedef struct opendal_result_read { - struct opendal_bytes *data; - enum opendal_code code; + struct opendal_bytes* data; + enum opendal_code code; } opendal_result_read; /* @@ -151,8 +150,8 @@ typedef struct opendal_result_read { corresponding error code. */ typedef struct opendal_result_is_exist { - bool is_exist; - enum opendal_code code; + bool is_exist; + enum opendal_code code; } opendal_result_is_exist; #ifdef __cplusplus @@ -170,7 +169,7 @@ extern "C" { the string. * The `scheme` points to NULL, this function simply returns you a null opendal_operator_ptr */ -opendal_operator_ptr opendal_operator_new(const char *scheme); +opendal_operator_ptr opendal_operator_new(const char* scheme); /* Free the allocated operator pointed by [`opendal_operator_ptr`] @@ -192,8 +191,8 @@ void opendal_operator_free(opendal_operator_ptr op_ptr); * If the `path` points to NULL, this function panics */ enum opendal_code opendal_operator_blocking_write(opendal_operator_ptr op_ptr, - const char *path, - struct opendal_bytes bytes); + const char* path, + struct opendal_bytes bytes); /* Read the data out from path into a [`Bytes`] blockingly by operator, returns @@ -211,7 +210,7 @@ enum opendal_code opendal_operator_blocking_write(opendal_operator_ptr op_ptr, * If the `path` points to NULL, this function panics */ struct opendal_result_read opendal_operator_blocking_read(opendal_operator_ptr op_ptr, - const char *path); + const char* path); /* Check whether the path exists. @@ -232,12 +231,12 @@ struct opendal_result_read opendal_operator_blocking_read(opendal_operator_ptr o * If the `path` points to NULL, this function panics */ struct opendal_result_is_exist opendal_operator_is_exist(opendal_operator_ptr op_ptr, - const char *path); + const char* path); /* Frees the heap memory used by the [`opendal_bytes`] */ -void opendal_bytes_free(const struct opendal_bytes *self); +void opendal_bytes_free(const struct opendal_bytes* self); #ifdef __cplusplus } // extern "C" From 9871f69a53806bfe851fca004aa8ea493191ebac Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Sun, 16 Apr 2023 11:55:16 +0800 Subject: [PATCH 3/5] Make sure binding been formated Signed-off-by: Xuanwo --- bindings/c/build.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bindings/c/build.rs b/bindings/c/build.rs index 47b27812a6d5..e5b01158f589 100644 --- a/bindings/c/build.rs +++ b/bindings/c/build.rs @@ -17,7 +17,7 @@ extern crate cbindgen; -use std::path::Path; +use std::{path::Path, process::Command}; fn main() { let header_file = Path::new("include").join("opendal.h"); @@ -25,4 +25,12 @@ fn main() { cbindgen::generate(".") .expect("Unable to generate bindings") .write_to_file(header_file); + + Command::new("clang-format") + .arg("--style=WebKit") + .arg("--verbose") + .arg("-i") + .arg("include/opendal.h") + .spawn() + .expect("clang-format must succeed"); } From 78f479d1dfa5fe3702f22d2418f941cf3ad7da8e Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Sun, 16 Apr 2023 11:55:53 +0800 Subject: [PATCH 4/5] FIx docs Signed-off-by: Xuanwo --- website/docs/vision.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/vision.md b/website/docs/vision.md index babf26518197..4d649400d154 100644 --- a/website/docs/vision.md +++ b/website/docs/vision.md @@ -11,7 +11,7 @@ OpenDAL must enable users to access various storage services ranging from `s3` t - Add support for google drive: Good, it allows users to access and manage their data on the google drive. - Add support for oss via native API: Good, users can utilize Aliyun's RAM support. -- Add support for [supabase storage](https://supabase.com/docs/guides/storage): Good, users can visit supabase sotrage now! +- Add support for [supabase storage](https://supabase.com/docs/guides/storage): Good, users can visit supabase storage now! - Add support for gcs via XML API: Bad, gcs has native JSON API which more powerful From a0855654a320fe0bb77cdc869e9a627570f1a409 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Sun, 16 Apr 2023 18:22:05 +0800 Subject: [PATCH 5/5] polish Signed-off-by: Xuanwo --- website/docs/vision.md | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/website/docs/vision.md b/website/docs/vision.md index 4d649400d154..dab6e36e17ea 100644 --- a/website/docs/vision.md +++ b/website/docs/vision.md @@ -3,24 +3,32 @@ title: Vision sidebar_position: 2 --- -OpenDAL VISION: **access data freely**. +OpenDAL VISION is: **access data freely**. -### Free from services +--- + +This is an overview of what the shape of OpenDAL looks like, but also somewhat zoomed out, so that the vision can survive while the exact minute details might shift and change over time. + +## 1. Free from services OpenDAL must enable users to access various storage services ranging from `s3` to `dropbox` via it's own native API. It should provide a unified API for accessing all these services. -- Add support for google drive: Good, it allows users to access and manage their data on the google drive. +### Examples + +- Add support for [Google Drive](https://www.google.com/drive/): Good, it allows users to access and manage their data on the [Google Drive](https://www.google.com/drive/). - Add support for oss via native API: Good, users can utilize Aliyun's RAM support. - Add support for [supabase storage](https://supabase.com/docs/guides/storage): Good, users can visit supabase storage now! -- Add support for gcs via XML API: Bad, gcs has native JSON API which more powerful +- Add support for [GCS](https://cloud.google.com/storage) via [XML API](https://cloud.google.com/storage/docs/xml-api/overview): Bad, [GCS](https://cloud.google.com/storage) has native [JSON API](https://cloud.google.com/storage/docs/json_api) which more powerful - Add support for MySQL/PostgreSQL: Bad, relational DBMS provides data types such as BLOB, but they are often not used as a storage service. -### Free from implementations +## 2. Free from implementations OpenDAL needs to separate the various implementation details of services and enables users to write identical logic for different services. +### Examples + - Add a new capability to indicate whether or not `presign` is supported: Good, users can now write logic based on the `can_presign` option. - Add a `default_storage_class` configuration for the S3 service: Good, configuration is specific to the s3 service. - Add an option for `content_type` in the `write` operation: Good, it aligns with HTTP standards. @@ -28,24 +36,23 @@ OpenDAL needs to separate the various implementation details of services and ena - Add a new option in read for `storage_class`: Bad, as different services could have varying values for this parameter. -### Free to integrate +## 3. Free to integrate OpenDAL needs to be integrated with different systems. +### Examples + - Add python binding: Good, users from `python` can use OpenDAL. - Add object_store integration: Good, users of `object_store` can adopt OpenDAL. - -- Rewrite OpenDAL in Golang: Good idea itself, but not related to OpenDAL. - -### Free to zero cost +## 4. Free to zero cost OpenDAL needs to implement features in zero cost way which means: - Users don't need to pay cost for not used features. - Users can't write better implementation for used features. -For examples: +### Examples - Add `layer` support: Good, users can add logging/metrics/tracing in zero cost way. - Implement `seek` for Reader: Good, users can't write better `seek` support, they all need to pay the same cost.