add repository stuff

This commit is contained in:
anna 2022-12-06 00:29:24 +01:00
parent 84589a1849
commit a5d9f049a9
Signed by: fef
GPG key ID: EC22E476DC2D3D84
6 changed files with 89 additions and 14 deletions

View file

@ -1,9 +1,8 @@
use log::*;
use serde;
use sqlx::{Executor, PgPool};
use crate::core::{Id, Result};
use crate::model::account::Account;
use crate::core::*;
use crate::model::account::{Account, NewAccount};
pub struct PgAccountDataSource {
pool: PgPool,
@ -19,11 +18,25 @@ impl PgAccountDataSource {
I: Into<Id> + Send,
{
let id: Id = id.into();
debug!(target: "db", "Query accounts by id {}", id);
let account: Account = sqlx::query_as("SELECT * FROM accounts WHERE id = $1")
.bind(id)
.fetch_one(&self.pool)
.await?;
Ok(account)
}
pub async fn create<T>(&self, new: T) -> Result<Account>
where
T: Into<NewAccount> + Send,
{
let new = new.into();
let account: Account =
sqlx::query_as("INSERT INTO accounts (name, domain, display_name) VALUES ($1, $2, $3)")
.bind(new.name)
.bind(new.domain)
.bind(new.display_name)
.fetch_one(&self.pool)
.await?;
Ok(account)
}
}

View file

@ -8,9 +8,16 @@ use crate::core::Id;
pub struct Account {
pub id: Id,
pub name: String,
pub domain: String,
pub display_name: Option<String>,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
pub struct NewAccount {
pub name: String,
pub domain: String,
pub display_name: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl Into<Id> for Account {

31
src/repo/account.rs Normal file
View file

@ -0,0 +1,31 @@
use sqlx::PgPool;
use crate::core::*;
use crate::data::account::PgAccountDataSource;
use crate::model::account::{Account, NewAccount};
pub struct AccountRepo {
db: PgAccountDataSource,
}
impl AccountRepo {
pub fn new(db_pool: PgPool) -> AccountRepo {
AccountRepo {
db: PgAccountDataSource::new(db_pool),
}
}
pub async fn by_id<I>(&self, id: I) -> Result<Account>
where
I: Into<Id> + Send,
{
self.db.by_id(id).await
}
pub async fn create<T>(&self, new: T) -> Result<Account>
where
T: Into<NewAccount> + Send,
{
self.db.create(new).await
}
}

19
src/repo/mod.rs Normal file
View file

@ -0,0 +1,19 @@
use sqlx::PgPool;
pub mod account;
use account::AccountRepo;
/// The central collection of all data accessible to the app.
/// This is included in `AppState` so it is accessible everywhere.
/// All interactions with resident data must happen through this interface.
pub struct AppRepo {
pub accounts: AccountRepo,
}
impl AppRepo {
pub fn new(db_pool: PgPool) -> AppRepo {
AppRepo {
accounts: AccountRepo::new(db_pool),
}
}
}

View file

@ -1,13 +1,14 @@
use crate::state::AppState;
use actix_web::{get, web, HttpRequest, HttpResponse, Responder};
use crate::core::*;
use crate::model::account::Account;
use crate::state::AppState;
#[get("/{id}")]
async fn get_by_id(path: web::Path<i32>, state: AppState) -> impl Responder {
async fn get_by_id(path: web::Path<Id>, state: AppState) -> Result<HttpResponse> {
let id = path.into_inner();
HttpResponse::Ok().body(format!(
"hello uid {}, listening on port {}",
id, state.config.bind_port
))
let account = state.repo.accounts.by_id(id).await?;
Ok(HttpResponse::Ok().json(account))
}
pub fn configure(cfg: &mut web::ServiceConfig) {

View file

@ -3,15 +3,19 @@ use sqlx::PgPool;
use std::sync::Arc;
use crate::conf::Config;
use crate::repo::AppRepo;
pub struct State {
pub config: Config,
pub db_pool: PgPool,
pub repo: AppRepo,
}
pub type AppStateRaw = Arc<State>;
pub type AppState = web::Data<AppStateRaw>;
pub fn new(config: Config, db_pool: PgPool) -> AppState {
web::Data::new(Arc::new(State { config, db_pool }))
web::Data::new(Arc::new(State {
config,
repo: AppRepo::new(db_pool),
}))
}