Upgrade Diesel 1.x to 2.x and move the db to sqlite
parent
031abd96ce
commit
df669e8b78
|
@ -12,4 +12,9 @@ proyectos
|
|||
Rocket.toml
|
||||
|
||||
# Certificates
|
||||
*.pem
|
||||
*.pem
|
||||
|
||||
# Sqlite database
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
|
@ -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"] }
|
||||
|
|
|
@ -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();
|
|
@ -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;
|
|
@ -1 +0,0 @@
|
|||
DROP TABLE posts
|
|
@ -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()
|
||||
)
|
||||
|
|
@ -0,0 +1 @@
|
|||
-- This file should undo anything in `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
|
||||
);
|
18
src/admin.rs
18
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"))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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("")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue