diff --git a/Cargo.lock b/Cargo.lock index 8d3fa2e..ddb3e1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,12 +190,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "deranged" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" - [[package]] name = "diesel" version = "2.1.3" @@ -206,10 +200,8 @@ dependencies = [ "byteorder", "diesel_derives", "itoa", - "libsqlite3-sys", "pq-sys", "serde_json", - "time", ] [[package]] @@ -471,16 +463,6 @@ version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" -[[package]] -name = "libsqlite3-sys" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" -dependencies = [ - "pkg-config", - "vcpkg", -] - [[package]] name = "lock_api" version = "0.4.10" @@ -694,12 +676,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - [[package]] name = "pq-sys" version = "0.4.8" @@ -969,34 +945,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "time" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" -dependencies = [ - "deranged", - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" -dependencies = [ - "time-core", -] - [[package]] name = "tokio" version = "1.32.0" 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/2023-10-08-191013_create-users/down.sql b/migrations/2023-10-08-191013_create-users/down.sql new file mode 100644 index 0000000..4ef4d0b --- /dev/null +++ b/migrations/2023-10-08-191013_create-users/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +DROP TABLE IF EXISTS "users"; diff --git a/migrations/2023-10-08-191013_create-users/up.sql b/migrations/2023-10-08-191013_create-users/up.sql new file mode 100644 index 0000000..544d9de --- /dev/null +++ b/migrations/2023-10-08-191013_create-users/up.sql @@ -0,0 +1,6 @@ +-- Your SQL goes here +CREATE TABLE "users"( + "id" SERIAL PRIMARY KEY, + "username" VARCHAR NOT NULL +); + diff --git a/src/bin/create_user.rs b/src/bin/create_user.rs new file mode 100644 index 0000000..3765bbd --- /dev/null +++ b/src/bin/create_user.rs @@ -0,0 +1,39 @@ +use diesel::pg::PgConnection; +use diesel::prelude::*; +use dotenvy::dotenv; +use miniweb::users::models::{NewUser, User}; +use std::env; +use std::io::stdin; + +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)) +} + +pub fn create_user(conn: &mut PgConnection, username: &str) -> User { + use miniweb::schema::users; + + let new_user = NewUser { username }; + + diesel::insert_into(users::table) + .values(&new_user) + .returning(User::as_returning()) + .get_result(conn) + .expect("Error saving new user") +} + +fn main() { + let connection = &mut establish_connection(); + + let mut username = String::new(); + + println!("Enter username for new user:"); + stdin().read_line(&mut username).unwrap(); + let username = username.trim_end(); // Remove the trailing newline + + let user = create_user(connection, username); + println!("\nSaved user {} with id {}", username, user.id); +} diff --git a/src/bin/list_users.rs b/src/bin/list_users.rs new file mode 100644 index 0000000..4e3f5fd --- /dev/null +++ b/src/bin/list_users.rs @@ -0,0 +1,29 @@ +use diesel::pg::PgConnection; +use diesel::prelude::*; +use dotenvy::dotenv; +use miniweb::schema::users::dsl::*; +use miniweb::users::models::User; +use std::env; + +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)) +} + +fn main() { + let connection = &mut establish_connection(); + + let results = users + .select(User::as_select()) + .load(connection) + .expect("Error loading posts"); + + println!("Displaying {} users", results.len()); + for user in results { + println!("{}", user.username); + } + println!("-----------\n"); +} diff --git a/src/lib.rs b/src/lib.rs index ed3adcf..60473e7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,4 @@ +pub mod schema; pub mod service; pub mod state; +pub mod users; diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..c2ed484 --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,8 @@ +// @generated automatically by Diesel CLI. + +diesel::table! { + users (id) { + id -> Int4, + username -> Varchar, + } +} diff --git a/src/users/mod.rs b/src/users/mod.rs new file mode 100644 index 0000000..e072fd8 --- /dev/null +++ b/src/users/mod.rs @@ -0,0 +1 @@ +pub mod models; diff --git a/src/users/models.rs b/src/users/models.rs new file mode 100644 index 0000000..a04b7f9 --- /dev/null +++ b/src/users/models.rs @@ -0,0 +1,15 @@ +use diesel::prelude::*; + +#[derive(Queryable, Selectable)] +#[diesel(table_name = crate::schema::users)] +#[diesel(check_for_backend(diesel::pg::Pg))] +pub struct User { + pub id: i32, + pub username: String, +} + +#[derive(Insertable)] +#[diesel(table_name = crate::schema::users)] +pub struct NewUser<'a> { + pub username: &'a str, +}