pub mod execute_commands;
use crate::errors;
use errors::NotebookError;
use sqlx::{self, PgPool};
use tracing::{event, Level};
pub struct Note {
pub id: i32,
pub note: Option<String>,
pub note_name: String,
}
impl Note {
pub async fn note_str(&mut self) -> String {
if let Some(some_note) = &self.note {
some_note.to_owned()
} else {
"".to_owned()
}
}
}
pub async fn display(notename: &str, pool: &PgPool) -> Result<(), NotebookError> {
let mut row = select_one(notename, pool).await?;
let row_note = row.note_str().await;
event!(
Level::INFO,
"Requested note:\nID: {}\nName: {}\nData:\n{}",
row.id,
row.note_name,
row_note
);
Ok(())
}
pub async fn display_all(pool: &PgPool) -> Result<(), NotebookError> {
let rows = sqlx::query!(
"
SELECT *
FROM notebook
"
)
.fetch_all(pool)
.await?;
event!(Level::INFO, "All notes in notebook:");
rows.iter().for_each(|row| {
let row_note = if let Some(n) = &row.note { n } else { "" };
event!(
Level::INFO,
"\nID: {}:\nName: {}\nData:\n{}",
row.id,
row.note_name,
row_note
);
});
Ok(())
}
pub async fn add(notename: &str, note: &str, pool: &PgPool) -> Result<Note, NotebookError> {
match sqlx::query!(
"
INSERT INTO notebook (note_name, note)
VALUES ( $1, $2 )
RETURNING id, note_name, note
",
notename,
note
)
.fetch_one(pool)
.await
{
Ok(row) => {
event!(
Level::INFO,
"Insert note with name `{}` with data `{}` into notebook",
notename,
note
);
Ok(Note {
id: row.id,
note: row.note,
note_name: row.note_name,
})
}
Err(err) => {
if let Some(db_err) = err.as_database_error() {
if let Some(code) = db_err.code() {
if code == "23505" {
return Err(NotebookError::AlreadyTaken {
notename: notename.to_owned(),
});
}
}
}
Err(err.into())
}
}
}
pub async fn del(notename: &str, pool: &PgPool) -> Result<(), NotebookError> {
match sqlx::query!(
"
DELETE FROM notebook
WHERE note_name = $1
RETURNING id, note_name, note
",
notename
)
.fetch_one(pool)
.await
{
Ok(row) => {
let row_note = if let Some(n) = &row.note { n } else { "" };
event!(
Level::INFO,
"Deleteing note:\nID: {}\nName: {}\nData:\n{}",
row.id,
notename,
row_note
);
Ok(())
}
Err(err) => Err(NotebookError::Sqlx(err)),
}
}
pub async fn del_all(pool: &PgPool) -> Result<(), NotebookError> {
match sqlx::query!(
"
DELETE FROM notebook
RETURNING id, note_name, note
"
)
.fetch_all(pool)
.await
{
Ok(del_rows) => {
del_rows.iter().for_each(|row| {
let row_note = if let Some(n) = &row.note { n } else { "" };
event!(
Level::INFO,
"Deleting ID: {}; Name: {}; Data:\n{}",
row.id,
row.note_name,
row_note
)
});
Ok(())
}
Err(err) => Err(NotebookError::Sqlx(err)),
}
}
pub async fn clear(notename: &str, pool: &PgPool) -> Result<(), NotebookError> {
match sqlx::query!(
"
UPDATE notebook
SET note = ''
WHERE note_name = $1
RETURNING note_name
",
notename
)
.fetch_one(pool)
.await
{
Ok(_) => {
event!(Level::INFO, "Content of `{}` was cleared", notename);
Ok(())
}
Err(err) => Err(NotebookError::Sqlx(err)),
}
}
pub async fn upd(notename: &str, new_note: &str, pool: &PgPool) -> Result<Note, NotebookError> {
match sqlx::query!(
"
UPDATE notebook
SET note = $1
WHERE note_name = $2
RETURNING id, note_name, note
",
new_note,
notename,
)
.fetch_one(pool)
.await
{
Ok(upd_row) => {
event!(Level::INFO, "Update `{}` data to:\n{}", notename, new_note,);
Ok(Note {
id: upd_row.id,
note_name: upd_row.note_name,
note: upd_row.note,
})
}
Err(err) => Err(NotebookError::Sqlx(err)),
}
}
pub async fn upd_notename(
notename: &str,
new_notename: &str,
pool: &PgPool,
) -> Result<Note, NotebookError> {
match sqlx::query!(
"
UPDATE notebook
SET note_name = $1
WHERE note_name = $2
RETURNING id, note_name, note
",
new_notename,
notename
)
.fetch_one(pool)
.await
{
Ok(upd_row) => {
event!(
Level::INFO,
"Update notename\nFrom: {}\nTo: {}",
notename,
new_notename
);
Ok(Note {
id: upd_row.id,
note_name: upd_row.note_name,
note: upd_row.note,
})
}
Err(err) => Err(NotebookError::Sqlx(err)),
}
}
pub async fn select_one(notename: &str, pool: &PgPool) -> Result<Note, NotebookError> {
let row = sqlx::query!(
"
SELECT *
FROM notebook
WHERE note_name = $1
",
notename
)
.fetch_one(pool)
.await?;
Ok(Note {
id: row.id,
note: row.note,
note_name: row.note_name,
})
}