Skip to content

Commit 72672f3

Browse files
authored
Merge pull request #136 from filecoin-project/feat/cache-application-db
Feat/cache-application-db
2 parents adf06d4 + 3f0e5fe commit 72672f3

File tree

2 files changed

+103
-56
lines changed

2 files changed

+103
-56
lines changed

fplus-database/src/database/applications.rs

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,61 @@
1-
use sea_orm::{entity::*, query::*, DbErr};
1+
use sea_orm::{entity::*, query::*, DbBackend, DbErr};
22
use crate::models::applications::{Column, ActiveModel, Entity as Application, Model as ApplicationModel};
33
use crate::get_database_connection;
44
use sha1::{Sha1, Digest};
5+
use chrono::{DateTime, Utc, TimeZone};
56

67
/**
78
* Get all applications from the database
89
*
910
* # Returns
1011
* @return Result<Vec<ApplicationModel>, sea_orm::DbErr> - The result of the operation
1112
*/
12-
pub async fn get_applications() ->Result<Vec<ApplicationModel>, sea_orm::DbErr> {
13+
pub async fn get_applications() -> Result<Vec<ApplicationModel>, sea_orm::DbErr> {
1314
let conn = get_database_connection().await?;
14-
Application::find().all(&conn).await
15+
16+
//Get all applications from the database.
17+
//Distinct on is not supported in sea_orm yet, so we have to use raw SQL
18+
let app_data = JsonValue::find_by_statement(Statement::from_sql_and_values(
19+
DbBackend::Postgres,
20+
r#"
21+
SELECT DISTINCT ON (owner, repo, id)
22+
a.id,
23+
a.owner,
24+
a.repo,
25+
a.pr_number,
26+
a.application,
27+
a.updated_at,
28+
a.sha,
29+
a.path
30+
FROM
31+
applications a
32+
ORDER BY
33+
a.owner,
34+
a.repo,
35+
a.id,
36+
a.pr_number DESC
37+
"#,
38+
[],
39+
))
40+
.all(&conn)
41+
.await?;
42+
43+
//Iterate over the results and convert them to ApplicationModel
44+
let mut applications: Vec<ApplicationModel> = Vec::new();
45+
for app in app_data {
46+
applications.push(ApplicationModel {
47+
id: app.get("id").unwrap().as_str().unwrap().to_string(),
48+
owner: app.get("owner").unwrap().as_str().unwrap().to_string(),
49+
repo: app.get("repo").unwrap().as_str().unwrap().to_string(),
50+
pr_number: app.get("pr_number").unwrap().as_i64().unwrap() as i64,
51+
application: Some(app.get("application").unwrap().as_str().unwrap().to_string()),
52+
updated_at: Utc.from_utc_datetime(&app.get("updated_at").unwrap().as_str().unwrap().parse::<DateTime<Utc>>().unwrap().naive_utc()),
53+
sha: Some(app.get("sha").unwrap().as_str().unwrap().to_string()),
54+
path: Some(app.get("path").unwrap().as_str().unwrap().to_string()),
55+
});
56+
}
57+
Ok(applications)
58+
1559
}
1660

1761
/**
@@ -24,12 +68,22 @@ pub async fn get_applications() ->Result<Vec<ApplicationModel>, sea_orm::DbErr>
2468
* # Returns
2569
* @return Result<Vec<ApplicationModel>, sea_orm::DbErr> - The result of the operation
2670
*/
27-
pub async fn get_merged_applications(owner: String, repo: String) -> Result<Vec<ApplicationModel>, sea_orm::DbErr> {
71+
pub async fn get_merged_applications(owner: Option<String>, repo: Option<String>) -> Result<Vec<ApplicationModel>, sea_orm::DbErr> {
2872
let conn = get_database_connection().await?;
29-
Application::find()
30-
.filter(Column::Owner.contains(owner))
31-
.filter(Column::Repo.contains(repo))
32-
.filter(Column::PrNumber.eq(0))
73+
let mut query = Application::find()
74+
.filter(Column::PrNumber.eq(0));
75+
if let Some(owner) = owner.clone() {
76+
query = query.filter(Column::Owner.contains(owner));
77+
}
78+
if let Some(repo) = repo {
79+
if owner.is_none() {
80+
return Err(DbErr::Custom(format!("Owner is required to get merged applications").into()));
81+
}
82+
query = query.filter(Column::Repo.contains(repo));
83+
}
84+
query
85+
.order_by(Column::Owner, Order::Asc)
86+
.order_by(Column::Repo, Order::Asc)
3387
.all(&conn)
3488
.await
3589
}
@@ -44,12 +98,22 @@ pub async fn get_merged_applications(owner: String, repo: String) -> Result<Vec<
4498
* # Returns
4599
* @return Result<Vec<ApplicationModel>, sea_orm::DbErr> - The result of the operation
46100
*/
47-
pub async fn get_active_applications(owner: String, repo: String) -> Result<Vec<ApplicationModel>, sea_orm::DbErr> {
101+
pub async fn get_active_applications(owner: Option<String>, repo: Option<String>) -> Result<Vec<ApplicationModel>, sea_orm::DbErr> {
48102
let conn = get_database_connection().await?;
49-
Application::find()
50-
.filter(Column::Owner.contains(owner))
51-
.filter(Column::Repo.contains(repo))
52-
.filter(Column::PrNumber.ne(0))
103+
let mut query = Application::find()
104+
.filter(Column::PrNumber.ne(0));
105+
if let Some(owner) = owner.clone() {
106+
query = query.filter(Column::Owner.contains(owner));
107+
}
108+
if let Some(repo) = repo {
109+
if owner.is_none() {
110+
return Err(DbErr::Custom(format!("Owner is required to get merged applications").into()));
111+
}
112+
query = query.filter(Column::Repo.contains(repo));
113+
}
114+
query
115+
.order_by(Column::Owner, Order::Asc)
116+
.order_by(Column::Repo, Order::Asc)
53117
.all(&conn)
54118
.await
55119
}

fplus-lib/src/core/mod.rs

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -290,50 +290,32 @@ impl LDNApplication {
290290
}
291291

292292
pub async fn all_applications() -> Result<Vec<(ApplicationFile, String, String)>, Vec<LDNError>> {
293-
//TODO: Avoid filtering by allocators. Simply get all active & merged applications from the database.
294-
let allocators = match database::allocators::get_allocators().await {
295-
Ok(allocs) => allocs,
296-
Err(e) => return Err(vec![LDNError::Load(format!("Failed to retrieve allocators: {}", e))]),
297-
}; let mut all_apps: Vec<(ApplicationFile, String, String)> = Vec::new();
298-
let mut errors: Vec<LDNError> = Vec::new();
299-
300-
for allocator in allocators {
301-
match Self::active(allocator.owner.clone(), allocator.repo.clone(), None).await {
302-
Ok(apps) => {
303-
for app in apps {
304-
all_apps.push((app, allocator.owner.clone(), allocator.repo.clone()));
305-
}
306-
},
307-
Err(e) => {
308-
errors.push(e);
309-
eprintln!("Failed to process active applications for allocator {}:{}", allocator.repo, allocator.owner);
310-
},
311-
}
312-
313-
match Self::merged(allocator.owner.clone(), allocator.repo.clone()).await {
314-
Ok(merged_apps) => {
315-
for (_, app) in merged_apps {
316-
all_apps.push((app, allocator.owner.clone(), allocator.repo.clone()));
317-
}
318-
},
319-
Err(e) => {
320-
errors.push(e);
321-
eprintln!("Failed to process merged applications for allocator {}:{}", allocator.repo, allocator.owner);
322-
},
323-
}
324-
}
325-
326-
if errors.is_empty() {
327-
Ok(all_apps)
328-
} else {
329-
Err(errors)
293+
let db_apps = database::applications::get_applications().await;
294+
let mut all_apps: Vec<(ApplicationFile, String, String)> = Vec::new();
295+
match db_apps {
296+
Ok(apps) => {
297+
for app in apps {
298+
let app_file = match ApplicationFile::from_str(&app.application.unwrap()) {
299+
Ok(app) => app,
300+
Err(e) => {
301+
return Err(vec![LDNError::Load(format!("Failed to parse application file from DB /// {}", e))]);
302+
}
303+
};
304+
all_apps.push((app_file, app.owner, app.repo));
305+
}
306+
return Ok(all_apps);
307+
},
308+
Err(e) => {
309+
return Err(vec![LDNError::Load(format!("Failed to retrieve applications from the database /// {}", e))]);
310+
},
330311
}
312+
331313
}
332314

333315

334316
pub async fn active(owner: String, repo: String, filter: Option<String>) -> Result<Vec<ApplicationFile>, LDNError> {
335317
// Get all active applications from the database.
336-
let active_apps_result = database::applications::get_active_applications(owner, repo).await;
318+
let active_apps_result = database::applications::get_active_applications(Some(owner), Some(repo)).await;
337319

338320
// Handle errors in getting active applications.
339321
let active_apps = match active_apps_result {
@@ -355,7 +337,8 @@ impl LDNApplication {
355337
if let Some(app_json) = app_model.application {
356338
match from_str::<ApplicationFile>(&app_json) {
357339
Ok(app) => apps.push(app),
358-
Err(e) => return Err(LDNError::Load(format!("Failed to parse application file: {}", e))),
340+
//if error, don't push into apps
341+
Err(_) => {}
359342
}
360343
}
361344
}
@@ -934,7 +917,7 @@ impl LDNApplication {
934917

935918
pub async fn merged(owner: String, repo: String) -> Result<Vec<(ApplicationGithubInfo, ApplicationFile)>, LDNError> {
936919
// Retrieve all applications in the main branch from the database.
937-
let merged_apps_result = database::applications::get_merged_applications(owner.clone(), repo.clone()).await;
920+
let merged_apps_result = database::applications::get_merged_applications(Some(owner.clone()), Some(repo.clone())).await;
938921

939922
// Handle errors in getting applications from the main branch.
940923
let merged_app_models = match merged_apps_result {
@@ -950,7 +933,7 @@ impl LDNApplication {
950933
if let Some(app_json) = app_model.application {
951934
match from_str::<ApplicationFile>(&app_json) {
952935
Ok(app) => merged_apps.push((ApplicationGithubInfo {sha: app_model.sha.unwrap(), path: app_model.path.unwrap()}, app)),
953-
Err(e) => return Err(LDNError::Load(format!("Failed to parse application file: {}", e))),
936+
Err(_) => {},
954937
}
955938
}
956939
}
@@ -1807,7 +1790,7 @@ Your Datacap Allocation Request has been {} by the Notary
18071790

18081791
pub async fn cache_renewal_active(owner: String, repo: String) -> Result<(), LDNError> {
18091792
let active_from_gh: Vec<ApplicationFileWithDate> = LDNApplication::active_apps_with_last_update(owner.clone(), repo.clone(), None).await?;
1810-
let active_from_db: Vec<ApplicationModel> = database::applications::get_active_applications(owner.clone(), repo.clone()).await.unwrap();
1793+
let active_from_db: Vec<ApplicationModel> = database::applications::get_active_applications(Some(owner.clone()), Some(repo.clone())).await.unwrap();
18111794

18121795
let mut db_apps_set: HashSet<String> = HashSet::new();
18131796
let mut processed_gh_apps: HashSet<String> = HashSet::new();
@@ -1864,7 +1847,7 @@ Your Datacap Allocation Request has been {} by the Notary
18641847

18651848
pub async fn cache_renewal_merged(owner: String, repo: String) -> Result<(), LDNError> {
18661849
let merged_from_gh: Vec<ApplicationFileWithDate> = LDNApplication::merged_apps_with_last_update(owner.clone(), repo.clone(), None).await?;
1867-
let merged_from_db: Vec<ApplicationModel> = database::applications::get_merged_applications(owner.clone(), repo.clone()).await.unwrap();
1850+
let merged_from_db: Vec<ApplicationModel> = database::applications::get_merged_applications(Some(owner.clone()), Some(repo.clone())).await.unwrap();
18681851

18691852
let mut db_apps_set: HashSet<String> = HashSet::new();
18701853
let mut processed_gh_apps: HashSet<String> = HashSet::new();

0 commit comments

Comments
 (0)