summaryrefslogtreecommitdiff
path: root/src/repository/models.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/repository/models.rs')
-rw-r--r--src/repository/models.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/repository/models.rs b/src/repository/models.rs
index 607008e..1fd1649 100644
--- a/src/repository/models.rs
+++ b/src/repository/models.rs
@@ -1,5 +1,6 @@
use crate::db::get_client;
use crate::errors::{AppError, AppErrorType};
+
use chrono::NaiveDateTime;
use deadpool_postgres::{Client, Pool};
use serde::{Deserialize, Serialize};
@@ -7,6 +8,8 @@ use tokio_pg_mapper::FromTokioPostgresRow;
use tokio_pg_mapper_derive::PostgresMapper;
use uuid::Uuid;
+use std::net::SocketAddr;
+
#[derive(Serialize, Deserialize, PostgresMapper)]
#[pg_mapper(table = "repository")]
/// Repository model
@@ -18,6 +21,12 @@ pub struct Repository {
pub uploader_ip: String,
}
+/// Struct used to create a new repository
+#[derive(Serialize, Deserialize)]
+pub struct RepositoryData {
+ pub url: String,
+}
+
impl Repository {
/// Find all repositories inside the database.
/// Make a select query and order the repositories by descrescent updated
@@ -116,4 +125,63 @@ impl Repository {
}
}
+ /// Create a new repository. It uses RepositoryData as support struct
+ pub async fn create(
+ pool: Pool,
+ data: &RepositoryData,
+ uploader_ip: Option<SocketAddr>,
+ ) -> Result<Repository, AppError> {
+ let client = get_client(pool.clone()).await.unwrap();
+
+ // Search a repository that matches with that url, because if it's
+ // exists, the server do not create a clone
+ let repo_search = Repository::search(&client, data.url.clone()).await;
+ match repo_search {
+ Ok(_) => {
+ return Err(AppError {
+ message: Some("Repository already exists".to_string()),
+ cause: Some("".to_string()),
+ error_type: AppErrorType::AuthorizationError,
+ });
+ }
+ Err(_) => {}
+ };
+
+ let statement = client
+ .prepare("
+ INSERT INTO repository(id, url, uploader_ip) VALUES($1, $2, $3) RETURNING *
+ ").await?;
+
+ // Create a new UUID v4
+ let uuid = Uuid::new_v4();
+
+ // Match the uploader ip
+ let user_ip = match uploader_ip {
+ Some(ip) => ip.to_string(),
+ None => {
+ return Err(AppError {
+ message: Some("Failed to fetch uploader ip".to_string()),
+ cause: Some("".to_string()),
+ error_type: AppErrorType::AuthorizationError,
+ })
+ }
+ };
+
+ let repo = client
+ .query(&statement, &[&uuid, &data.url, &user_ip])
+ .await?
+ .iter()
+ .map(|row| Repository::from_row_ref(row).unwrap())
+ .collect::<Vec<Repository>>()
+ .pop();
+
+ match repo {
+ Some(repo) => Ok(repo),
+ None => Err(AppError {
+ message: Some("Error creating a new repository".to_string()),
+ cause: Some("Unknown error".to_string()),
+ error_type: AppErrorType::DbError,
+ }),
+ }
+ }
}