Initial implementation of db stuffs

Got the migrations and datastructures in. Next step is building db
utility function into the db module or client module
This commit is contained in:
2026-05-18 14:54:57 -07:00
parent 907c6a8fb0
commit c92ee309a9
21 changed files with 262 additions and 1 deletions
+1
View File
@@ -1,2 +1,3 @@
/target /target
confetti.toml confetti.toml
.env
Generated
+28
View File
@@ -229,6 +229,7 @@ dependencies = [
"ctrlc-async", "ctrlc-async",
"diesel", "diesel",
"diesel-async", "diesel-async",
"diesel-derive-composite",
"fedichat", "fedichat",
"quinn", "quinn",
"rmp-serde", "rmp-serde",
@@ -246,6 +247,15 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
[[package]]
name = "convert_case"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.10.1" version = "0.10.1"
@@ -390,6 +400,18 @@ dependencies = [
"tokio-postgres", "tokio-postgres",
] ]
[[package]]
name = "diesel-derive-composite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a634241e758e588c8deb76cc44f0b605b46536aa769946446b6afd4956c7f2e8"
dependencies = [
"convert_case",
"darling",
"quote",
"syn",
]
[[package]] [[package]]
name = "diesel_derives" name = "diesel_derives"
version = "2.3.9" version = "2.3.9"
@@ -1778,6 +1800,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
[[package]]
name = "unicode-segmentation"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.6" version = "0.2.6"
+2 -1
View File
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
diesel = { version = "2.3.9" } diesel = { version = "2.3.9", features = ["postgres_backend"] }
quinn = "0.11.9" quinn = "0.11.9"
fedichat = {git = "https://git.firechicken.net/fedichat/fedichat-lib"} fedichat = {git = "https://git.firechicken.net/fedichat/fedichat-lib"}
#fedichat = {path = "../fedichat-lib"} #fedichat = {path = "../fedichat-lib"}
@@ -18,3 +18,4 @@ toml = "1.1.2"
diesel-async = { version = "0.9.0", features = ["postgres","deadpool"] } diesel-async = { version = "0.9.0", features = ["postgres","deadpool"] }
ctrlc-async = { version = "3.2.2", features = ["termination"] } ctrlc-async = { version = "3.2.2", features = ["termination"] }
rmp-serde = "1.3.1" rmp-serde = "1.3.1"
diesel-derive-composite = "0.1.0"
+9
View File
@@ -0,0 +1,9 @@
# For documentation on how to configure this file,
# see https://diesel.rs/guides/configuring-diesel-cli
[print_schema]
file = "src/db/schema.rs"
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
[migrations_directory]
dir = "migrations"
View File
View File
@@ -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();
@@ -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;
@@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
DROP TABLE users;
@@ -0,0 +1,6 @@
-- Your SQL goes here
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL
)
@@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
DROP TABLE groups;
DROP TYPE user_t;
@@ -0,0 +1,11 @@
-- Your SQL goes here
CREATE TYPE user_t AS (
name TEXT,
server TEXT
);
CREATE TABLE groups (
id SERIAL PRIMARY KEY,
groupname TEXT NOT NULL,
role TEXT,
username user_t NOT NULL
)
@@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
DROP TABLE messages;
DROP TYPE room_id;
@@ -0,0 +1,14 @@
-- Your SQL goes here
CREATE TYPE room_id AS (
coordinates bigint[],
server text
);
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY,
room room_id NOT NULL,
body TEXT NOT NULL,
signature TEXT NOT NULL,
client_timestamp BIGINT NOT NULL,
server_timestamp BIGINT NOT NULL,
username user_t NOT NULL
)
@@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
DROP TABLE roles;
@@ -0,0 +1,7 @@
-- Your SQL goes here
CREATE TABLE roles (
id SERIAL PRIMARY KEY,
rolename TEXT NOT NULL,
groupname TEXT NOT NULL,
permission TEXT NOT NULL
)
+2
View File
@@ -0,0 +1,2 @@
pub mod models;
pub mod schema;
+68
View File
@@ -0,0 +1,68 @@
use diesel::prelude::*;
use diesel::deserialize::FromSqlRow;
use diesel::expression::AsExpression;
// Man this library is brittle
use diesel_derive_composite::Composite;
use diesel::pg::Pg;
// Gets around broken macro in diesel_derive_composite
type MyArr = diesel::sql_types::Array<diesel::sql_types::BigInt>;
#[derive(Debug, Composite, FromSqlRow, AsExpression)]
#[diesel(sql_type = crate::db::schema::sql_types::UserT)]
pub struct UserT {
#[diesel_composite(sql_type = diesel::sql_types::Text)]
pub name: String,
#[diesel_composite(sql_type = diesel::sql_types::Text)]
pub server: String
}
#[derive(Debug, Composite, FromSqlRow, AsExpression)]
#[diesel(sql_type = crate::db::schema::sql_types::UserT)]
pub struct RoomId {
#[diesel_composite(sql_type = MyArr)]
pub coordinates: Vec<i64>,
#[diesel_composite(sql_type = diesel::sql_types::Text)]
pub server: String
}
#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::db::schema::groups)]
pub struct Group {
pub id: i32,
pub groupname: String,
pub role: Option<String>,
pub username: UserT
}
#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::db::schema::roles)]
pub struct Role {
pub id: i32,
pub rolename: String,
pub groupname: String,
pub permission: String
}
#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::db::schema::users)]
pub struct User {
pub id: i32,
pub username: String,
pub password: String,
}
#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::db::schema::messages)]
pub struct Messages {
pub id: i64,
pub room: RoomId,
pub body: String,
pub signature: String,
pub client_timestamp: i64,
pub server_timestamp: i64,
pub username: UserT
}
+58
View File
@@ -0,0 +1,58 @@
// @generated automatically by Diesel CLI.
pub mod sql_types {
#[derive(diesel::query_builder::QueryId, Clone, diesel::sql_types::SqlType)]
#[diesel(postgres_type(name = "room_id"))]
pub struct RoomId;
#[derive(diesel::query_builder::QueryId, Clone, diesel::sql_types::SqlType)]
#[diesel(postgres_type(name = "user_t"))]
pub struct UserT;
}
diesel::table! {
use diesel::sql_types::*;
use super::sql_types::UserT;
groups (id) {
id -> Int4,
groupname -> Text,
role -> Nullable<Text>,
username -> UserT,
}
}
diesel::table! {
use diesel::sql_types::*;
use super::sql_types::RoomId;
use super::sql_types::UserT;
messages (id) {
id -> Int8,
room -> RoomId,
body -> Text,
signature -> Text,
client_timestamp -> Int8,
server_timestamp -> Int8,
username -> UserT,
}
}
diesel::table! {
roles (id) {
id -> Int4,
rolename -> Text,
groupname -> Text,
permission -> Text,
}
}
diesel::table! {
users (id) {
id -> Int4,
username -> Text,
password -> Text,
}
}
diesel::allow_tables_to_appear_in_same_query!(groups, messages, roles, users,);
+1
View File
@@ -1,6 +1,7 @@
mod client; mod client;
mod config; mod config;
mod connection; mod connection;
mod db;
mod state; mod state;
use diesel_async::pooled_connection::AsyncDieselConnectionManager; use diesel_async::pooled_connection::AsyncDieselConnectionManager;
+3
View File
@@ -40,6 +40,9 @@ impl State {
} }
pub fn write_to_file(&mut self, path: &str) -> Result<(),io::Error> { pub fn write_to_file(&mut self, path: &str) -> Result<(),io::Error> {
// Should write to state.next file, then move to actual state file
// Uses twice as much space but won't corrupt state if the program crashes
// during an autosave
unimplemented!() unimplemented!()
} }
pub fn load_from_file(path: &str) -> Result<Self,io::Error> { pub fn load_from_file(path: &str) -> Result<Self,io::Error> {