Skip to content

Commit

Permalink
database and create fucked with
Browse files Browse the repository at this point in the history
  • Loading branch information
Joeyh021 committed Dec 18, 2022
1 parent 7d328e7 commit fe4e766
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 546 deletions.
497 changes: 23 additions & 474 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions dcspkg-create/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ smol = "1.2.5"
tar = "0.4.38"
anyhow = "1"
flate2 = "1.0.24"
clap = { version = "3.2.20", features = ["derive", "cargo"] }
clap = { version = "4.0.29", features = ["derive", "cargo"] }
dialoguer = "0.10.2"
semver = "1.0.13"
url = "2.3.0"
sqlx = { version = "0.6.1", features = ["sqlite", "runtime-async-std-rustls"] }
sqlx = { version = "0.6.2", features = ["sqlite", "runtime-async-std-rustls"] }
dcspkg_server = { path = "../dcspkg-server" }
32 changes: 12 additions & 20 deletions dcspkg-create/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
use anyhow::{anyhow, Context, Result};
use dcspkg_common::Package;
use dcspkg_server::Package;
use sqlx::{
sqlite::{self, SqliteConnection},
Connection,
};
use std::path::Path;

pub fn validate_name_and_version(db_path: &Path, pkg_name: &str, version: &str) -> Result<()> {
smol::block_on(async { async_validate_name_and_version(db_path, pkg_name, version).await })
pub fn check_name_unique(db_path: &Path, pkg_name: &str) -> Result<()> {
smol::block_on(async { async_check_name_unique(db_path, pkg_name).await })
}

pub fn add_package_to_db(db_path: &Path, package: &mut Package) -> Result<()> {
pub fn add_package_to_db(db_path: &Path, package: Package) -> Result<()> {
smol::block_on(async { async_add_package_to_db(db_path, package).await })
}

async fn async_validate_name_and_version(
db_path: &Path,
pkg_name: &str,
version: &str,
) -> Result<()> {
async fn async_check_name_unique(db_path: &Path, pkg_name: &str) -> Result<()> {
let mut connection = connect(db_path).await?;
let result: Result<Option<(String, String)>, sqlx::Error> =
sqlx::query_as("SELECT name, version FROM packages WHERE name=? AND version=?")
sqlx::query_as("SELECT * FROM packages WHERE pkgname=?")
.bind(pkg_name)
.bind(version)
.fetch_optional(&mut connection)
.await;

Expand All @@ -36,23 +31,20 @@ async fn async_validate_name_and_version(
}
}

async fn async_add_package_to_db(db_path: &Path, package: &mut Package) -> Result<()> {
async fn async_add_package_to_db(db_path: &Path, package: Package) -> Result<()> {
let mut connection = connect(db_path).await?;
let query = sqlx::query(
"INSERT INTO packages (name, description, version, image_url, archive_path, executable_path, crc, has_installer, add_to_path) VALUES (?,?,?,?,?,?,?,?,?)")
.bind(&package.name)
sqlx::query(
"INSERT INTO packages (pkgname, fullname, description, image_url, executable_path, crc, has_installer, add_to_path) VALUES (?,?,?,?,?,?,?,?,?)")
.bind(&package.pkgname)
.bind(&package.fullname)
.bind(&package.description)
.bind(&package.version)
.bind(&package.image_url)
.bind(&package.archive_path)
.bind(&package.executable_path)
.bind(package.crc)
.bind(package.has_installer)
.bind(package.add_to_path)
.execute(&mut connection)
.await.context("Could not insert package into database")?;
package.id = query.last_insert_rowid();
Ok(())
.await.context("Could not insert package into database").map(|_|()).map_err(Into::into)
}

async fn connect(path: &Path) -> Result<SqliteConnection> {
Expand Down
59 changes: 30 additions & 29 deletions dcspkg-create/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clap::Parser;
use dcspkg_common::Package;
use dcspkg_server::Package;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
mod archive;
mod db;
mod opts;
Expand All @@ -12,44 +12,41 @@ fn main() -> anyhow::Result<()> {
println!("Creating new dcspkg from {directory:?}");
println!("Please specify package options (skip to use defaults)");

let pkg_name = opts::get_pkg_name(directory.file_name().and_then(|s| s.to_str()))?;
let version = opts::get_version()?;
let pkgname = opts::get_pkg_name(directory.file_name().and_then(|s| s.to_str()))?;

db::validate_name_and_version(&args.db, &pkg_name, &version)?;
db::check_name_unique(&args.db, &pkgname)?;

let fullname = opts::get_full_name(&pkgname)?;
let description = opts::get_description()?;
let image_url = opts::get_image_url()?;
let executable_path = opts::get_exe_path(&directory)?;
let add_to_path = opts::add_to_path()?;
let has_installer = opts::has_installer(&directory)?;
let archive_name = format!("{pkg_name}-{version}.dcspkg");

print!("Creating tarball...");
std::io::stdout().flush()?; //print with no newline so force a flush

let archive_path = args.pkg_dir.join(&archive_name);
let archive_path = args.pkg_dir.join(format!("{pkgname}.dcspkg"));

let crc = archive::make_archive(&archive_path, &directory)?;

println!("done!");

let mut package = Package {
id: 0,
name: pkg_name,
let package = Package {
pkgname,
description,
version,
image_url,
archive_path: archive_name,
executable_path,
crc,
has_installer,
add_to_path,
fullname,
};

db::add_package_to_db(&args.db, &mut package)?;

println!("{}", serde_json::to_string_pretty(&package)?);

db::add_package_to_db(&args.db, package)?;

println!("Added package to database");
println!("Your package is now ready for download!");
Ok(())
Expand All @@ -59,26 +56,30 @@ fn main() -> anyhow::Result<()> {
#[clap(author, version, about, long_about = None)]
struct Cli {
/// The directory to package up
#[clap(validator = dir_exists)]
#[arg(value_parser = dir_exists)]
directory: PathBuf,
#[clap(short, long, value_parser, validator=file_exists)]
#[clap(default_value = "packages/packagedb.sqlite")]
#[arg(short, long, value_parser, value_parser=file_exists)]
#[arg(default_value = "packages/packagedb.sqlite")]
db: PathBuf,
#[clap(short, long, value_parser, validator=dir_exists)]
#[clap(default_value = "packages/packages")]
#[arg(short, long, value_parser, value_parser=dir_exists)]
#[arg(default_value = "packages/packages")]
pkg_dir: PathBuf,
}

fn dir_exists(f: &str) -> Result<(), &'static str> {
Path::new(f)
.is_dir()
.then_some(())
.ok_or("Directory does not exist")
fn dir_exists(f: &str) -> Result<PathBuf, &'static str> {
let path = PathBuf::from(f);
if !path.is_dir() {
Err("Directory does not exist")
} else {
Ok(path)
}
}

fn file_exists(f: &str) -> Result<(), &'static str> {
Path::new(f)
.is_file()
.then_some(())
.ok_or("File does not exist")
fn file_exists(f: &str) -> Result<PathBuf, &'static str> {
let path = PathBuf::from(f);
if !path.is_file() {
Err("File does not exist")
} else {
Ok(path)
}
}
22 changes: 11 additions & 11 deletions dcspkg-create/src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,28 @@ use std::path::Path;
pub fn get_pkg_name(default: Option<&str>) -> Result<String> {
if let Some(default) = default {
Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter package name")
.with_prompt("Enter package short name")
.default(default.to_string())
.show_default(true)
.interact_text()
} else {
Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter package name")
.with_prompt("Enter package short name")
.show_default(true)
.interact_text()
}
.context("Could not get package name")
}

pub fn get_full_name(default: &str) -> Result<String> {
Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter full application name or game title")
.default(default.to_string())
.show_default(true)
.interact_text()
.context("Could not get package fullname")
}

pub fn get_description() -> Result<Option<String>> {
Input::<String>::with_theme(&ColorfulTheme::default())
.with_prompt("Enter package description")
Expand All @@ -27,15 +36,6 @@ pub fn get_description() -> Result<Option<String>> {
.context("Could not get description")
}

pub fn get_version() -> Result<String> {
Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter version")
.default("0.1.0".to_owned())
.validate_with(|input: &String| semver::Version::parse(input).map(|_| ()))
.interact_text()
.context("Could not get version")
}

pub fn get_image_url() -> Result<Option<String>> {
Input::<String>::with_theme(&ColorfulTheme::default())
.with_prompt("Enter URL for image")
Expand Down
2 changes: 1 addition & 1 deletion dcspkg-server/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub async fn get_package_by_name(
conn: &sqlx::SqlitePool,
name: &str,
) -> Result<Option<Package>, sqlx::Error> {
sqlx::query_as("SELECT * FROM packages WHERE name=?")
sqlx::query_as("SELECT * FROM packages WHERE pkgname=?")
.bind(name)
.fetch_optional(conn)
.await
Expand Down
4 changes: 1 addition & 3 deletions dcspkg-server/src/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ use serde::{Deserialize, Serialize};
pub struct Package {
/// The package's name, ie "gcc"
/// This is the primary key
pub name: String,
pub pkgname: String,
/// The game/app's full name/title, ie "The GNU Compiler Collection, Version 4.3"
pub fullname: String,
/// A short description of the package
#[sqlx(default)]
pub description: Option<String>,
/// A URL pointing to an image for the package
pub image_url: Option<String>,
/// The path to the package tarball on disk
pub archive_path: String,
/// The relative path of the executable within the tarball
pub executable_path: Option<String>,
/// The package's CRC checksum
Expand Down
10 changes: 4 additions & 6 deletions scripts/initdb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ mkdir -p packages/packages
touch packages/packagedb.sqlite
sqlite3 packages/packagedb.sqlite \
"CREATE TABLE packages(
id INTEGER PRIMARY KEY NOT NULL,
name STRING NOT NULL,
pkgname STRING PRIMARY KEY NOT NULL,
fullname STRING NOT NULL,
description STRING,
version STRING NOT NULL,
image_url STRING,
archive_path STRING NOT NULL,
executable_path STRING,
crc INTEGER NOT NULL,
has_installer INTEGER NOT NULL,
add_to_path INTEGER NOT NULL,
UNIQUE (name, version))"
add_to_path INTEGER NOT NULL)
"

0 comments on commit fe4e766

Please sign in to comment.