Skip to content

Commit

Permalink
Update sqlx & poem
Browse files Browse the repository at this point in the history
  • Loading branch information
lucemans committed Nov 27, 2024
1 parent 3643f47 commit 884e090
Show file tree
Hide file tree
Showing 34 changed files with 701 additions and 330 deletions.
2 changes: 1 addition & 1 deletion engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ regex = "1.11.1"
reqwest = "0.12.5"
scraper = "0.21.0"
serde = "1.0.204"
serde_json = "1.0.120"
serde_json = { version = "1.0", features = ["raw_value"] }
serde_with = { version = "3.9.0", features = ["json", "chrono"] }
sha2 = "0.10.8"
sqlx = { version = "0.7.4", features = [
Expand Down
12 changes: 12 additions & 0 deletions engine/migrations/0001_init.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
DROP TABLE IF EXISTS items_to_tags;
DROP TABLE IF EXISTS product_media;
DROP TABLE IF EXISTS item_media;
DROP TABLE IF EXISTS item_fields;
DROP TABLE IF EXISTS items;
DROP TABLE IF EXISTS media;
DROP TABLE IF EXISTS field_definitions;
DROP TABLE IF EXISTS tags;
DROP TABLE IF EXISTS products;
DROP TABLE IF EXISTS locations;
DROP TABLE IF EXISTS sessions;
DROP TABLE IF EXISTS users;
7 changes: 0 additions & 7 deletions engine/migrations/0001_init.sql

This file was deleted.

112 changes: 112 additions & 0 deletions engine/migrations/0001_init.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
-- Independent tables first

-- Create Users table
CREATE TABLE users (
user_id SERIAL PRIMARY KEY, -- Unique identifier for each user
oauth_sub TEXT NOT NULL UNIQUE, -- OAuth subject identifier from authentication provider
oauth_data JSONB NOT NULL, -- JSON data containing OAuth provider information
nickname TEXT, -- Optional display name for the user
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the user record was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the user record was last updated
);

-- Insert a system user
INSERT INTO users (user_id, oauth_sub, oauth_data, nickname) VALUES (0, '$$SYSTEM$$', '{}', 'System');

-- Create Sessions table
CREATE TABLE sessions (
session_id TEXT PRIMARY KEY, -- Unique session identifier
user_id INTEGER NOT NULL, -- Reference to the user this session belongs to
user_agent TEXT NOT NULL, -- Browser/client information
user_ip TEXT NOT NULL, -- IP address of the client
valid BOOLEAN NOT NULL DEFAULT TRUE, -- Whether the session is still valid
last_access TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, -- When the session was last used
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the session was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the session was last updated
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE -- Links session to user, deletes session when user is deleted
);

CREATE TABLE locations (
location_id SERIAL PRIMARY KEY, -- Unique identifier for each location
name TEXT NOT NULL, -- Name of the location
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the location was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the location was last updated
);

CREATE TABLE products (
product_id SERIAL PRIMARY KEY, -- Unique identifier for each product
name TEXT NOT NULL, -- Name of the product
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the product was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the product was last updated
);

CREATE TABLE tags (
tag_id SERIAL PRIMARY KEY, -- Unique identifier for each tag
name TEXT NOT NULL, -- Name of the tag
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the tag was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the tag was last updated
);

CREATE TABLE field_definitions (
definition_id TEXT PRIMARY KEY, -- Unique identifier for each field definition
kind TEXT NOT NULL, -- Type of the field
name TEXT NOT NULL, -- Name of the field
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the field definition was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the field definition was last updated
);

CREATE TABLE media (
media_id SERIAL PRIMARY KEY, -- Unique identifier for each media item
description TEXT, -- Description of the media
url TEXT NOT NULL, -- URL where the media can be accessed
kind TEXT NOT NULL, -- Type of media (image, video, etc.)
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the media was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the media was last updated
);

-- Tables with single foreign key dependencies
CREATE TABLE items (
item_id TEXT PRIMARY KEY, -- Unique identifier for each item
name TEXT NOT NULL, -- Name of the item
owner_id INTEGER, -- Reference to the user who owns this item
location_id INTEGER, -- Reference to the location where this item is stored
product_id INTEGER, -- Optional reference to the associated product
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the item was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- When the item was last updated
);

-- Junction tables and tables with multiple dependencies
CREATE TABLE item_fields (
item_id TEXT NOT NULL, -- Reference to the item
definition_id TEXT NOT NULL, -- Reference to the field definition
value JSONB NOT NULL, -- The value of the field for this item
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the field value was created
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- When the field value was last updated
PRIMARY KEY (item_id, definition_id),
FOREIGN KEY (item_id) REFERENCES items(item_id) ON DELETE CASCADE, -- Links field to item, deletes field when item is deleted
FOREIGN KEY (definition_id) REFERENCES field_definitions(definition_id) ON DELETE CASCADE -- Links field to definition, deletes field when definition is deleted
);

CREATE TABLE item_media (
item_id TEXT NOT NULL, -- Reference to the item
media_id INTEGER NOT NULL, -- Reference to the media
PRIMARY KEY (item_id, media_id)
-- FOREIGN KEY (item_id) REFERENCES items(item_id) ON DELETE CASCADE, -- Links media to item, deletes link when item is deleted
-- FOREIGN KEY (media_id) REFERENCES media(media_id) ON DELETE CASCADE -- Links media to item, deletes link when media is deleted
);

CREATE TABLE product_media (
product_id INTEGER NOT NULL, -- Reference to the product
media_id INTEGER NOT NULL, -- Reference to the media
PRIMARY KEY (product_id, media_id)
-- FOREIGN KEY (product_id) REFERENCES products(product_id) ON DELETE CASCADE, -- Links media to product, deletes link when product is deleted
-- FOREIGN KEY (media_id) REFERENCES media(media_id) ON DELETE CASCADE -- Links media to product, deletes link when media is deleted
);

CREATE TABLE items_to_tags (
item_id TEXT NOT NULL, -- Reference to the item
tag_id INTEGER NOT NULL, -- Reference to the tag
PRIMARY KEY (item_id, tag_id),
FOREIGN KEY (item_id) REFERENCES items(item_id) ON DELETE CASCADE, -- Links tag to item, deletes link when item is deleted
FOREIGN KEY (tag_id) REFERENCES tags(tag_id) ON DELETE CASCADE -- Links tag to item, deletes link when tag is deleted
);
9 changes: 0 additions & 9 deletions engine/migrations/0002_sessions.sql

This file was deleted.

25 changes: 0 additions & 25 deletions engine/migrations/0003_property.sql

This file was deleted.

27 changes: 0 additions & 27 deletions engine/migrations/0004_media.sql

This file was deleted.

8 changes: 4 additions & 4 deletions engine/src/auth/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use std::sync::Arc;
use poem::{web::Data, Error, FromRequest, Request, RequestBody, Result};
use reqwest::StatusCode;

use crate::state::AppState;
use crate::{models::sessions::Session, state::AppState};

use super::{hash::hash_session, session::SessionState};
use super::{hash::hash_session};

pub struct ActiveUser {
pub session: SessionState,
pub session: Session,
}

pub enum AuthToken {
Expand All @@ -33,7 +33,7 @@ impl<'a> FromRequest<'a> for AuthToken {
let hash = hash_session(&token).unwrap();

// Check if active session exists with token
let session = SessionState::try_access(&hash, &state.database)
let session = Session::try_access(&hash, &state.database)
.await
.unwrap()
.ok_or(Error::from_string(
Expand Down
1 change: 0 additions & 1 deletion engine/src/auth/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod hash;
pub mod middleware;
pub mod oauth;
pub mod session;
64 changes: 64 additions & 0 deletions engine/src/models/field_definitions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use serde::{Deserialize, Serialize};
use sqlx::prelude::*;

use crate::database::Database;

#[derive(sqlx::Type, poem_openapi::Enum, Debug, Clone, Serialize, Deserialize)]
#[sqlx(type_name = "text")]
#[sqlx(rename_all = "lowercase")]
pub enum FieldKind {
String,
Number,
Boolean,
Json,
}

impl std::fmt::Display for FieldKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_string())
}
}

impl From<String> for FieldKind {
fn from(s: String) -> Self {
match s.to_lowercase().as_str() {
"string" => FieldKind::String,
"number" => FieldKind::Number,
"boolean" => FieldKind::Boolean,
"json" => FieldKind::Json,
_ => FieldKind::String,
}
}
}

impl From<FieldKind> for String {
fn from(kind: FieldKind) -> Self {
kind.to_string().to_lowercase()
}
}

#[derive(sqlx::FromRow, poem_openapi::Object, Debug, Clone, Serialize, Deserialize)]
pub struct FieldDefinition {
pub definition_id: String,
pub kind: FieldKind,
pub name: String,
pub created_at: Option<chrono::DateTime<chrono::Utc>>,
pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
}

impl FieldDefinition {
pub async fn create(
kind: FieldKind,
name: String,
database: &Database,
) -> Result<FieldDefinition, sqlx::Error> {
sqlx::query_as!(
FieldDefinition,
"INSERT INTO field_definitions (kind, name) VALUES ($1, $2) RETURNING *",
kind.to_string(),
name
)
.fetch_one(&database.pool)
.await
}
}
Loading

0 comments on commit 884e090

Please sign in to comment.