Skip to content

Commit c258185

Browse files
committed
snapshot
1 parent 5db9971 commit c258185

24 files changed

Lines changed: 429 additions & 384 deletions

File tree

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README_cn.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,5 @@ WHERE fg.file_id = 'specified_file_id';
127127
4. **用户权限管理**:如果系统对多用户开放,需要考虑用户权限管理,确保用户只能访问和操作自己的文件。
128128
5. **文件版本控制**:可以增加版本控制功能,记录文件的修改历史。
129129
6. **文件搜索优化**:除了标签搜索,还可以实现基于文件内容的全文搜索,提高搜索的准确性。
130+
7. **多种数据库兼容**:由于某些数据库不支持returning子句,所以若要兼容这个需要抛弃一旦插入就能直接返回对象的想法。
131+
8. **支持批量操作**

file_classification_cli/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ doc = false
1515
name = "list_files_by_conditions"
1616
doc = false
1717

18-
[[bin]]
19-
name = "create_file"
20-
doc = false
21-
2218
[[bin]]
2319
name = "delete_file"
2420
doc = false

file_classification_cli/src/bin/create_file.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.

file_classification_cli/src/bin/delete_group_tag.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use file_classification_core::service::group_tag::delete_group_tag;
1+
use file_classification_core::service::group_tag::delete_group_tag_by_id;
22
use file_classification_core::utils::database::establish_connection;
33
use std::io::{stdin, stdout, Write};
44
use file_classification_core::model::models::GroupTagDTO;
@@ -19,7 +19,7 @@ fn main() {
1919
stdin().read_line(&mut tag_id_input).unwrap();
2020
let tag_id: i32 = tag_id_input.trim().parse().expect("Invalid Tag ID");
2121

22-
let result = delete_group_tag(connection, GroupTagDTO{group_id, tag_id});
22+
let result = delete_group_tag_by_id(connection, GroupTagDTO{group_id, tag_id});
2323
match result {
2424
Ok(deleted_group_tag_num) => {
2525
if deleted_group_tag_num == 0 {
Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,27 @@
1-
use super::{models::FileGroupDTO, AppError};
2-
use crate::internal::{
3-
files::increase_file_reference_count,
4-
groups::{find_group_by_id, increase_group_reference_count},
5-
};
1+
use super::models::{FileGroupDTO,FileGroupCondition};
62
use crate::model::schema::{file_groups};
73
use diesel::prelude::*;
84
use std::fmt::{Debug, Formatter, Result as fmtResult};
95

10-
pub fn create_file_group(
6+
pub fn insert_file_group(
117
conn: &mut SqliteConnection,
12-
file_group_dto: FileGroupDTO,
13-
) -> Result<FileGroupDTO, AppError> {
14-
let group = find_group_by_id(conn, file_group_dto.group_id)?.ok_or(AppError::GroupNotFound)?;
15-
16-
if group.is_primary {
17-
return Err(AppError::CannotAssociateWithPrimary);
18-
}
19-
20-
let result = conn.transaction::<_, AppError, _>(|conn| {
21-
increase_file_reference_count(conn, file_group_dto.file_id)?;
22-
increase_group_reference_count(conn, file_group_dto.group_id)?;
23-
Ok(diesel::insert_into(file_groups::table).values(&file_group_dto).execute(conn))
24-
});
25-
let _ = result?;
26-
Ok(file_group_dto)
8+
file_group_dto: &FileGroupDTO,
9+
) -> Result<usize, diesel::result::Error>{
10+
diesel::insert_into(file_groups::table)
11+
.values(file_group_dto)
12+
.execute(conn)
2713
}
2814

29-
pub fn delete_file_group(
15+
pub fn delete_file_group_by_id(
3016
conn: &mut SqliteConnection,
31-
file_group_dto: FileGroupDTO,
32-
) -> Result<usize, AppError> {
33-
let result = conn.transaction::<_, AppError, _>(|conn| {
34-
// 减少组和标签的引用计数
35-
decrease_group_reference_count(conn, file_group_dto.group_id)?;
36-
decrease_file_reference_count(conn, file_group_dto.file_id)?;
37-
38-
// 删除关联记录
39-
let deleted_count = diesel::delete(
40-
file_groups::table
41-
.filter(file_groups::group_id.eq(file_group_dto.group_id))
42-
.filter(file_groups::file_id.eq(file_group_dto.file_id))
43-
)
44-
.execute(conn)?;
45-
46-
Ok(deleted_count)
47-
});
48-
49-
result.map_err(|e| e)
17+
file_group_dto: &FileGroupDTO,
18+
) -> Result<usize, diesel::result::Error> {
19+
// 删除关联记录
20+
diesel::delete(
21+
file_groups::table
22+
.filter(file_groups::group_id.eq(file_group_dto.group_id))
23+
.filter(file_groups::file_id.eq(file_group_dto.file_id))
24+
).execute(conn)
5025
}
5126

5227
impl Debug for FileGroupDTO {
@@ -55,14 +30,7 @@ impl Debug for FileGroupDTO {
5530
}
5631
}
5732

58-
// 在 files.rs 文件中添加以下代码(需要添加到文件末尾,在其他 use 语句之后)
59-
60-
use super::models::FileGroupCondition;
61-
use diesel::dsl::not;
62-
use diesel::sql_types::Bool;
6333
use diesel::sqlite::Sqlite;
64-
use crate::internal::files::decrease_file_reference_count;
65-
use crate::internal::groups::decrease_group_reference_count;
6634

6735
// 将 FileGroupCondition 转换为 diesel 查询条件的辅助函数
6836
fn build_file_group_condition(condition: FileGroupCondition) -> Box<dyn BoxableExpression<file_groups::table, Sqlite, SqlType = diesel::sql_types::Bool>> {
@@ -84,7 +52,7 @@ fn build_file_group_condition(condition: FileGroupCondition) -> Box<dyn BoxableE
8452
Some(prev) => result = Some(Box::new(prev.and(expr))),
8553
}
8654
}
87-
result.unwrap_or_else(|| Box::new(true.into_sql::<Bool>()))
55+
result.unwrap_or_else(|| Box::new(true.into_sql::<diesel::sql_types::Bool>()))
8856
},
8957
FileGroupCondition::Or(conditions) => {
9058
let mut result: Option<Box<dyn BoxableExpression<file_groups::table, Sqlite, SqlType = diesel::sql_types::Bool>>> = None;
@@ -95,11 +63,11 @@ fn build_file_group_condition(condition: FileGroupCondition) -> Box<dyn BoxableE
9563
Some(prev) => result = Some(Box::new(prev.or(expr))),
9664
}
9765
}
98-
result.unwrap_or_else(|| Box::new(false.into_sql::<Bool>()))
66+
result.unwrap_or_else(|| Box::new(false.into_sql::<diesel::sql_types::Bool>()))
9967
},
10068
FileGroupCondition::Not(condition) => {
10169
let expr = build_file_group_condition(*condition);
102-
Box::new(not(expr))
70+
Box::new(diesel::dsl::not(expr))
10371
}
10472
}
10573
}
@@ -123,3 +91,19 @@ pub fn select_file_groups_by_conditions(
12391
.select((file_groups::file_id, file_groups::group_id))
12492
.load(conn)
12593
}
94+
95+
pub fn delete_file_groups_by_conditions(
96+
conn: &mut SqliteConnection,
97+
conditions: Vec<FileGroupCondition>,
98+
) -> Result<usize, diesel::result::Error> {
99+
let mut query = diesel::delete(file_groups::table).into_boxed::<Sqlite>();
100+
101+
// 对每个条件应用 AND 逻辑
102+
for condition in conditions {
103+
let boxed_condition = build_file_group_condition(condition);
104+
query = query.filter(boxed_condition);
105+
}
106+
107+
query.execute(conn)
108+
}
109+

