add repository stuff
This commit is contained in:
parent
84589a1849
commit
a5d9f049a9
6 changed files with 89 additions and 14 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
31
src/repo/account.rs
Normal 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
19
src/repo/mod.rs
Normal 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),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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),
|
||||
}))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue