diff --git a/.gitignore b/.gitignore index 6c37690..4909f2f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,9 @@ proyectos Rocket.toml # Certificates -*.pem \ No newline at end of file +*.pem + +# Sqlite database +*.db +*.sqlite +*.sqlite3 \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index ad2eaa2..6322794 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] rocket = { version = "0.5.0", features = ["secrets"] } rocket_dyn_templates = { version = "0.1.0", features = ["tera"] } -diesel = { version = "1.0.0", features = ["postgres", "chrono"] } +diesel = { version = "2.0.0", features = ["sqlite", "chrono", "returning_clauses_for_sqlite_3_35"] } dotenv = "0.15.0" rand = "0.8.5" chrono = { version = "0.4.9", features = ["serde"] } diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql deleted file mode 100644 index a9f5260..0000000 --- a/migrations/00000000000000_diesel_initial_setup/down.sql +++ /dev/null @@ -1,6 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - -DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); -DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql deleted file mode 100644 index d68895b..0000000 --- a/migrations/00000000000000_diesel_initial_setup/up.sql +++ /dev/null @@ -1,36 +0,0 @@ --- This file was automatically created by Diesel to setup helper functions --- and other internal bookkeeping. This file is safe to edit, any future --- changes will be added to existing projects as new migrations. - - - - --- Sets up a trigger for the given table to automatically set a column called --- `updated_at` whenever the row is modified (unless `updated_at` was included --- in the modified columns) --- --- # Example --- --- ```sql --- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); --- --- SELECT diesel_manage_updated_at('users'); --- ``` -CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ -BEGIN - EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s - FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ -BEGIN - IF ( - NEW IS DISTINCT FROM OLD AND - NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at - ) THEN - NEW.updated_at := current_timestamp; - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; diff --git a/migrations/2022-12-22-062417_create_posts/down.sql b/migrations/2022-12-22-062417_create_posts/down.sql deleted file mode 100644 index b1eab72..0000000 --- a/migrations/2022-12-22-062417_create_posts/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE posts diff --git a/migrations/2022-12-22-062417_create_posts/up.sql b/migrations/2022-12-22-062417_create_posts/up.sql deleted file mode 100644 index c007206..0000000 --- a/migrations/2022-12-22-062417_create_posts/up.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE posts ( - id SERIAL PRIMARY KEY, - title VARCHAR NOT NULL, - content TEXT NOT NULL, - published BOOLEAN NOT NULL DEFAULT 'f', - views integer NOT NULL DEFAULT 0, - created_at TIMESTAMP NOT NULL DEFAULT NOW(), - updated_at TIMESTAMP NOT NULL DEFAULT NOW() -) - diff --git a/migrations/2025-04-11-054642_create_db/down.sql b/migrations/2025-04-11-054642_create_db/down.sql new file mode 100644 index 0000000..d9a93fe --- /dev/null +++ b/migrations/2025-04-11-054642_create_db/down.sql @@ -0,0 +1 @@ +-- This file should undo anything in `up.sql` diff --git a/migrations/2025-04-11-054642_create_db/up.sql b/migrations/2025-04-11-054642_create_db/up.sql new file mode 100644 index 0000000..b226103 --- /dev/null +++ b/migrations/2025-04-11-054642_create_db/up.sql @@ -0,0 +1,9 @@ +CREATE TABLE posts ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + content TEXT NOT NULL, + published BOOLEAN NOT NULL DEFAULT 0, + views INTEGER NOT NULL DEFAULT 0, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); diff --git a/src/admin.rs b/src/admin.rs index 111d77c..f6b786f 100644 --- a/src/admin.rs +++ b/src/admin.rs @@ -50,7 +50,7 @@ fn login(cookies: &CookieJar<'_>, login: Form<Login>) -> Redirect { } #[get("/panel")] -fn panel(cookies: &CookieJar<'_>) -> Result<Template, Redirect> { +fn panel(cookies: &CookieJar<'_>) -> Result<Template, Box<Redirect>> { let password = env::var("admin_pass").expect("admin_pass not setted"); match cookies.get_private("user") { @@ -62,15 +62,15 @@ fn panel(cookies: &CookieJar<'_>) -> Result<Template, Redirect> { Ok(Template::render("admin/panel", context)) } else { - Err(Redirect::to("/admin")) + Err(Box::new(Redirect::to("/admin"))) } } - None => Err(Redirect::to("/admin")), + None => Err(Box::new(Redirect::to("/admin"))), } } #[get("/add_post")] -fn add_post(cookies: &CookieJar<'_>) -> Result<Template, Redirect> { +fn add_post(cookies: &CookieJar<'_>) -> Result<Template, Box<Redirect>> { let password = env::var("admin_pass").expect("admin_pass not setted"); match cookies.get_private("user") { @@ -80,10 +80,10 @@ fn add_post(cookies: &CookieJar<'_>) -> Result<Template, Redirect> { Ok(Template::render("admin/add_post", context)) } else { - Err(Redirect::to("/admin")) + Err(Box::new(Redirect::to("/admin"))) } } - None => Err(Redirect::to("/admin")), + None => Err(Box::new(Redirect::to("/admin"))), } } @@ -107,7 +107,7 @@ fn write_add_post(cookies: &CookieJar<'_>, post: Form<NewPost>) -> Redirect { } #[get("/edit_post/<id>")] -fn edit_post(cookies: &CookieJar<'_>, id: i32) -> Result<Template, Redirect> { +fn edit_post(cookies: &CookieJar<'_>, id: i32) -> Result<Template, Box<Redirect>> { let password = env::var("admin_pass").expect("admin_pass not setted"); match cookies.get_private("user") { @@ -119,10 +119,10 @@ fn edit_post(cookies: &CookieJar<'_>, id: i32) -> Result<Template, Redirect> { Ok(Template::render("admin/edit_post", context)) } else { - Err(Redirect::to("/admin")) + Err(Box::new(Redirect::to("/admin"))) } } - None => Err(Redirect::to("/admin")), + None => Err(Box::new(Redirect::to("/admin"))), } } diff --git a/src/controllers.rs b/src/controllers.rs index 8493090..4b301c3 100644 --- a/src/controllers.rs +++ b/src/controllers.rs @@ -1,17 +1,18 @@ use chrono::prelude::Utc; -use diesel::pg::PgConnection; +use diesel::sqlite::SqliteConnection; use diesel::result::Error; use diesel::Connection; use diesel::ExpressionMethods; use diesel::QueryDsl; use diesel::RunQueryDsl; +use diesel::SelectableHelper; use std::env; use std::vec::Vec; -fn establish_connection() -> PgConnection { +fn establish_connection() -> SqliteConnection { let database_url = env::var("DATABASE_URL").expect("DATABASE_URL not setted"); - PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url)) + SqliteConnection::establish(&database_url).unwrap_or_else(|_| panic!("Error connecting to {}", database_url)) } pub mod posts { @@ -23,24 +24,24 @@ pub mod posts { pub fn get_posts(page: Option<u64>) -> (Vec<Post>, i64) { use crate::schema::posts::dsl::*; - let connection = establish_connection(); + let connection = &mut establish_connection(); let visible_posts = posts.order(created_at.desc()); let visible_posts = match page { Some(number_page) => visible_posts .filter(published.eq(true)) .limit(MAX_POSTS_PER_PAGE as i64) .offset((MAX_POSTS_PER_PAGE * (number_page - 1)) as i64) - .load::<Post>(&connection) + .load::<Post>(connection) .expect("Error loading posts"), None => visible_posts - .load::<Post>(&connection) + .load::<Post>(connection) .expect("Error loading posts"), }; let number_of_posts: i64 = posts .filter(published.eq(true)) .count() - .get_result(&connection) + .get_result(connection) .expect("Error counting the posts"); (visible_posts, number_of_posts) @@ -49,24 +50,25 @@ pub mod posts { pub fn get_post(id_number: i32) -> Result<Post, Error> { use crate::schema::posts::dsl::*; - let connection = establish_connection(); - let post = posts.find(id_number).first(&connection); + let connection = &mut establish_connection(); + + posts.find(id_number).first(connection) - post } pub fn add_post(new_post: &NewPost) -> Result<Post, Error> { use crate::schema::posts; - let connection = establish_connection(); + let connection = &mut establish_connection(); diesel::insert_into(posts::table) .values(new_post) - .get_result(&connection) + .returning(Post::as_returning()) + .get_result(connection) } pub fn edit_post(updated_id: i32, new_post: &NewPost) -> Result<Post, Error> { use crate::schema::posts::dsl::*; - let connection = establish_connection(); + let connection = &mut establish_connection(); let date = Utc::now().naive_utc(); @@ -77,16 +79,17 @@ pub mod posts { published.eq(&new_post.published), updated_at.eq(&date), )) - .get_result(&connection) + .returning(Post::as_returning()) + .get_result(connection) } pub fn add_visit(post_id: i32) { use crate::schema::posts::dsl::*; - let connection = establish_connection(); + let connection = &mut establish_connection(); diesel::update(posts.filter(id.eq(post_id))) .set(views.eq(views + 1)) - .execute(&connection) + .execute(connection) .unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 3a973e2..af87514 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ mod schema; -#[macro_use] extern crate diesel; #[macro_use] @@ -22,7 +21,7 @@ use std::vec::Vec; static BOTS: OnceCell<Bots> = OnceCell::const_new(); -async fn is_bot(ua: &String) -> bool { +async fn is_bot(ua: &str) -> bool { let bots = BOTS.get_or_init(|| async { Bots::default() }).await; bots.is_bot(ua) } diff --git a/src/misc.rs b/src/misc.rs index 9de44f0..b98a1a0 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -59,7 +59,7 @@ pub fn ascii_table(raw_table: String) -> String { let index_subrow = index / row.len(); let index_col = index % row.len(); let text = if let Some(col) = row.get(index_col) { - if let Some(&ref text) = col.get(index_subrow) { + if let Some(text) = col.get(index_subrow) { text } else { &String::from("") diff --git a/src/models.rs b/src/models.rs index 429d53c..84076f2 100644 --- a/src/models.rs +++ b/src/models.rs @@ -3,7 +3,9 @@ use serde::Serialize; use super::schema::posts; -#[derive(Queryable, Serialize)] +#[derive(Queryable, Selectable, Serialize)] +#[diesel(table_name = posts)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] pub struct Post { pub id: i32, pub title: String, @@ -15,7 +17,7 @@ pub struct Post { } #[derive(FromForm, Insertable, Debug)] -#[table_name = "posts"] +#[diesel(table_name = posts)] pub struct NewPost { pub title: String, pub content: String, diff --git a/src/schema.rs b/src/schema.rs index 0769d7e..d6d3e0b 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -2,11 +2,11 @@ diesel::table! { posts (id) { - id -> Int4, - title -> Varchar, + id -> Integer, + title -> Text, content -> Text, published -> Bool, - views -> Int4, + views -> Integer, created_at -> Timestamp, updated_at -> Timestamp, }