file_classification_core/src/internal/files.rs

Lines changed: 34 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,34 @@
1-
use super::{models::{CreateFileDTO, File, FileFilter, FileCondition}, AppError};
1+
use super::{models::{UpdateFileDTO, CreateFileDTO, File, FileFilter, FileCondition}};
22
use diesel::prelude::*;
33

4-
pub fn create_file(conn: &mut SqliteConnection, new_file: &CreateFileDTO) -> Result<File, AppError> {
4+
pub fn create_file(conn: &mut SqliteConnection, new_file: &CreateFileDTO) -> Result<usize, diesel::result::Error> {
55
diesel::insert_into(files::table)
6-
.values(new_file)
7-
// NOTE: as_returning 只有一部分数据库支持
8-
// TODO: 若不支持则需要另外处理
9-
.returning(File::as_returning())
10-
.get_result(conn)
11-
.map_err(|e| AppError::CreateFileFailed(e.to_string()))
6+
.values(new_file).execute(conn)
127
}
138

9+
pub fn find_file_by_id(conn: &mut SqliteConnection, _id: i32) -> Result<Option<File>, diesel::result::Error> {
10+
files::table
11+
.filter(files::id.eq(_id))
12+
.select(File::as_select())
13+
.first(conn)
14+
.optional()
15+
}
1416
pub fn increase_file_reference_count(
1517
conn: &mut SqliteConnection,
1618
file_id: i32,
17-
) -> Result<(), AppError> {
19+
) -> Result<usize, diesel::result::Error> {
1820
diesel::update(files::table.find(file_id))
1921
.set(files::reference_count.eq(files::reference_count + 1))
20-
.execute(conn)?;
21-
22-
Ok(())
22+
.execute(conn)
2323
}
2424

25-
#[allow(dead_code)]
2625
pub fn decrease_file_reference_count(
2726
conn: &mut SqliteConnection,
2827
file_id: i32,
29-
) -> Result<(), AppError> {
28+
) -> Result<usize, diesel::result::Error> {
3029
diesel::update(files::table.find(file_id))
3130
.set(files::reference_count.eq(files::reference_count - 1))
32-
.execute(conn)?;
33-
34-
Ok(())
31+
.execute(conn)
3532
}
3633

3734
#[deprecated]
@@ -64,52 +61,10 @@ pub fn select_files(
6461
base_query.load(conn)
6562
}
6663

67-
// pub fn update_file(
68-
// conn: &mut SqliteConnection,
69-
// update_input: UpdateFile,
70-
// ) -> Result<usize, diesel::result::Error> {
71-
// // 初始化更新查询
72-
// let mut query = diesel::update(files).into_boxed();
73-
74-
// // 动态设置需要更新的字段
75-
// if let Some(new_path) = update_input.set.path {
76-
// query = query.set(path.eq(new_path));
77-
// }
78-
// if let Some(new_type) = update_input.set.type_ {
79-
// query = query.set(type_.eq(new_type));
80-
// }
81-
// if let Some(new_ref_count) = update_input.set.reference_count {
82-
// query = query.set(reference_count.eq(new_ref_count));
83-
// }
84-
// if let Some(new_group) = update_input.set.group_id {
85-
// query = query.set(group_id.eq(new_group));
86-
// }
87-
88-
// // 动态添加过滤条件
89-
// if let Some(file_id) = update_input.filter.id {
90-
// query = query.filter(id.eq(file_id));
91-
// }
92-
// if let Some(file_type) = update_input.filter.type_ {
93-
// query = query.filter(type_.eq(file_type));
94-
// }
95-
// if let Some(file_path) = update_input.filter.path {
96-
// query = query.filter(path.eq(file_path));
97-
// }
98-
// if let Some(ref_count) = update_input.filter.reference_count {
99-
// query = query.filter(reference_count.eq(ref_count));
100-
// }
101-
// if let Some(group) = update_input.filter.group_id {
102-
// query = query.filter(group_id.eq(group));
103-
// }
104-
// query.load(conn)
105-
// }
106-
107-
pub fn delete_file(conn: &mut SqliteConnection, file_id: i32) -> Result<(), diesel::result::Error> {
108-
match diesel::delete(files.filter(files::id.eq(file_id))).execute(conn) {
109-
Ok(_) => Ok(()),
110-
Err(e) => Err(e),
111-
}
64+
pub fn delete_file_by_id(conn: &mut SqliteConnection, file_id: i32) -> Result<usize, diesel::result::Error> {
65+
diesel::delete(files.filter(files::id.eq(file_id))).execute(conn)
11266
}
67+
11368
use crate::model::schema::files;
11469
use crate::model::schema::files::dsl::*;
11570
use std::fmt::{Debug, Formatter, Result as fmtResult};
@@ -126,8 +81,6 @@ impl Debug for File {
12681
}
12782
}
12883

129-
use diesel::dsl::not;
130-
use crate::model::models::UpdateFileDTO;
13184

13285
// 将 FileCondition 转换为 diesel 查询条件的辅助函数
13386
// 更新 build_condition 函数以处理新增的条件类型
@@ -173,7 +126,7 @@ fn build_file_condition(condition: FileCondition) -> Box<dyn BoxableExpression<f
173126
},
174127
FileCondition::Not(condition) => {
175128
let expr = build_file_condition(*condition);
176-
Box::new(not(expr))
129+
Box::new(diesel::dsl::not(expr))
177130
}
178131
}
179132
}
@@ -203,7 +156,7 @@ pub fn update_files_by_conditions(
203156
conn: &mut SqliteConnection,
204157
conditions: Vec<FileCondition>,
205158
update_set: UpdateFileDTO,
206-
) -> Result<usize, AppError> {
159+
) -> Result<usize, diesel::result::Error> {
207160
let mut query = diesel::update(files::table).into_boxed::<Sqlite>();
208161

209162
// 应用所有条件
@@ -212,7 +165,20 @@ pub fn update_files_by_conditions(
212165
query = query.filter(boxed_condition);
213166
}
214167

215-
let result = query.set(update_set).execute(conn)?;
216-
Ok(result)
168+
query.set(update_set).execute(conn)
217169
}
218170

171+
pub fn delete_files_by_conditions(
172+
conn: &mut SqliteConnection,
173+
conditions: Vec<FileCondition>,
174+
) -> Result<usize, diesel::result::Error> {
175+
let mut query = diesel::delete(files::table).into_boxed::<Sqlite>();
176+
177+
// 应用所有条件
178+
for condition in conditions {
179+
let boxed_condition = build_file_condition(condition);
180+
query = query.filter(boxed_condition);
181+
}
182+
183+
query.execute(conn)
184+
}

0 commit comments

Comments
 (0)