Skip to content

Commit

Permalink
init table
Browse files Browse the repository at this point in the history
  • Loading branch information
“Giems” committed Feb 8, 2024
1 parent 2158084 commit a8dcee7
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 22 deletions.
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
fn main() {
// trigger recompilation when a new migration is added
println!("cargo:rerun-if-changed=migrations");
}
}
5 changes: 5 additions & 0 deletions database/migrations/000000000001_subscription.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TYPE subscription AS (
subscription_type TEXT,
valid_from BIGINT,
valid_till BIGINT
);
6 changes: 0 additions & 6 deletions database/migrations/000000000001_test_table.sql

This file was deleted.

12 changes: 12 additions & 0 deletions database/migrations/000000000002_registered_apps.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE registered_apps(
app_id TEXT NOT NULL UNIQUE,
app_name TEXT NOT NULL,
whitelisted_domains TEXT[] NOT NULL,
subscription subscription,
ack_public_keys TEXT[] NOT NULL,
email TEXT,
registration_timestamp BIGINT NOT NULL,
pass_hash TEXT
);

CREATE UNIQUE INDEX app_id_idx ON registered_apps(app_id);
7 changes: 7 additions & 0 deletions database/src/bin/tables_migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use database::db::Db;

#[tokio::main]
async fn main() {
let db = Db::connect_to_the_pool().await;
db.migrate_tables().await.unwrap();
}
44 changes: 41 additions & 3 deletions database/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
// pub struct Db {
// pub connection_pool: PgPool,
// }
use sqlx::{migrate, pool::PoolOptions, PgPool};

pub struct Db {
pub connection_pool: PgPool,
}

impl Db {
pub async fn connect_to_the_pool() -> Db {
dotenvy::from_filename("infra/.env").unwrap();
let db_name = std::env::var("POSTGRES_DB").expect("POSTGRES_DB must be set");
let db_user = std::env::var("POSTGRES_USER").expect("POSTGRES_USER must be set");
let db_password =
std::env::var("POSTGRES_PASSWORD").expect("POSTGRES_PASSWORD must be set");

let pool = PoolOptions::new()
.max_connections(50)
.connect(
format!(
"postgres://{}:{}@localhost:5432/{}",
db_user, db_password, db_name
)
.as_str(),
)
.await
.unwrap();

Db {
connection_pool: pool,
}
}

pub async fn migrate_tables(&self) -> Result<(), sqlx::migrate::MigrateError> {
migrate!("./migrations").run(&self.connection_pool).await
}

pub async fn truncate_table(&self, table_name: &str) -> Result<(), sqlx::Error> {
let query = format!("TRUNCATE TABLE {table_name}");
sqlx::query(&query).execute(&self.connection_pool).await?;
Ok(())
}
}
1 change: 1 addition & 0 deletions database/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod db;
pub mod tables;
26 changes: 14 additions & 12 deletions database/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ async fn main() {
let db_password = std::env::var("POSTGRES_PASSWORD").expect("POSTGRES_PASSWORD must be set");

println!("db_name: {:?}", db_name);
println!("db_user: {:?}", db_user);
println!("db_password: {:?}", db_password);

let pool = PgPool::connect(
format!(
Expand All @@ -55,21 +57,21 @@ async fn main() {

migrate!("./migrations").run(&pool).await.unwrap();

let res = query("SELECT 1+1 as sum").fetch_one(&pool).await.unwrap();
let sum: i32 = res.get("sum");
println!("sum: {}", sum);
// let res = query("SELECT 1+1 as sum").fetch_one(&pool).await.unwrap();
// let sum: i32 = res.get("sum");
// println!("sum: {}", sum);

let sub = Subscription {
email: "dupa".to_string(),
subscribed_at: 123,
};
// let sub = Subscription {
// email: "dupa".to_string(),
// subscribed_at: 123,
// };

create_subscription(&pool, sub).await.unwrap();
// create_subscription(&pool, sub).await.unwrap();

println!(
"sub: {:?}",
get_sub(&pool, "dupa".to_string()).await.unwrap()
);
// println!(
// "sub: {:?}",
// get_sub(&pool, "dupa".to_string()).await.unwrap()
// );

// let rows = sqlx::query("SELECT * FROM users")
// .fetch_all(&pool)
Expand Down
1 change: 1 addition & 0 deletions database/src/tables/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod registered_app;
3 changes: 3 additions & 0 deletions database/src/tables/registered_app/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod select;
pub mod table_struct;
pub mod update;
18 changes: 18 additions & 0 deletions database/src/tables/registered_app/select.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use super::table_struct::{RegisteredApp, REGISTERED_APPS_TABLE_NAME};
use crate::db::Db;
use sqlx::query_as;

impl Db {
pub async fn get_registered_app_by_app_id(
&self,
app_id: &String,
) -> Result<RegisteredApp, sqlx::Error> {
let query = format!("SELECT * FROM {REGISTERED_APPS_TABLE_NAME} WHERE app_id = $1");
let typed_query = query_as::<_, RegisteredApp>(&query);

return typed_query
.bind(&app_id)
.fetch_one(&self.connection_pool)
.await;
}
}
40 changes: 40 additions & 0 deletions database/src/tables/registered_app/table_struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use sqlx::{postgres::PgRow, FromRow, Row, Type};

// TODO move later to a common place
#[derive(Clone, Debug, Eq, PartialEq, Type)]
#[sqlx(type_name = "subscription")]
pub struct Subscription {
pub email: String,
pub subscribed_at: i64,
}

pub const REGISTERED_APPS_TABLE_NAME: &str = "registered_apps";
pub const REGISTERED_APPS_KEYS: &str = "app_id, app_name, whitelisted_domains, subscription, ack_public_keys, email, registration_timestamp, pass_hash";

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RegisteredApp {
pub app_id: String,
pub app_name: String,
pub whitelisted_domains: Vec<String>,
pub subscription: Option<Subscription>,
pub ack_public_keys: Vec<String>,
pub email: Option<String>,
pub registration_timestamp: u64,
pub pass_hash: Option<String>,
}

impl FromRow<'_, PgRow> for RegisteredApp {
fn from_row(row: &sqlx::postgres::PgRow) -> std::result::Result<Self, sqlx::Error> {
let registration_timestamp: i64 = row.get("registration_timestamp");
Ok(RegisteredApp {
app_id: row.get("app_id"),
app_name: row.get("app_name"),
whitelisted_domains: row.get("whitelisted_domains"),
subscription: row.get("subscription"),
ack_public_keys: row.get("ack_public_keys"),
email: row.get("email"),
registration_timestamp: registration_timestamp as u64,
pass_hash: row.get("pass_hash"),
})
}
}
77 changes: 77 additions & 0 deletions database/src/tables/registered_app/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use super::table_struct::{
RegisteredApp, Subscription, REGISTERED_APPS_KEYS, REGISTERED_APPS_TABLE_NAME,
};
use crate::db::Db;
use sqlx::query;

impl Db {
pub async fn register_new_app(&self, app: &RegisteredApp) -> Result<(), sqlx::Error> {
let query_body = format!(
"INSERT INTO {REGISTERED_APPS_TABLE_NAME} ({}) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
REGISTERED_APPS_KEYS
);

let query_result = query(&query_body)
.bind(&app.app_id)
.bind(&app.app_name)
.bind(&app.whitelisted_domains)
.bind(&app.subscription)
.bind(&app.ack_public_keys)
.bind(&app.email)
.bind(&(app.registration_timestamp as i64))
.bind(&app.pass_hash)
.execute(&self.connection_pool)
.await;

match query_result {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}

pub async fn update_subscription(
&self,
app_id: &String,
subscription: &Subscription,
) -> Result<(), sqlx::Error> {
let query_body = "UPDATE registered_apps SET subscription = $1 WHERE app_id = $2";
let query_result = query(query_body)
.bind(subscription)
.bind(app_id)
.execute(&self.connection_pool)
.await;

match query_result {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
}

#[cfg(test)]
mod tests {
use crate::tables::registered_app::table_struct::{RegisteredApp, REGISTERED_APPS_TABLE_NAME};

#[tokio::test]
async fn test_register_app() {
let db = super::Db::connect_to_the_pool().await;
db.migrate_tables().await.unwrap();
db.truncate_table(REGISTERED_APPS_TABLE_NAME).await.unwrap();

let app = RegisteredApp {
app_id: "test_app_id".to_string(),
app_name: "test_app_name".to_string(),
whitelisted_domains: vec!["test_domain".to_string()],
subscription: None,
ack_public_keys: vec!["test_key".to_string()],
email: None,
registration_timestamp: 0,
pass_hash: None,
};

db.register_new_app(&app).await.unwrap();

let result = db.get_registered_app_by_app_id(&app.app_id).await.unwrap();
assert_eq!(app, result);
}
}

0 comments on commit a8dcee7

Please sign in to comment.