feat(mongo): add GridFS manager for MongoDB
* feat(mongo): browse GridFS buckets and files Refs #2342 * feat(mongo): add GridFS manager for MongoDB * chore(i18n): autofill new translations --------- Co-authored-by: dbx-i18n-bot <github-actions[bot]@users.noreply.github.com> Co-authored-by: t8y2 <1156263951@qq.com>
This commit is contained in:
35 files changed
+1959
-39
No files matched your search
@@ -449,6 +449,13 @@ async fn main() {
|
||||
.route("/document-store/list-databases", post(routes::document_store::list_databases))
|
||||
.route("/document-store/list-collections", post(routes::document_store::list_collections))
|
||||
.route("/document-store/find-documents", post(routes::document_store::find_documents))
|
||||
.route("/document-store/list-gridfs-buckets", post(routes::document_store::list_gridfs_buckets))
|
||||
.route("/document-store/create-gridfs-bucket", post(routes::document_store::create_gridfs_bucket))
|
||||
.route("/document-store/delete-gridfs-bucket", post(routes::document_store::delete_gridfs_bucket))
|
||||
.route("/document-store/list-gridfs-files", post(routes::document_store::list_gridfs_files))
|
||||
.route("/document-store/download-gridfs-file", post(routes::document_store::download_gridfs_file))
|
||||
.route("/document-store/upload-gridfs-file", post(routes::document_store::upload_gridfs_file))
|
||||
.route("/document-store/delete-gridfs-file", post(routes::document_store::delete_gridfs_file))
|
||||
.route("/document-store/insert-document", post(routes::document_store::insert_document))
|
||||
.route("/document-store/update-document", post(routes::document_store::update_document))
|
||||
.route("/document-store/delete-document", post(routes::document_store::delete_document))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::extract::State;
|
||||
use axum::extract::{Multipart, State};
|
||||
use axum::Json;
|
||||
use serde::Deserialize;
|
||||
|
||||
@@ -99,6 +99,32 @@ pub struct DocumentDeleteRequest {
|
||||
pub routing: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GridFsBucketRequest {
|
||||
pub connection_id: String,
|
||||
pub database: String,
|
||||
pub bucket: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GridFsDownloadRequest {
|
||||
pub connection_id: String,
|
||||
pub database: String,
|
||||
pub bucket: String,
|
||||
pub file_id: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GridFsFileDeleteRequest {
|
||||
pub connection_id: String,
|
||||
pub database: String,
|
||||
pub bucket: String,
|
||||
pub file_id: String,
|
||||
}
|
||||
|
||||
pub async fn list_databases(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<DocumentListDatabasesRequest>,
|
||||
@@ -193,3 +219,134 @@ pub async fn delete_document(
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
pub async fn list_gridfs_files(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<GridFsBucketRequest>,
|
||||
) -> Result<Json<Vec<dbx_core::document_ops::MongoGridFsFileInfo>>, AppError> {
|
||||
let result =
|
||||
dbx_core::document_ops::list_gridfs_files_core(&state.app, &req.connection_id, &req.database, &req.bucket)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
pub async fn list_gridfs_buckets(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<DocumentListCollectionsRequest>,
|
||||
) -> Result<Json<Vec<dbx_core::document_ops::MongoGridFsBucketInfo>>, AppError> {
|
||||
let result = dbx_core::document_ops::list_gridfs_buckets_core(&state.app, &req.connection_id, &req.database)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
pub async fn create_gridfs_bucket(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<GridFsBucketRequest>,
|
||||
) -> Result<Json<()>, AppError> {
|
||||
ensure_writable(&state.app, &req.connection_id, "Create GridFS bucket").await?;
|
||||
dbx_core::document_ops::create_gridfs_bucket_core(&state.app, &req.connection_id, &req.database, &req.bucket)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(()))
|
||||
}
|
||||
|
||||
pub async fn delete_gridfs_bucket(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<GridFsBucketRequest>,
|
||||
) -> Result<Json<()>, AppError> {
|
||||
ensure_writable(&state.app, &req.connection_id, "Delete GridFS bucket").await?;
|
||||
dbx_core::document_ops::delete_gridfs_bucket_core(&state.app, &req.connection_id, &req.database, &req.bucket)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(()))
|
||||
}
|
||||
|
||||
pub async fn download_gridfs_file(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<GridFsDownloadRequest>,
|
||||
) -> Result<Json<Vec<u8>>, AppError> {
|
||||
let result = dbx_core::document_ops::download_gridfs_file_core(
|
||||
&state.app,
|
||||
&req.connection_id,
|
||||
&req.database,
|
||||
&req.bucket,
|
||||
&req.file_id,
|
||||
)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
pub async fn upload_gridfs_file(
|
||||
State(state): State<Arc<WebState>>,
|
||||
mut multipart: Multipart,
|
||||
) -> Result<Json<String>, AppError> {
|
||||
let mut connection_id: Option<String> = None;
|
||||
let mut database: Option<String> = None;
|
||||
let mut bucket: Option<String> = None;
|
||||
let mut file_name: Option<String> = None;
|
||||
let mut content_type: Option<String> = None;
|
||||
let mut file_bytes: Option<Vec<u8>> = None;
|
||||
|
||||
while let Some(field) = multipart.next_field().await.map_err(|e| AppError(e.to_string()))? {
|
||||
let name = field.name().unwrap_or_default().to_string();
|
||||
match name.as_str() {
|
||||
"connectionId" => connection_id = Some(field.text().await.map_err(|e| AppError(e.to_string()))?),
|
||||
"database" => database = Some(field.text().await.map_err(|e| AppError(e.to_string()))?),
|
||||
"bucket" => bucket = Some(field.text().await.map_err(|e| AppError(e.to_string()))?),
|
||||
"fileName" => file_name = Some(field.text().await.map_err(|e| AppError(e.to_string()))?),
|
||||
"contentType" => content_type = Some(field.text().await.map_err(|e| AppError(e.to_string()))?),
|
||||
"file" => {
|
||||
if file_name.is_none() {
|
||||
file_name = field.file_name().map(str::to_string);
|
||||
}
|
||||
if content_type.is_none() {
|
||||
content_type = field.content_type().map(str::to_string);
|
||||
}
|
||||
file_bytes = Some(field.bytes().await.map_err(|e| AppError(e.to_string()))?.to_vec());
|
||||
}
|
||||
_ => {
|
||||
let _ = field.bytes().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let connection_id = connection_id.ok_or_else(|| AppError("Missing connectionId".to_string()))?;
|
||||
let database = database.ok_or_else(|| AppError("Missing database".to_string()))?;
|
||||
let bucket = bucket.ok_or_else(|| AppError("Missing bucket".to_string()))?;
|
||||
let file_name = file_name.ok_or_else(|| AppError("Missing fileName".to_string()))?;
|
||||
let file_bytes = file_bytes.ok_or_else(|| AppError("No file uploaded".to_string()))?;
|
||||
|
||||
ensure_writable(&state.app, &connection_id, "Upload GridFS file").await?;
|
||||
let result = dbx_core::document_ops::upload_gridfs_file_core(
|
||||
&state.app,
|
||||
&connection_id,
|
||||
&database,
|
||||
&bucket,
|
||||
&file_name,
|
||||
&file_bytes,
|
||||
content_type.as_deref(),
|
||||
)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
pub async fn delete_gridfs_file(
|
||||
State(state): State<Arc<WebState>>,
|
||||
Json(req): Json<GridFsFileDeleteRequest>,
|
||||
) -> Result<Json<()>, AppError> {
|
||||
ensure_writable(&state.app, &req.connection_id, "Delete GridFS file").await?;
|
||||
dbx_core::document_ops::delete_gridfs_file_core(
|
||||
&state.app,
|
||||
&req.connection_id,
|
||||
&req.database,
|
||||
&req.bucket,
|
||||
&req.file_id,
|
||||
)
|
||||
.await
|
||||
.map_err(AppError)?;
|
||||
Ok(Json(()))
|
||||
}
|
||||
Reference in new issue
Block a user