Add user input database verification
This commit is contained in:
125
src/database.rs
125
src/database.rs
@@ -1,4 +1,7 @@
|
|||||||
|
use std::i64;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use ratatui::widgets::block::title;
|
||||||
use sqlx::{Row, SqlitePool};
|
use sqlx::{Row, SqlitePool};
|
||||||
|
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
@@ -7,11 +10,49 @@ pub struct Database {
|
|||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
pub async fn new() -> Result<Self> {
|
pub async fn new() -> Result<Self> {
|
||||||
let pool = SqlitePool::connect("sqlite:ratings.db").await?;
|
let pool = SqlitePool::connect("sqlite://ratings.db?mode=rwc").await?;
|
||||||
Ok(Database { pool })
|
Ok(Database { pool })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_user(&self, name: &str, number: i64) -> Result<i64> {
|
pub async fn create_tables(&self) -> Result<()> {
|
||||||
|
let mut conn = self.pool.acquire().await?;
|
||||||
|
|
||||||
|
let _ = sqlx::query(
|
||||||
|
r#"
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS interprets (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
interpret TEXT NOT NULL,
|
||||||
|
UNIQUE(interpret)
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS songs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
interpret_id INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY("interpret_id") REFERENCES interpret (id),
|
||||||
|
UNIQUE(title, interpret_id)
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS ratings (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
user_id INTEGER NOT NULL,
|
||||||
|
song_id INTEGER NOT NULL,
|
||||||
|
rating INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY("user_id") REFERENCES users (id),
|
||||||
|
FOREIGN KEY("song_id") REFERENCES songs (id),
|
||||||
|
UNIQUE(user_id, song_id)
|
||||||
|
);
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.execute(&mut *conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add_user(&self, user_id: i64, name: &str) -> Result<i64> {
|
||||||
let mut conn = self.pool.acquire().await?;
|
let mut conn = self.pool.acquire().await?;
|
||||||
|
|
||||||
let id = sqlx::query(
|
let id = sqlx::query(
|
||||||
@@ -20,8 +61,8 @@ impl Database {
|
|||||||
VALUES (?1, ?2)
|
VALUES (?1, ?2)
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
|
.bind(user_id)
|
||||||
.bind(name)
|
.bind(name)
|
||||||
.bind(number)
|
|
||||||
.execute(&mut *conn)
|
.execute(&mut *conn)
|
||||||
.await?
|
.await?
|
||||||
.last_insert_rowid();
|
.last_insert_rowid();
|
||||||
@@ -29,7 +70,7 @@ impl Database {
|
|||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn user_exists(&self, number: i64) -> Result<i64> {
|
pub async fn user_exists(&self, user_id: i64) -> Result<i64> {
|
||||||
let mut conn = self.pool.acquire().await?;
|
let mut conn = self.pool.acquire().await?;
|
||||||
|
|
||||||
let record = sqlx::query(
|
let record = sqlx::query(
|
||||||
@@ -38,7 +79,7 @@ impl Database {
|
|||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(number)
|
.bind(user_id)
|
||||||
.fetch_one(&mut *conn)
|
.fetch_one(&mut *conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -46,4 +87,78 @@ impl Database {
|
|||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn user_add_rating(
|
||||||
|
&self,
|
||||||
|
user_id: i64,
|
||||||
|
interpret: &str,
|
||||||
|
song: &str,
|
||||||
|
rating: i64,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut conn = self.pool.acquire().await?;
|
||||||
|
|
||||||
|
// Add interpret
|
||||||
|
let _ = sqlx::query(
|
||||||
|
r#"
|
||||||
|
INSERT OR IGNORE INTO interprets (interpret)
|
||||||
|
VALUES (?1)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(interpret)
|
||||||
|
.execute(&mut *conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Get the interpret ID
|
||||||
|
let record = sqlx::query(
|
||||||
|
r#"
|
||||||
|
SELECT id FROM interprets
|
||||||
|
WHERE interpret = ?1
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(interpret)
|
||||||
|
.fetch_one(&mut *conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let interpret_id: i64 = record.try_get("id")?;
|
||||||
|
|
||||||
|
// Add the song
|
||||||
|
let _ = sqlx::query(
|
||||||
|
r#"
|
||||||
|
INSERT OR IGNORE INTO songs (title, interpret_id)
|
||||||
|
VALUES (?1, ?2)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(song)
|
||||||
|
.bind(interpret_id)
|
||||||
|
.execute(&mut *conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Get the song ID
|
||||||
|
let record = sqlx::query(
|
||||||
|
r#"
|
||||||
|
SELECT id FROM songs
|
||||||
|
WHERE title = ?1
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(song)
|
||||||
|
.fetch_one(&mut *conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let song_id: i64 = record.try_get("id")?;
|
||||||
|
|
||||||
|
// Add the rating
|
||||||
|
let _ = sqlx::query(
|
||||||
|
r#"
|
||||||
|
INSERT INTO ratings (user_id, song_id, rating)
|
||||||
|
VALUES (?1, ?2, ?3)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(user_id)
|
||||||
|
.bind(song_id)
|
||||||
|
.bind(rating)
|
||||||
|
.execute(&mut *conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,10 +8,17 @@ use tokio;
|
|||||||
async fn main() {
|
async fn main() {
|
||||||
let player = player::MprisPlayer::new().expect("Could not create player");
|
let player = player::MprisPlayer::new().expect("Could not create player");
|
||||||
|
|
||||||
let (usernumber, userrating) = userinterface::get_user_rating().expect("Lala");
|
let db = database::Database::new()
|
||||||
|
.await
|
||||||
|
.expect("Could not create database");
|
||||||
|
|
||||||
|
let (usernumber, userrating) = userinterface::get_user_rating(&db).await.expect("Lala");
|
||||||
|
|
||||||
let track = player
|
let track = player
|
||||||
.get_interpret_and_track()
|
.get_interpret_and_track()
|
||||||
.expect("Could not read track");
|
.expect("Could not read track");
|
||||||
println!("User: {usernumber} with rating: {userrating}: {track}");
|
println!("User: {usernumber} with rating: {userrating}: {track}");
|
||||||
|
|
||||||
|
db.create_tables().await.unwrap();
|
||||||
|
//db.add_user(1, "Janek").await.unwrap();
|
||||||
}
|
}
|
||||||
|
@@ -12,8 +12,11 @@ use tui_textarea::{Input, Key, TextArea};
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
fn validate_user(textarea: &mut TextArea) -> bool {
|
use crate::database::Database;
|
||||||
if let Err(_) = textarea.lines()[0].parse::<u64>() {
|
|
||||||
|
async fn validate_user(textarea: &mut TextArea<'_>, db: &Database) -> bool {
|
||||||
|
match textarea.lines()[0].parse::<u64>() {
|
||||||
|
Err(_) => {
|
||||||
textarea.set_style(Style::default().fg(Color::LightRed));
|
textarea.set_style(Style::default().fg(Color::LightRed));
|
||||||
textarea.set_block(
|
textarea.set_block(
|
||||||
Block::default()
|
Block::default()
|
||||||
@@ -21,10 +24,23 @@ fn validate_user(textarea: &mut TextArea) -> bool {
|
|||||||
.title(format!("ERROR: Please enter a valid user number")),
|
.title(format!("ERROR: Please enter a valid user number")),
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
} else {
|
}
|
||||||
|
Ok(value) => {
|
||||||
|
let db_user = db.user_exists(value as i64).await.is_ok();
|
||||||
|
if db_user {
|
||||||
textarea.set_style(Style::default().fg(Color::LightGreen));
|
textarea.set_style(Style::default().fg(Color::LightGreen));
|
||||||
textarea.set_block(Block::default().borders(Borders::ALL).title("OK"));
|
textarea.set_block(Block::default().borders(Borders::ALL).title("OK"));
|
||||||
true
|
true
|
||||||
|
} else {
|
||||||
|
textarea.set_style(Style::default().fg(Color::LightRed));
|
||||||
|
textarea.set_block(
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.title(format!("ERROR: Please enter a valid user number")),
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +72,7 @@ fn validate_rating(textarea: &mut TextArea) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_user_rating() -> Result<(String, String)> {
|
pub async fn get_user_rating(db: &Database) -> Result<(String, String)> {
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
let mut stdout = stdout.lock();
|
let mut stdout = stdout.lock();
|
||||||
|
|
||||||
@@ -70,7 +86,7 @@ pub fn get_user_rating() -> Result<(String, String)> {
|
|||||||
textarea.set_placeholder_text("USER: Enter a valid user number (e.g. 156)");
|
textarea.set_placeholder_text("USER: Enter a valid user number (e.g. 156)");
|
||||||
let layout =
|
let layout =
|
||||||
Layout::default().constraints([Constraint::Length(3), Constraint::Min(1)].as_slice());
|
Layout::default().constraints([Constraint::Length(3), Constraint::Min(1)].as_slice());
|
||||||
let mut is_valid = validate_user(&mut textarea);
|
let mut is_valid = validate_user(&mut textarea, db).await;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
term.draw(|f| {
|
term.draw(|f| {
|
||||||
@@ -95,7 +111,7 @@ pub fn get_user_rating() -> Result<(String, String)> {
|
|||||||
input => {
|
input => {
|
||||||
// TextArea::input returns if the input modified its text
|
// TextArea::input returns if the input modified its text
|
||||||
if textarea.input(input) {
|
if textarea.input(input) {
|
||||||
is_valid = validate_user(&mut textarea);
|
is_valid = validate_user(&mut textarea, db).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user