(feat) Switched to sqlx.
Signed-off-by: Louis Hollingworth <louis@hollingworth.nl>
This commit is contained in:
parent
f267d6b285
commit
ba4216c21e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@
|
|||
/target
|
||||
.DS_Store
|
||||
.env
|
||||
/.sqlx
|
||||
|
|
1040
Cargo.lock
generated
1040
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -19,11 +19,15 @@ argon2 = { version = "0.5.2", features = ["password-hash", "std"] }
|
|||
axum = {version = "0.6.20", features = ["macros"]}
|
||||
chrono = {version = "0.4.31", features = ["serde"]}
|
||||
crypto = { version = "0.5.1", features = ["password-hash"] }
|
||||
diesel = { version = "2.1.3", features = ["postgres", "extras", "uuid", "r2d2"] }
|
||||
diesel_migrations = { version = "2.1.0", features = ["postgres"] }
|
||||
dotenvy = "0.15.7"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.189", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
tokio = { version = "1.33.0", features = ["full"] }
|
||||
uuid = { version = "1.0.0", features = ["serde", "v4", "v7"] }
|
||||
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres", "macros", "migrate", "uuid", "chrono", "json"] }
|
||||
anyhow = "1.0.75"
|
||||
thiserror = "1.0.50"
|
||||
|
||||
[profile.dev.package.sqlx-macros]
|
||||
opt-level = 3
|
||||
|
|
13
diesel.toml
13
diesel.toml
|
@ -1,13 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# For documentation on how to configure this file,
|
||||
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
||||
custom_type_derives = ["diesel::query_builder::QueryId"]
|
||||
|
||||
[migrations_directory]
|
||||
dir = "migrations"
|
|
@ -1,42 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- 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,6 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE posts;
|
|
@ -1,17 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- Your SQL goes here
|
||||
|
||||
CREATE TABLE posts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
slug VARCHAR NOT NULL,
|
||||
title VARCHAR NOT NULL,
|
||||
body TEXT NOT NULL,
|
||||
published BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
SELECT diesel_manage_updated_at('posts');
|
|
@ -1,6 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE blogs;
|
|
@ -1,18 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE blogs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
slug VARCHAR NOT NULL,
|
||||
name VARCHAR NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
SELECT diesel_manage_updated_at('blogs');
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- This file should undo anything in `up.sql`
|
||||
|
||||
ALTER TABLE posts
|
||||
DROP COLUMN blog_id;
|
|
@ -1,8 +0,0 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- Your SQL goes here
|
||||
|
||||
ALTER TABLE posts
|
||||
ADD COLUMN blog_id INTEGER NOT NULL REFERENCES blogs(id);
|
|
@ -2,9 +2,6 @@
|
|||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- 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.
|
||||
|
||||
-- Add down migration script here
|
||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
24
migrations/20231026121809_init.up.sql
Normal file
24
migrations/20231026121809_init.up.sql
Normal file
|
@ -0,0 +1,24 @@
|
|||
-- SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- Add up migration script here
|
||||
|
||||
CREATE OR REPLACE FUNCTION 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 set_updated_at()', _tbl);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION 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 := NOW();
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql
|
|
@ -2,5 +2,5 @@
|
|||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- This file should undo anything in `up.sql`
|
||||
-- Add down migration script here
|
||||
DROP TABLE users;
|
|
@ -2,17 +2,16 @@
|
|||
--
|
||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
-- Your SQL goes here
|
||||
-- Add up migration script here
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
username VARCHAR NOT NULL,
|
||||
epost VARCHAR NOT NULL,
|
||||
username VARCHAR UNIQUE NOT NULL,
|
||||
epost VARCHAR UNIQUE NOT NULL,
|
||||
pass VARCHAR NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
main_fedi TEXT,
|
||||
UNIQUE(username, epost)
|
||||
main_fedi TEXT
|
||||
);
|
||||
SELECT diesel_manage_updated_at('users');
|
||||
SELECT manage_updated_at('users');
|
55
src/lib.rs
55
src/lib.rs
|
@ -2,27 +2,52 @@
|
|||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
use diesel::prelude::*;
|
||||
use thiserror::Error;
|
||||
|
||||
pub type DbPool = diesel::r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FbError {
|
||||
#[error("Database Error: {0}")]
|
||||
DbError(sqlx::Error),
|
||||
|
||||
pub fn establish_connection() -> diesel::pg::PgConnection {
|
||||
#[error("Internal Error: {0}")]
|
||||
IError(String)
|
||||
}
|
||||
|
||||
pub async fn connection_pool() -> Result<sqlx::Pool<sqlx::Postgres>, sqlx::Error> {
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||
diesel::pg::PgConnection::establish(&database_url)
|
||||
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
|
||||
|
||||
Ok(sqlx::postgres::PgPoolOptions::new()
|
||||
.max_connections(5)
|
||||
.connect(&database_url).await?)
|
||||
}
|
||||
|
||||
pub fn connection_pool() -> DbPool {
|
||||
dotenvy::dotenv().ok();
|
||||
pub async fn get_user_by_name_for_auth(username: String, pool: sqlx::Pool<sqlx::Postgres>) -> Result<models::user::AuthUser, sqlx::Error> {
|
||||
let user = sqlx::query_as!(models::user::AuthUser, "SELECT id, username, pass FROM users WHERE username = $1", username).fetch_one(&pool).await.unwrap();
|
||||
|
||||
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||
let manager = diesel::r2d2::ConnectionManager::<diesel::PgConnection>::new(database_url);
|
||||
|
||||
diesel::r2d2::Pool::builder()
|
||||
.test_on_check_out(true)
|
||||
.build(manager)
|
||||
.expect("Could not build connection pool")
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_all_users(pool: sqlx::Pool<sqlx::Postgres>) -> Result<Vec<models::user::User>, sqlx::Error> {
|
||||
let users = sqlx::query_as!(models::user::User, "SELECT * FROM users").fetch_all(&pool).await.unwrap();
|
||||
|
||||
Ok(users)
|
||||
}
|
||||
|
||||
/// Creates user in database. No need to salt and hash the password, the function does it for you.
|
||||
pub async fn create_user(user: models::user::NewUser, pool: sqlx::Pool<sqlx::Postgres>) -> Result<(), FbError> {
|
||||
use argon2::password_hash::{PasswordHasher, SaltString};
|
||||
|
||||
let argon = argon2::Argon2::default();
|
||||
let salt = SaltString::generate(&mut rand::thread_rng());
|
||||
let hashed: String = match argon.hash_password(&user.pass.into_bytes(), &salt) {
|
||||
Err(_) => return Err(FbError::IError("Error while hashing password".to_string())),
|
||||
Ok(pswd) => pswd.to_string()
|
||||
};
|
||||
let _ = sqlx::query_as!(models::user::NewUser, "
|
||||
INSERT INTO users (username, epost, pass)
|
||||
VALUES ($1, $2, $3)", user.username, user.epost, hashed).execute(&pool).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
|
114
src/main.rs
114
src/main.rs
|
@ -3,18 +3,16 @@
|
|||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
use argon2::password_hash::{PasswordHasher, SaltString};
|
||||
use axum::{routing::{get, post}, Router, response::Json, extract::State};
|
||||
use diesel::prelude::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let pool: fediblog::DbPool = fediblog::connection_pool();
|
||||
let pool = fediblog::connection_pool().await.unwrap();
|
||||
|
||||
let app = Router::new()
|
||||
.route("/health", get(health_check))
|
||||
.route("/api/v0/user", post(create_user))
|
||||
.route("/api/v0/user", get(get_user))
|
||||
// .route("/api/v0/user", get(get_user))
|
||||
.with_state(pool);
|
||||
|
||||
axum::Server::bind(&"0.0.0.0:7654".parse().unwrap())
|
||||
|
@ -23,115 +21,17 @@ async fn main() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
async fn create_user(
|
||||
State(pool): State<fediblog::DbPool>,
|
||||
Json(new_user): Json<NewUser>,
|
||||
) -> Result<Json<UserResponse>, (axum::http::StatusCode, String)> {
|
||||
use fediblog::schema::users::dsl::*;
|
||||
let argon = argon2::Argon2::default();
|
||||
let salt = SaltString::generate(&mut rand::thread_rng());
|
||||
let hashed_pass: String = match argon.hash_password(&new_user.pass.into_bytes(), &salt) {
|
||||
Err(_) => {
|
||||
return Err((
|
||||
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Error hashing password".to_string(),
|
||||
))
|
||||
}
|
||||
Ok(pswd) => pswd.to_string(),
|
||||
};
|
||||
diesel::insert_into(users)
|
||||
.values((
|
||||
username.eq(new_user.username.clone()),
|
||||
epost.eq(new_user.epost.clone()),
|
||||
pass.eq(hashed_pass),
|
||||
))
|
||||
.execute(&mut pool.get().unwrap())
|
||||
.expect("Error saving new user");
|
||||
State(pool): State<sqlx::Pool<sqlx::Postgres>>,
|
||||
Json(u): Json<fediblog::models::user::NewUser>
|
||||
) -> &'static str {
|
||||
let _ = fediblog::create_user(u, pool).await;
|
||||
|
||||
let uid = get_userid_from_name(new_user.username.clone(), &mut pool.get().unwrap());
|
||||
|
||||
match uid {
|
||||
None => return Err((axum::http::StatusCode::INTERNAL_SERVER_ERROR, "There was an error creating this account".to_string())),
|
||||
Some(user_id) => return Ok(Json(
|
||||
UserResponse {
|
||||
id: user_id,
|
||||
username: new_user.username,
|
||||
epost: Some(new_user.epost.to_string()),
|
||||
main_fedi: None
|
||||
}
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_userid_from_name(username: String, pool: &mut diesel::r2d2::PooledConnection<diesel::r2d2::ConnectionManager<diesel::PgConnection>>) -> Option<uuid::Uuid> {
|
||||
let uv: Result<Vec<fediblog::models::BaseUser>, diesel::result::Error> = pool.build_transaction().read_only().run(|conn| {
|
||||
let userv = fediblog::schema::users::dsl::users
|
||||
.select((fediblog::schema::users::dsl::id, fediblog::schema::users::dsl::username))
|
||||
.load::<fediblog::models::BaseUser>(conn);
|
||||
Ok(userv.unwrap())
|
||||
});
|
||||
|
||||
find_userid_from_base_user(uv.unwrap(), username)
|
||||
}
|
||||
|
||||
fn find_userid_from_base_user(usrs: Vec<fediblog::models::BaseUser>, usrn: String) -> Option<uuid::Uuid> {
|
||||
for u in usrs {
|
||||
if u.username == usrn {
|
||||
return Some(u.id);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
async fn get_user(
|
||||
State(pool): State<fediblog::DbPool>,
|
||||
Json(auth_user): Json<AuthUser>
|
||||
) ->Result<Json<UserResponse>, (axum::http::StatusCode, String)> {
|
||||
let conn = &mut pool.get().unwrap();
|
||||
|
||||
let uid = get_userid_from_name(auth_user.username, conn).unwrap();
|
||||
|
||||
|
||||
let userv = diesel::sql_query(format!("SELECT * FROM users WHERE id = {}", uid.to_string())).load::<fediblog::models::User>(conn);
|
||||
|
||||
match userv {
|
||||
Ok(usrs) => return Ok(Json(UserResponse{
|
||||
id: usrs[0].id,
|
||||
|
||||
}))
|
||||
}
|
||||
|
||||
Ok(Json(UserResponse{
|
||||
id: user.id,
|
||||
username: user.username.clone(),
|
||||
epost: None,
|
||||
main_fedi: None
|
||||
}))
|
||||
"All done :)"
|
||||
}
|
||||
|
||||
async fn health_check() -> &'static str {
|
||||
"Saluton, amiko! Looks like we are running!"
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
||||
struct NewUser {
|
||||
username: String,
|
||||
epost: String,
|
||||
pass: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
||||
struct AuthUser {
|
||||
username: String,
|
||||
pass: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
struct UserResponse {
|
||||
id: uuid::Uuid,
|
||||
username: String,
|
||||
epost: Option<String>,
|
||||
main_fedi: Option<String>,
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use diesel::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(
|
||||
Selectable, Debug, Queryable, QueryableByName
|
||||
)]
|
||||
#[diesel(table_name = crate::schema::users)]
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct User {
|
||||
pub id: Uuid,
|
||||
pub username: String,
|
||||
pub epost: String,
|
||||
pub pass: String,
|
||||
pub created_at: chrono::NaiveDateTime,
|
||||
pub updated_at: chrono::NaiveDateTime,
|
||||
pub main_fedi: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Queryable, PartialEq, Debug)]
|
||||
#[diesel(table_name = crate::schema::users)]
|
||||
pub struct BaseUser {
|
||||
pub id: Uuid,
|
||||
pub username: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug, Selectable)]
|
||||
#[diesel(table_name = crate::schema::users)]
|
||||
pub struct NewUser {
|
||||
pub username: String,
|
||||
pub epost: String,
|
||||
pub pass: String
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Identifiable, Associations, Debug, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
#[diesel(belongs_to(User))]
|
||||
#[diesel(table_name = crate::schema::blogs)]
|
||||
pub struct Blog {
|
||||
pub id: isize,
|
||||
pub slug: String,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub url: String,
|
||||
pub user_id: Uuid,
|
||||
pub created_at: chrono::NaiveDateTime,
|
||||
pub updated_at: chrono::NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Identifiable, Associations, Debug, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
#[diesel(belongs_to(User))]
|
||||
#[diesel(belongs_to(Blog))]
|
||||
#[diesel(table_name = crate::schema::posts)]
|
||||
pub struct Post {
|
||||
pub id: isize,
|
||||
pub slug: String,
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub published: bool,
|
||||
pub user_id: Uuid,
|
||||
pub blog_id: isize,
|
||||
pub created_at: chrono::NaiveDateTime,
|
||||
pub updated_at: chrono::NaiveDateTime,
|
||||
}
|
5
src/models/mod.rs
Normal file
5
src/models/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
// SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
pub mod user;
|
28
src/models/user.rs
Normal file
28
src/models/user.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct AuthUser {
|
||||
pub id: uuid::Uuid,
|
||||
pub username: String,
|
||||
pub pass: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct NewUser {
|
||||
pub username: String,
|
||||
pub pass: String,
|
||||
pub epost: String
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, sqlx::FromRow)]
|
||||
pub struct User {
|
||||
pub id: uuid::Uuid,
|
||||
pub username: String,
|
||||
pub epost: String,
|
||||
pub pass: String,
|
||||
pub created_at: chrono::NaiveDateTime,
|
||||
pub updated_at: chrono::NaiveDateTime,
|
||||
pub main_fedi: Option<String>
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2023 Louis Hollingworth <louis@hollingworth.nl>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
blogs (id) {
|
||||
id -> Int4,
|
||||
slug -> Varchar,
|
||||
name -> Varchar,
|
||||
description -> Text,
|
||||
url -> Text,
|
||||
user_id -> Uuid,
|
||||
created_at -> Timestamp,
|
||||
updated_at -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
posts (id) {
|
||||
id -> Int4,
|
||||
slug -> Varchar,
|
||||
title -> Varchar,
|
||||
body -> Text,
|
||||
published -> Bool,
|
||||
user_id -> Uuid,
|
||||
created_at -> Timestamp,
|
||||
updated_at -> Timestamp,
|
||||
blog_id -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users (id) {
|
||||
id -> Uuid,
|
||||
username -> Varchar,
|
||||
epost -> Varchar,
|
||||
pass -> Varchar,
|
||||
created_at -> Timestamp,
|
||||
updated_at -> Timestamp,
|
||||
main_fedi -> Nullable<Text>,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(blogs -> users (user_id));
|
||||
diesel::joinable!(posts -> blogs (blog_id));
|
||||
diesel::joinable!(posts -> users (user_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
blogs,
|
||||
posts,
|
||||
users,
|
||||
);
|
Loading…
Reference in a new issue