diff --git a/.gitignore b/.gitignore index ea8c4bf..8766f8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +/postgres +.env diff --git a/Cargo.lock b/Cargo.lock index 8a476da..5183a31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,58 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "diesel" +version = "2.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" +dependencies = [ + "bitflags", + "byteorder", + "diesel_derives", + "itoa", + "pq-sys", +] + +[[package]] +name = "diesel_derives" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" +dependencies = [ + "diesel_table_macro_syntax", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +dependencies = [ + "syn", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "itoa" version = "1.0.10" @@ -12,10 +64,21 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" name = "nushtyu" version = "0.1.0" dependencies = [ + "diesel", + "dotenvy", "serde", "serde_json", ] +[[package]] +name = "pq-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c0052426df997c0cbd30789eb44ca097e3541717a7b8fa36b1c464ee7edebd" +dependencies = [ + "vcpkg", +] + [[package]] name = "proc-macro2" version = "1.0.78" @@ -87,3 +150,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" diff --git a/Cargo.toml b/Cargo.toml index f529015..2abf9b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,5 @@ edition = "2021" [dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +diesel = { version = "2.1.0", features = ["postgres"] } +dotenvy = "0.15" diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..c028f4a --- /dev/null +++ b/diesel.toml @@ -0,0 +1,9 @@ +# 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" diff --git a/migrations/.keep b/migrations/.keep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 0000000..a9f5260 --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,6 @@ +-- 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 new file mode 100644 index 0000000..d68895b --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/up.sql @@ -0,0 +1,36 @@ +-- 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/2024-02-18-103848_create_users/down.sql b/migrations/2024-02-18-103848_create_users/down.sql new file mode 100644 index 0000000..cf7e736 --- /dev/null +++ b/migrations/2024-02-18-103848_create_users/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +DROP TABLE users diff --git a/migrations/2024-02-18-103848_create_users/up.sql b/migrations/2024-02-18-103848_create_users/up.sql new file mode 100644 index 0000000..e310ed8 --- /dev/null +++ b/migrations/2024-02-18-103848_create_users/up.sql @@ -0,0 +1,12 @@ +-- Your SQL goes here +CREATE TABLE users ( + id VARCHAR PRIMARY KEY, + name TEXT NOT NULL, + preferred_username TEXT NOT NULL, + following TEXT NOT NULL, + followers TEXT NOT NULL, + inbox TEXT NOT NULL, + outbox TEXT NOT NULL, + is_local boolean NOT NULL, + summary TEXT +) diff --git a/src/ap/mod.rs b/src/ap/mod.rs index 9d255aa..c086e41 100644 --- a/src/ap/mod.rs +++ b/src/ap/mod.rs @@ -71,12 +71,10 @@ pub fn parse_activity(input: &String) -> Result { Ok(successful_actor) => Ok(Object::Person(successful_actor)), Err(error) => Err(format!("Error while trying to parse actor {}", error)), }, - _ => { - return Err(format!( - "Activity type {} not implemented", - json_input.unwrap().activity_type - )); - } + _ => Err(format!( + "Activity type {} not implemented", + json_input.unwrap().activity_type + )), } } else { Err("Failed to parse json data".to_string()) diff --git a/src/db/helpers.rs b/src/db/helpers.rs new file mode 100644 index 0000000..bbd2c5a --- /dev/null +++ b/src/db/helpers.rs @@ -0,0 +1,26 @@ +// use crate::schema::local_users; +use crate::schema::users; +use diesel::RunQueryDsl; +use diesel::{self, Insertable, SelectableHelper}; + +#[derive(Insertable)] +#[diesel(table_name = users)] +pub struct NewUser { + pub id: String, + pub name: String, + pub preferred_username: String, + pub following: String, + pub followers: String, + pub inbox: String, + pub outbox: String, + pub is_local: bool, + pub summary: Option, +} + +pub fn create_local_user(conn: &mut diesel::PgConnection, user: NewUser) { + diesel::insert_into(crate::schema::users::table) + .values(&user) + .returning(crate::db::User::as_returning()) + .get_result(conn) + .expect("Error saving new post"); +} diff --git a/src/db/mod.rs b/src/db/mod.rs new file mode 100644 index 0000000..9200429 --- /dev/null +++ b/src/db/mod.rs @@ -0,0 +1,28 @@ +use diesel::pg::PgConnection; +use diesel::prelude::*; +use dotenvy::dotenv; +use std::env; +pub mod helpers; + +pub fn establish_connection() -> PgConnection { + dotenv().ok(); + + let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); + PgConnection::establish(&database_url) + .unwrap_or_else(|_| panic!("Error connecting to {}", database_url)) +} + +#[derive(Queryable, Selectable)] +#[diesel(table_name = crate::schema::users)] +#[diesel(check_for_backend(diesel::pg::Pg))] +pub struct User { + pub id: String, + pub name: String, + pub preferred_username: String, + pub following: String, + pub followers: String, + pub inbox: String, + pub outbox: String, + pub is_local: bool, + pub summary: Option, +} diff --git a/src/main.rs b/src/main.rs index 6168b96..c945941 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,11 @@ +use crate::db::helpers::{create_local_user, NewUser}; + mod ap; +mod db; +mod schema; + fn main() { - println!("This does nothing look at ap/mod.rs and run cargo test to see it in action"); + // println!("This does nothing look at ap/mod.rs and run cargo test to see it in action"); + + let connection = &mut db::establish_connection(); } diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..6e3cb3e --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,15 @@ +// @generated automatically by Diesel CLI. + +diesel::table! { + users (id) { + id -> Varchar, + name -> Text, + preferred_username -> Text, + following -> Text, + followers -> Text, + inbox -> Text, + outbox -> Text, + is_local -> Bool, + summary -> Nullable, + } +}