Skip to content

Commit 8a85336

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/multisig-support
2 parents e66ad1f + c947e69 commit 8a85336

File tree

5 files changed

+139
-73
lines changed

5 files changed

+139
-73
lines changed

fplus-database/src/database/allocators.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub async fn get_allocators() ->Result<Vec<AllocatorModel>, sea_orm::DbErr> {
2222
* @param installation_id: Option<i64> - The installation ID
2323
* @param multisig_address: Option<String> - The multisig address
2424
* @param verifiers_gh_handles: Option<String> - The GitHub handles of the verifiers
25+
* @param multisig_threshold: Option<i32> - The multisig threshold
2526
*
2627
* # Returns
2728
* @return Result<AllocatorModel, sea_orm::DbErr> - The result of the operation
@@ -32,16 +33,30 @@ pub async fn update_allocator(
3233
installation_id: Option<i64>,
3334
multisig_address: Option<String>,
3435
verifiers_gh_handles: Option<String>,
36+
multisig_threshold: Option<i32>
3537
) -> Result<AllocatorModel, sea_orm::DbErr> {
3638
let conn = get_database_connection().await?;
3739

3840
let existing_allocator = get_allocator(owner, repo).await?;
3941
if let Some(allocator_model) = existing_allocator {
4042
let mut allocator_active_model = allocator_model.into_active_model();
4143

42-
allocator_active_model.installation_id = Set(installation_id);
43-
allocator_active_model.multisig_address = Set(multisig_address);
44-
allocator_active_model.verifiers_gh_handles = Set(verifiers_gh_handles);
44+
//if fields are not None, update them
45+
if Some(installation_id) != None {
46+
allocator_active_model.installation_id = Set(installation_id);
47+
}
48+
49+
if Some(multisig_address.clone()) != None {
50+
allocator_active_model.multisig_address = Set(multisig_address);
51+
}
52+
53+
if Some(verifiers_gh_handles.clone()) != None {
54+
allocator_active_model.verifiers_gh_handles = Set(verifiers_gh_handles);
55+
}
56+
57+
if Some(multisig_threshold) != None {
58+
allocator_active_model.multisig_threshold = Set(multisig_threshold);
59+
}
4560

4661
let updated_model = allocator_active_model.update(&conn).await?;
4762

@@ -108,16 +123,28 @@ pub async fn create_or_update_allocator(
108123

109124
Ok(updated_model)
110125
} else {
111-
let new_allocator = ActiveModel {
126+
let mut new_allocator = ActiveModel {
112127
owner: Set(owner),
113128
repo: Set(repo),
114-
installation_id: Set(installation_id),
115-
multisig_address: Set(multisig_address),
116-
verifiers_gh_handles: Set(verifiers_gh_handles),
117-
multisig_threshold: Set(multisig_threshold),
118129
..Default::default()
119130
};
131+
132+
if installation_id.is_some() {
133+
new_allocator.installation_id = Set(installation_id);
134+
}
135+
136+
if multisig_address.is_some() {
137+
new_allocator.multisig_address = Set(multisig_address);
138+
}
139+
140+
if verifiers_gh_handles.is_some() {
141+
new_allocator.verifiers_gh_handles = Set(verifiers_gh_handles);
142+
}
120143

144+
if multisig_threshold.is_some() {
145+
new_allocator.multisig_threshold = Set(multisig_threshold);
146+
}
147+
121148
let conn = get_database_connection().await.expect("Failed to get DB connection");
122149
new_allocator.insert(&conn).await
123150
}

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-database/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,15 @@ mod tests {
169169
let installation_id = Some(1234);
170170
let multisig_address = Some("0x0987654321".to_string());
171171
let verifiers_gh_handles = Some("test_verifier_3, test_verifier_4".to_string());
172+
let multisig_threshold = Some(1);
172173

173174
let result = database::allocators::update_allocator(
174175
&owner,
175176
&repo,
176177
installation_id,
177178
multisig_address,
178179
verifiers_gh_handles,
180+
multisig_threshold
179181
).await;
180182
assert!(result.is_ok());
181183
}

fplus-http-server/src/router/allocator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub async fn update(
8383
info.installation_id,
8484
info.multisig_address.clone(),
8585
info.verifiers_gh_handles.clone(),
86+
info.multisig_threshold
8687
).await {
8788
Ok(allocator_model) => HttpResponse::Ok().json(allocator_model),
8889
Err(e) => {

fplus-lib/src/core/mod.rs

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub struct AllocatorUpdateInfo {
117117
pub installation_id: Option<i64>,
118118
pub multisig_address: Option<String>,
119119
pub verifiers_gh_handles: Option<String>,
120+
pub multisig_threshold: Option<i32>,
120121
}
121122

122123
#[derive(Deserialize)]
@@ -292,61 +293,31 @@ impl LDNApplication {
292293
}
293294

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

340-
if errors.is_empty() {
341-
Ok(all_apps)
342-
} else {
343-
Err(errors)
344-
}
345316
}
346317

347318
pub async fn active(owner: String, repo: String, filter: Option<String>) -> Result<Vec<ApplicationFile>, LDNError> {
348319
// Get all active applications from the database.
349-
let active_apps_result = database::applications::get_active_applications(owner, repo).await;
320+
let active_apps_result = database::applications::get_active_applications(Some(owner), Some(repo)).await;
350321

351322
// Handle errors in getting active applications.
352323
let active_apps = match active_apps_result {
@@ -368,7 +339,8 @@ impl LDNApplication {
368339
if let Some(app_json) = app_model.application {
369340
match from_str::<ApplicationFile>(&app_json) {
370341
Ok(app) => apps.push(app),
371-
Err(e) => return Err(LDNError::Load(format!("Failed to parse application file: {}", e))),
342+
//if error, don't push into apps
343+
Err(_) => {}
372344
}
373345
}
374346
}
@@ -1014,7 +986,7 @@ impl LDNApplication {
1014986

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

1019991
// Handle errors in getting applications from the main branch.
1020992
let merged_app_models = match merged_apps_result {
@@ -1030,7 +1002,7 @@ impl LDNApplication {
10301002
if let Some(app_json) = app_model.application {
10311003
match from_str::<ApplicationFile>(&app_json) {
10321004
Ok(app) => merged_apps.push((ApplicationGithubInfo {sha: app_model.sha.unwrap(), path: app_model.path.unwrap()}, app)),
1033-
Err(e) => return Err(LDNError::Load(format!("Failed to parse application file: {}", e))),
1005+
Err(_) => {},
10341006
}
10351007
}
10361008
}
@@ -1952,7 +1924,7 @@ Your Datacap Allocation Request has been {} by the Notary
19521924

19531925
pub async fn cache_renewal_active(owner: String, repo: String) -> Result<(), LDNError> {
19541926
let active_from_gh: Vec<ApplicationFileWithDate> = LDNApplication::active_apps_with_last_update(owner.clone(), repo.clone(), None).await?;
1955-
let active_from_db: Vec<ApplicationModel> = database::applications::get_active_applications(owner.clone(), repo.clone()).await.unwrap();
1927+
let active_from_db: Vec<ApplicationModel> = database::applications::get_active_applications(Some(owner.clone()), Some(repo.clone())).await.unwrap();
19561928

19571929
let mut db_apps_set: HashSet<String> = HashSet::new();
19581930
let mut processed_gh_apps: HashSet<String> = HashSet::new();
@@ -2009,7 +1981,7 @@ Your Datacap Allocation Request has been {} by the Notary
20091981

20101982
pub async fn cache_renewal_merged(owner: String, repo: String) -> Result<(), LDNError> {
20111983
let merged_from_gh: Vec<ApplicationFileWithDate> = LDNApplication::merged_apps_with_last_update(owner.clone(), repo.clone(), None).await?;
2012-
let merged_from_db: Vec<ApplicationModel> = database::applications::get_merged_applications(owner.clone(), repo.clone()).await.unwrap();
1984+
let merged_from_db: Vec<ApplicationModel> = database::applications::get_merged_applications(Some(owner.clone()), Some(repo.clone())).await.unwrap();
20131985

20141986
let mut db_apps_set: HashSet<String> = HashSet::new();
20151987
let mut processed_gh_apps: HashSet<String> = HashSet::new();

0 commit comments

Comments
 (0)