feat: ✨ client read all, read, download, delete
fix: 🚑 creating table instead of record in database
This commit is contained in:
parent
0c64f098c6
commit
a968a2db4a
8 changed files with 145 additions and 22 deletions
|
@ -3,10 +3,11 @@ use tokio::{
|
|||
io::AsyncWriteExt,
|
||||
};
|
||||
|
||||
const FILE_LOCATION: &str = "~/.local/share/";
|
||||
const FILE_LOCATION: &str = "./packages/";
|
||||
|
||||
pub async fn save_package(package_name: String, package_data: &[u8]) -> Result<(), std::io::Error> {
|
||||
let mut package_file = File::create_new(format!("{}{}", FILE_LOCATION, package_name)).await?;
|
||||
let file_location = format!("{}{}", FILE_LOCATION, package_name);
|
||||
let mut package_file = File::create(file_location).await?;
|
||||
package_file.write_all(package_data).await
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,28 @@ pub struct Package {
|
|||
location: String,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
pub fn get_name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Package {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: Default::default(),
|
||||
publisher: Default::default(),
|
||||
version: Default::default(),
|
||||
size: Default::default(),
|
||||
hash: Default::default(),
|
||||
dependencies: Default::default(),
|
||||
publish_date_time: Default::default(),
|
||||
last_update_date_time: Default::default(),
|
||||
location: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
first: u8,
|
||||
|
@ -21,7 +43,25 @@ pub struct Version {
|
|||
third: u8,
|
||||
}
|
||||
|
||||
impl Default for Version {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
first: Default::default(),
|
||||
second: Default::default(),
|
||||
third: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Publisher {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Default for Publisher {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ pub async fn read_all_packages() -> Result<Vec<Package>, Box<dyn Error>> {
|
|||
.as_array()
|
||||
.map_or(Err(""), |values| Ok(values))?
|
||||
.iter()
|
||||
.map(|value| serde_json::from_value::<Package>(value.clone()).unwrap())
|
||||
.map(|value| serde_json::from_value::<Package>(value.clone()).unwrap_or_default())
|
||||
.filter(|package| !package.get_name().is_empty())
|
||||
.collect())
|
||||
}
|
||||
|
||||
|
@ -34,14 +35,13 @@ pub async fn read_package(package_name: String) -> Option<Package> {
|
|||
pub async fn download_package(package_name: String) -> Option<Vec<u8>> {
|
||||
Some(
|
||||
CLIENT
|
||||
.get(format!("{}{}/{}", URL, "/packages", package_name))
|
||||
.get(format!("{}{}/{}", URL, "/packages/downloads", package_name))
|
||||
.send()
|
||||
.await
|
||||
.ok()?
|
||||
.text()
|
||||
.bytes()
|
||||
.await
|
||||
.ok()?
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,62 @@
|
|||
use tokio::test;
|
||||
|
||||
#[test]
|
||||
async fn test_list_packages() {
|
||||
async fn test_read_all_packages() {
|
||||
use crate::request::read_all_packages;
|
||||
|
||||
let packages = read_all_packages().await;
|
||||
|
||||
println!("{:#?}", packages);
|
||||
assert_eq!(packages.is_ok(), true);
|
||||
assert_eq!(packages.as_ref().unwrap().is_empty(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_read_package() {
|
||||
use crate::request::read_package;
|
||||
|
||||
let package = read_package("test_package".to_owned()).await;
|
||||
assert_eq!(package.is_some(), true);
|
||||
assert_eq!(package.unwrap().get_name().is_empty(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_download_package() {
|
||||
use crate::request::download_package;
|
||||
|
||||
let package_data = download_package("test_package".to_owned()).await;
|
||||
assert_eq!(package_data.is_some(), true);
|
||||
assert_eq!(package_data.unwrap().is_empty(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_save_package() {
|
||||
use crate::request::download_package;
|
||||
|
||||
let package_data = download_package("test_package".to_owned()).await;
|
||||
assert_eq!(package_data.is_some(), true);
|
||||
assert_eq!(package_data.as_ref().unwrap().is_empty(), false);
|
||||
|
||||
use crate::file::save_package;
|
||||
|
||||
let saved_or_not = save_package("test_package".to_string(), &package_data.unwrap()[..]).await;
|
||||
assert_eq!(saved_or_not.is_ok(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_delete_package() {
|
||||
use crate::request::download_package;
|
||||
|
||||
let package_data = download_package("test_package".to_owned()).await;
|
||||
assert_eq!(package_data.is_some(), true);
|
||||
assert_eq!(package_data.as_ref().unwrap().is_empty(), false);
|
||||
|
||||
use crate::file::save_package;
|
||||
|
||||
let saved_or_not = save_package("test_package".to_string(), &package_data.unwrap()[..]).await;
|
||||
assert_eq!(saved_or_not.is_ok(), true);
|
||||
|
||||
use crate::file::delete_package;
|
||||
|
||||
let deleted_or_not = delete_package("test_package".to_string()).await;
|
||||
assert_eq!(deleted_or_not.is_ok(), true);
|
||||
}
|
||||
|
|
|
@ -14,11 +14,10 @@ pub async fn establish_connection() -> Result<(), surrealdb::Error> {
|
|||
DB.connect::<Ws>("localhost:8000").await?;
|
||||
DB.use_ns("Packages").await?;
|
||||
DB.use_db("Packages").await?;
|
||||
DB.query("DEFINE TABLE Packages")
|
||||
.await.map(|_| ())?;
|
||||
DB.query("DEFINE INDEX package_nameINDEX on TABLE Packages COLUMNS package_name UNIQUE").await.map(|_| ())
|
||||
|
||||
|
||||
DB.query("DEFINE TABLE Packages").await.map(|_| ())?;
|
||||
DB.query("DEFINE INDEX package_nameINDEX on TABLE Packages COLUMNS package_name UNIQUE")
|
||||
.await
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
pub async fn is_alive() -> bool {
|
||||
|
@ -45,7 +44,8 @@ pub async fn read_package(package_name: String) -> Option<Package> {
|
|||
pub async fn update_package(package_name: String, package: Package) -> Option<Package> {
|
||||
DB.update(("Packages", package_name))
|
||||
.content(package)
|
||||
.await.ok()?
|
||||
.await
|
||||
.ok()?
|
||||
}
|
||||
|
||||
pub async fn delete_package(package_name: String) -> Option<Package> {
|
||||
|
|
|
@ -2,7 +2,7 @@ pub mod database;
|
|||
pub mod package;
|
||||
pub mod routing;
|
||||
|
||||
pub const PACKAGE_PATH: &str = "/packages";
|
||||
pub const PACKAGE_PATH: &str = "./packages";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppState {}
|
||||
|
|
|
@ -19,6 +19,22 @@ pub struct Package {
|
|||
location: String,
|
||||
}
|
||||
|
||||
impl Default for Package {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: Default::default(),
|
||||
publisher: Default::default(),
|
||||
version: Default::default(),
|
||||
size: Default::default(),
|
||||
hash: Default::default(),
|
||||
dependencies: Default::default(),
|
||||
publish_date_time: Default::default(),
|
||||
last_update_date_time: Default::default(),
|
||||
location: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Package {
|
||||
pub fn new(name: String, publisher: Publisher, version: Version) -> Self {
|
||||
Self {
|
||||
|
@ -80,6 +96,16 @@ pub struct Version {
|
|||
third: u8,
|
||||
}
|
||||
|
||||
impl Default for Version {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
first: Default::default(),
|
||||
second: Default::default(),
|
||||
third: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Version {
|
||||
pub fn new(first: u8, second: u8, third: u8) -> Self {
|
||||
Version {
|
||||
|
@ -101,6 +127,14 @@ pub struct Publisher {
|
|||
name: String,
|
||||
}
|
||||
|
||||
impl Default for Publisher {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Publisher {
|
||||
pub fn new(name: String) -> Self {
|
||||
Publisher { name }
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use axum::extract::Multipart;
|
||||
use tokio::{fs::File, io::AsyncWriteExt};
|
||||
use tokio_util::io::ReaderStream;
|
||||
|
@ -44,21 +42,20 @@ pub async fn download_package(package_name: String) -> Option<ReaderStream<File>
|
|||
|
||||
pub async fn upload_package(mut package_file: Multipart) -> Option<Package> {
|
||||
let package_file_part = package_file.next_field().await.ok()??;
|
||||
let package_file_name = package_file_part.file_name()?.to_string();
|
||||
let package_file_name = package_file_part.name()?.to_string();
|
||||
|
||||
let file_location = format!("./{}/{}", PACKAGE_PATH, package_file_name);
|
||||
let file_location = PathBuf::from(file_location).canonicalize().ok()?;
|
||||
let file_location = file_location.to_str()?;
|
||||
let file_location = format!("{}/{}", PACKAGE_PATH, package_file_name);
|
||||
|
||||
let package_file_data = package_file_part.bytes().await.ok()?;
|
||||
let mut package = crate::package::utils::read_package(package_file_name).await?;
|
||||
|
||||
let mut file_descriptor = File::create_new(&file_location).await.ok()?;
|
||||
let mut file_descriptor = File::create(&file_location).await.ok()?;
|
||||
file_descriptor.write_all(&package_file_data).await.ok()?;
|
||||
|
||||
package.set_location(&file_location.to_string());
|
||||
package.set_hash().await;
|
||||
|
||||
let package = crate::package::utils::update_package(package.get_name(), package).await?;
|
||||
Some(package)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue