From 0586f2e670200e1b2bc8a3afa3b303315d89b0d2 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Thu, 19 May 2022 21:38:01 +0530 Subject: [PATCH] feat: get all repositories trait def and impl for sqlx sqlite --- db/db-core/src/lib.rs | 23 +++++++ db/db-sqlx-sqlite/sqlx-data.json | 72 ++++++++++++++++++++ db/db-sqlx-sqlite/src/lib.rs | 113 +++++++++++++++++++++++++------ forge/gitea/src/lib.rs | 4 +- 4 files changed, 189 insertions(+), 23 deletions(-) diff --git a/db/db-core/src/lib.rs b/db/db-core/src/lib.rs index 4a73d6e..6ff0b21 100644 --- a/db/db-core/src/lib.rs +++ b/db/db-core/src/lib.rs @@ -107,6 +107,26 @@ pub struct AddRepository<'a> { pub website: Option<&'a str>, } +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +/// repository +pub struct Repository { + /// html link to the repository + pub html_url: String, + /// repository topic tags + pub tags: Option>, + /// hostname of the forge instance: with scheme but remove trailing slash + /// hostname can be derived from html_link also, but used to link to user's forge instance + pub hostname: String, + /// repository name + pub name: String, + /// repository owner + pub username: String, + /// repository description, if any + pub description: Option, + /// repository website, if any + pub website: Option, +} + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] /// represents a DNS challenge pub struct Challenge { @@ -165,6 +185,9 @@ pub trait SCDatabase: std::marker::Send + std::marker::Sync + CloneSPDatabase { /// check if a repository exists. async fn repository_exists(&self, name: &str, owner: &str, hostname: &str) -> DBResult; + /// Get all repositories + async fn get_all_repositories(&self, page: u32, limit: u32) -> DBResult>; + /// add new repository to database. async fn create_repository(&self, r: &AddRepository) -> DBResult<()>; } diff --git a/db/db-sqlx-sqlite/sqlx-data.json b/db/db-sqlx-sqlite/sqlx-data.json index e9a641e..6e00d2e 100644 --- a/db/db-sqlx-sqlite/sqlx-data.json +++ b/db/db-sqlx-sqlite/sqlx-data.json @@ -102,6 +102,60 @@ }, "query": "DELETE FROM starchart_dns_challenges WHERE key = $1" }, + "80106a5fde0077375453d6170948330cc89dee997c2b8ad1d98b0799702eddc4": { + "describe": { + "columns": [ + { + "name": "hostname", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "username", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "description", + "ordinal": 3, + "type_info": "Text" + }, + { + "name": "html_url", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "ID", + "ordinal": 5, + "type_info": "Int64" + }, + { + "name": "website", + "ordinal": 6, + "type_info": "Text" + } + ], + "nullable": [ + false, + false, + false, + true, + false, + false, + true + ], + "parameters": { + "Right": 2 + } + }, + "query": " SELECT \n\t\tstarchart_forges.hostname,\n\t\tstarchart_users.username,\n\t\tstarchart_repositories.name,\n\t\tstarchart_repositories.description,\n\t\tstarchart_repositories.html_url,\n starchart_repositories.ID,\n\t\tstarchart_repositories.website\nFROM\n\tstarchart_repositories\nINNER JOIN\n\tstarchart_forges\nON\n\tstarchart_repositories.hostname_id = starchart_forges.id\nINNER JOIN\n\tstarchart_users\nON\n\tstarchart_repositories.owner_id = starchart_users.id\nORDER BY\n\tstarchart_repositories.ID\nLIMIT $1 OFFSET $2\n;" + }, "891a09656a04fdabfbf51b15204e224221cea8d30782170d3d8503c9275b3d58": { "describe": { "columns": [ @@ -228,6 +282,24 @@ }, "query": " DELETE FROM starchart_repositories\n WHERE \n name = $1\n AND\n owner_id = ( SELECT ID FROM starchart_users WHERE username = $2)\n AND\n hostname_id = (SELECT ID FROM starchart_forges WHERE hostname = $3)" }, + "f162b8469f951609e5fa026fa14b074361a4c206b34a8e6ed048d2e54157f4bb": { + "describe": { + "columns": [ + { + "name": "name", + "ordinal": 0, + "type_info": "Text" + } + ], + "nullable": [ + false + ], + "parameters": { + "Right": 1 + } + }, + "query": "SELECT name FROM starchart_project_topics WHERE ID = (\n SELECT topic_id FROM starchart_repository_topic_mapping WHERE repository_id = $1\n )" + }, "f52cde89ec10d5ca2151c9df6ae273ee0d52af9f79bb776765cfa716aad6af53": { "describe": { "columns": [], diff --git a/db/db-sqlx-sqlite/src/lib.rs b/db/db-sqlx-sqlite/src/lib.rs index 9e575d7..6819626 100644 --- a/db/db-sqlx-sqlite/src/lib.rs +++ b/db/db-sqlx-sqlite/src/lib.rs @@ -383,30 +383,99 @@ impl SCDatabase for Database { Ok(()) } + + /// Get all repositories + async fn get_all_repositories(&self, page: u32, limit: u32) -> DBResult> { + struct InnerRepository { + /// html link to the repository + pub html_url: String, + /// hostname of the forge instance: with scheme but remove trailing slash + /// hostname can be derived from html_link also, but used to link to user's forge instance + pub hostname: String, + /// repository name + pub name: String, + /// repository owner + pub username: String, + /// repository description, if any + pub description: Option, + /// repository website, if any + pub website: Option, + pub ID: i64, + } + + let mut db_res = sqlx::query_as!( + InnerRepository, + " SELECT + starchart_forges.hostname, + starchart_users.username, + starchart_repositories.name, + starchart_repositories.description, + starchart_repositories.html_url, + starchart_repositories.ID, + starchart_repositories.website +FROM + starchart_repositories +INNER JOIN + starchart_forges +ON + starchart_repositories.hostname_id = starchart_forges.id +INNER JOIN + starchart_users +ON + starchart_repositories.owner_id = starchart_users.id +ORDER BY + starchart_repositories.ID +LIMIT $1 OFFSET $2 +;", + limit, + page, + ) + .fetch_all(&self.pool) + .await + .map_err(map_register_err)?; + + let mut res = Vec::with_capacity(db_res.len()); + struct Topics { + name: String, + } + + for repo in db_res.drain(0..) { + let mut db_topics = sqlx::query_as!( + Topics, + "SELECT name FROM starchart_project_topics WHERE ID = ( + SELECT topic_id FROM starchart_repository_topic_mapping WHERE repository_id = $1 + )", + repo.ID + ) + .fetch_all(&self.pool) + .await + .map_err(map_register_err)?; + + let topics = if db_topics.is_empty() { + None + } else { + let mut topics = Vec::with_capacity(db_topics.len()); + for t in db_topics.drain(0..) { + topics.push(t.name); + } + + Some(topics) + }; + res.push(Repository { + html_url: repo.html_url, + hostname: repo.hostname, + name: repo.name, + username: repo.username, + description: repo.description, + website: repo.website, + tags: topics, + }); + } + + Ok(res) + } } fn now_unix_time_stamp() -> i64 { OffsetDateTime::now_utc().unix_timestamp() } - -// -//#[allow(non_snake_case)] -//struct InnerGistComment { -// ID: i64, -// owner: String, -// comment: Option, -// gist_public_id: String, -// created: i64, -//} -// -//impl From for GistComment { -// fn from(g: InnerGistComment) -> Self { -// Self { -// id: g.ID, -// owner: g.owner, -// comment: g.comment.unwrap(), -// gist_public_id: g.gist_public_id, -// created: g.created, -// } -// } -//} diff --git a/forge/gitea/src/lib.rs b/forge/gitea/src/lib.rs index 9f7117f..4496ed3 100644 --- a/forge/gitea/src/lib.rs +++ b/forge/gitea/src/lib.rs @@ -20,8 +20,10 @@ use std::sync::Arc; use reqwest::Client; use url::Url; -use db_core::prelude::*; +use db_core::ForgeImplementation; +use db_core::SCDatabase; use forge_core::dev::*; +use forge_core::Repository; pub mod schema;