mirror of
https://github.com/nullishamy/ferri.git
synced 2025-06-28 00:54:17 +00:00
feat: start on CRUD ops for new types
This commit is contained in:
parent
d252131e0d
commit
e6b654a0b3
6 changed files with 149 additions and 32 deletions
|
@ -1,24 +1,18 @@
|
|||
use crate::types_rewrite::{ObjectUuid, ObjectUri, db};
|
||||
use sqlx::SqliteConnection;
|
||||
use thiserror::Error;
|
||||
use tracing::info;
|
||||
use chrono::{NaiveDateTime, DateTime, Utc};
|
||||
use crate::types_rewrite::DbError;
|
||||
|
||||
const SQLITE_TIME_FMT: &'static str = "%Y-%m-%d %H:%M:%S";
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FetchError {
|
||||
#[error("an unknown error occured when fetching: {0}")]
|
||||
Unknown(String)
|
||||
}
|
||||
|
||||
fn parse_ts(ts: String) -> Option<DateTime<Utc>> {
|
||||
NaiveDateTime::parse_from_str(&ts, SQLITE_TIME_FMT)
|
||||
.ok()
|
||||
.map(|nt| nt.and_utc())
|
||||
}
|
||||
|
||||
pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<db::User, FetchError> {
|
||||
pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<db::User, DbError> {
|
||||
info!("fetching user by uuid '{:?}' from the database", id);
|
||||
|
||||
let record = sqlx::query!(r#"
|
||||
|
@ -39,7 +33,7 @@ pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<d
|
|||
"#, id.0)
|
||||
.fetch_one(&mut *conn)
|
||||
.await
|
||||
.map_err(|e| FetchError::Unknown(e.to_string()))?;
|
||||
.map_err(|e| DbError::FetchError(e.to_string()))?;
|
||||
|
||||
let follower_count = sqlx::query_scalar!(r#"
|
||||
SELECT COUNT(follower_id)
|
||||
|
@ -48,7 +42,7 @@ pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<d
|
|||
"#, record.actor_id)
|
||||
.fetch_one(&mut *conn)
|
||||
.await
|
||||
.map_err(|e| FetchError::Unknown(e.to_string()))?;
|
||||
.map_err(|e| DbError::FetchError(e.to_string()))?;
|
||||
|
||||
let last_post_at = sqlx::query_scalar!(r#"
|
||||
SELECT datetime(p.created_at)
|
||||
|
@ -59,7 +53,7 @@ pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<d
|
|||
"#, record.user_id)
|
||||
.fetch_one(&mut *conn)
|
||||
.await
|
||||
.map_err(|e| FetchError::Unknown(e.to_string()))?
|
||||
.map_err(|e| DbError::FetchError(e.to_string()))?
|
||||
.and_then(|ts| {
|
||||
info!("parsing timestamp {}", ts);
|
||||
parse_ts(ts)
|
30
ferri-main/src/types_rewrite/make.rs
Normal file
30
ferri-main/src/types_rewrite/make.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use crate::types_rewrite::db;
|
||||
use sqlx::SqliteConnection;
|
||||
use crate::types_rewrite::DbError;
|
||||
|
||||
pub async fn new_user(user: db::User, conn: &mut SqliteConnection) -> Result<db::User, DbError> {
|
||||
let ts = user.created_at.to_rfc3339();
|
||||
sqlx::query!(r#"
|
||||
INSERT INTO user (id, acct, url, created_at, remote, username, actor_id, display_name)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)
|
||||
"#, user.id.0, user.acct, user.url, ts,
|
||||
user.remote, user.username, user.actor.id.0, user.display_name
|
||||
)
|
||||
.execute(conn)
|
||||
.await
|
||||
.map_err(|e| DbError::CreationError(e.to_string()))?;
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
pub async fn new_actor(actor: db::Actor, conn: &mut SqliteConnection) -> Result<db::Actor, DbError> {
|
||||
sqlx::query!(r#"
|
||||
INSERT INTO actor (id, inbox, outbox)
|
||||
VALUES (?1, ?2, ?3)
|
||||
"#, actor.id.0, actor.inbox, actor.outbox)
|
||||
.execute(conn)
|
||||
.await
|
||||
.map_err(|e| DbError::CreationError(e.to_string()))?;
|
||||
|
||||
Ok(actor)
|
||||
}
|
|
@ -1,7 +1,19 @@
|
|||
use serde::{Serialize, Deserialize};
|
||||
use thiserror::Error;
|
||||
use std::fmt::Debug;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod convert;
|
||||
pub mod fetch;
|
||||
pub mod get;
|
||||
pub mod make;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DbError {
|
||||
#[error("an unknown error occured when creating: {0}")]
|
||||
CreationError(String),
|
||||
#[error("an unknown error occured when fetching: {0}")]
|
||||
FetchError(String)
|
||||
}
|
||||
|
||||
pub const AS_CONTEXT_RAW: &'static str = "https://www.w3.org/ns/activitystreams";
|
||||
pub fn as_context() -> ObjectContext {
|
||||
|
@ -15,12 +27,18 @@ pub enum ObjectContext {
|
|||
Vec(Vec<serde_json::Value>),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
|
||||
pub struct ObjectUri(pub String);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
|
||||
pub struct ObjectUuid(pub String);
|
||||
|
||||
impl ObjectUuid {
|
||||
pub fn new() -> Self {
|
||||
Self(Uuid::new_v4().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
pub struct Object {
|
||||
#[serde(rename = "@context")]
|
||||
|
@ -32,20 +50,20 @@ pub mod db {
|
|||
use chrono::{DateTime, Utc};
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Actor {
|
||||
pub id: ObjectUri,
|
||||
pub inbox: String,
|
||||
pub outbox: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct UserPosts {
|
||||
// User may have no posts
|
||||
pub last_post_at: Option<DateTime<Utc>>
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct User {
|
||||
pub id: ObjectUuid,
|
||||
pub actor: Actor,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue