Skip to content

Commit 56fa173

Browse files
c-gitmxttc
andcommitted
refactor: pull out database code
Co-authored-by: mxttc <mxttc@users.noreply.github.com>
1 parent 0e37dbc commit 56fa173

6 files changed

Lines changed: 58 additions & 76 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ serde_json = "1.0.143"
1414
shuttle-runtime = { version = "0.57.0", default-features = false }
1515
shuttle-serenity = "0.57.0" # Since poise is a serenity command framework, it can run on Shuttle with shuttle-serenity
1616
shuttle-shared-db = { version = "0.57.0", default-features = false, features = ["sqlx", "postgres"] }
17-
sqlx = { version = "0.8.6", default-features = false, features = ["postgres", "runtime-tokio-rustls"] }
1817
tracing = "0.1.41"
1918
tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
2019
version = "3.0.0"

src/config.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub struct SharedConfig {
2020
pub start_instant: Instant,
2121
pub auth_role_id: RoleId,
2222
pub channel_unranked: ChannelId,
23-
pub db_pool: sqlx::PgPool,
2423
pub channel_bot_status: Option<ChannelId>,
2524
}
2625

@@ -49,30 +48,26 @@ impl StartupConfig {
4948
}
5049

5150
impl SharedConfig {
52-
pub fn try_new(
53-
secret_store: &SecretStore,
54-
db_pool: sqlx::PgPool,
55-
) -> anyhow::Result<&'static Self> {
51+
const KEY_VALUE_STORE_FOLDER: &str = "KV";
52+
pub fn try_new(secret_store: &SecretStore) -> anyhow::Result<&'static Self> {
5653
let auth_role_id = KeyName::AuthRoleId.get_non_secret_parse(secret_store)?;
5754
let channel_unranked = KeyName::ChannelUnrankedId.get_non_secret_parse(secret_store)?;
5855
let channel_bot_status = KeyName::ChannelBotStatus.get_non_secret_parse_opt(secret_store);
5956
let result = Box::new(Self {
6057
start_instant: Instant::now(),
6158
auth_role_id,
6259
channel_unranked,
63-
db_pool,
6460
channel_bot_status,
6561
});
6662
Ok(Box::leak(result))
6763
}
6864

6965
/// Doesn't actually perform the save but spawns a task to do it in the background
7066
pub fn save_kv<T: serde::Serialize>(&self, key: &str, value: &T) -> anyhow::Result<()> {
71-
let pool = self.db_pool.clone();
7267
let key = key.to_string();
7368
let value = serde_json::to_string(value).context("failed to convert to json")?;
7469
tokio::spawn(async move {
75-
crate::db::save_kv(&pool, &key, value).await;
70+
crate::db::save_kv(&key, value).await;
7671
});
7772
Ok(())
7873
}
@@ -81,7 +76,7 @@ impl SharedConfig {
8176
&self,
8277
key: &str,
8378
) -> T {
84-
let Some(content) = crate::db::load_kv(&self.db_pool, key).await else {
79+
let Some(content) = crate::db::load_kv(key).await else {
8580
return T::default();
8681
};
8782
match serde_json::from_str(&content) {

src/db.rs

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
use tracing::{debug, error, info};
2-
3-
pub async fn save_kv(pool: &sqlx::PgPool, key: &str, value: String) {
4-
let query = sqlx::query!(
5-
"\
6-
INSERT INTO kv_store (id, content)
7-
VALUES ($1, $2)
8-
ON CONFLICT(id)
9-
DO UPDATE SET
10-
content = EXCLUDED.content;",
11-
key,
12-
value
13-
);
14-
match query.execute(pool).await {
15-
Ok(query_result) => {
16-
if query_result.rows_affected() == 1 {
17-
debug!("Save completed for key: {key}");
18-
} else {
19-
error!(
20-
?key,
21-
"Expected 1 row to be affected by save but got: {}",
22-
query_result.rows_affected()
23-
)
24-
}
25-
}
26-
Err(err_msg) => error!(
27-
?err_msg,
28-
"Failed to save content for key: {key} to kv store"
29-
),
30-
}
1+
pub async fn save_kv(key: &str, value: String) {
2+
todo!("save to disk")
3+
// let query = sqlx::query!(
4+
// "\
5+
// INSERT INTO kv_store (id, content)
6+
// VALUES ($1, $2)
7+
// ON CONFLICT(id)
8+
// DO UPDATE SET
9+
// content = EXCLUDED.content;",
10+
// key,
11+
// value
12+
// );
13+
// match query.execute(pool).await {
14+
// Ok(query_result) => {
15+
// if query_result.rows_affected() == 1 {
16+
// debug!("Save completed for key: {key}");
17+
// } else {
18+
// error!(
19+
// ?key,
20+
// "Expected 1 row to be affected by save but got: {}",
21+
// query_result.rows_affected()
22+
// )
23+
// }
24+
// }
25+
// Err(err_msg) => error!(
26+
// ?err_msg,
27+
// "Failed to save content for key: {key} to kv store"
28+
// ),
29+
// }
3130
}
3231

33-
pub async fn load_kv(pool: &sqlx::PgPool, key: &str) -> Option<String> {
34-
match sqlx::query!("SELECT content FROM kv_store where id = $1", key)
35-
.fetch_optional(pool)
36-
.await
37-
{
38-
Ok(Some(record)) => Some(record.content),
39-
Ok(None) => {
40-
info!("No content found in DB for key: {key}");
41-
None
42-
}
43-
Err(err_msg) => {
44-
error!(?err_msg, "Failed to get content for key: {key}");
45-
None
46-
}
47-
}
32+
pub async fn load_kv(key: &str) -> Option<String> {
33+
todo!("load from disk")
34+
// match sqlx::query!("SELECT content FROM kv_store where id = $1", key)
35+
// .fetch_optional(pool)
36+
// .await
37+
// {
38+
// Ok(Some(record)) => Some(record.content),
39+
// Ok(None) => {
40+
// info!("No content found in DB for key: {key}");
41+
// None
42+
// }
43+
// Err(err_msg) => {
44+
// error!(?err_msg, "Failed to get content for key: {key}");
45+
// None
46+
// }
47+
// }
4848
}

src/heartbeat.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use tracing::{error, info};
99

1010
const KEY: &str = "HEARTBEAT";
1111

12-
pub fn start_heartbeat(db_pool: sqlx::PgPool) {
12+
pub fn start_heartbeat() {
1313
shuttle_runtime::tokio::spawn(async move {
1414
info!("Heartbeat started");
1515
loop {
@@ -20,14 +20,14 @@ pub fn start_heartbeat(db_pool: sqlx::PgPool) {
2020
break;
2121
}
2222
};
23-
save_kv(&db_pool, KEY, timestamp.to_db_fmt()).await;
23+
save_kv(KEY, timestamp.to_db_fmt()).await;
2424
shuttle_runtime::tokio::time::sleep(std::time::Duration::from_secs(600)).await;
2525
}
2626
});
2727
}
2828

29-
pub async fn last_heartbeat_info(db_pool: sqlx::PgPool) -> String {
30-
match load_kv(&db_pool, KEY).await {
29+
pub async fn last_heartbeat_info() -> String {
30+
match load_kv(KEY).await {
3131
Some(db_value) => match UnixTimestamp::from_db_fmt(&db_value) {
3232
Ok(last_heartbeat) => {
3333
let Ok(now) = UnixTimestamp::now() else {

src/main.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,7 @@ use tracing_subscriber::{
1616
use version::version;
1717

1818
#[shuttle_runtime::main]
19-
async fn main(
20-
#[shuttle_runtime::Secrets] secret_store: SecretStore,
21-
#[shuttle_shared_db::Postgres(
22-
local_uri = "postgres://db_user:password@localhost:5432/bazooka_bot"
23-
)]
24-
db_pool: sqlx::PgPool,
25-
) -> ShuttleSerenity {
19+
async fn main(#[shuttle_runtime::Secrets] secret_store: SecretStore) -> ShuttleSerenity {
2620
tracing_subscriber::registry()
2721
.with(fmt::layer().with_span_events(FmtSpan::NEW | FmtSpan::CLOSE))
2822
.with(
@@ -33,17 +27,12 @@ async fn main(
3327

3428
info!("Bot version is {}", version::version!());
3529

36-
sqlx::migrate!("./migrations")
37-
.run(&db_pool)
38-
.await
39-
.expect("Migrations failed");
40-
4130
// Load setup values
4231
let discord_token = get_secret_discord_token(&secret_store)?;
4332
let startup_config =
4433
StartupConfig::try_new(&secret_store).context("failed to create setup config")?;
45-
let shared_config = SharedConfig::try_new(&secret_store, db_pool.clone())
46-
.context("failed to created shared_config")?;
34+
let shared_config =
35+
SharedConfig::try_new(&secret_store).context("failed to created shared_config")?;
4736

4837
let framework = poise::Framework::builder()
4938
.options(poise::FrameworkOptions {
@@ -86,7 +75,7 @@ async fn main(
8675
let connect_msg = format!(
8776
"{} is connected! Version: {}\n{}",
8877
ready.user.name, version!(),
89-
heartbeat::last_heartbeat_info(db_pool.clone()).await,
78+
heartbeat::last_heartbeat_info().await,
9079
);
9180
info!("{connect_msg}");
9281
if let Some(channel) = shared_config.channel_bot_status{
@@ -95,7 +84,7 @@ async fn main(
9584
warn!("Not sending connection notification because channel_bot_status not set");
9685
}
9786
let data = Data::new(shared_config, ctx.clone()).await;
98-
heartbeat::start_heartbeat(db_pool);
87+
heartbeat::start_heartbeat();
9988
info!("END OF SETUP CLOSURE");
10089
Ok(data)
10190
})

0 commit comments

Comments
 (0)