diff options
Diffstat (limited to '')
| -rw-r--r-- | src/database/mod.rs | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/src/database/mod.rs b/src/database/mod.rs index 9679811..e81e448 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs | |||
| @@ -75,14 +75,24 @@ async fn run_migrations(pool: &DbPool) -> Result<()> { | |||
| 75 | sqlx::query( | 75 | sqlx::query( |
| 76 | "CREATE TABLE IF NOT EXISTS triggers ( | 76 | "CREATE TABLE IF NOT EXISTS triggers ( |
| 77 | id INTEGER PRIMARY KEY AUTOINCREMENT, | 77 | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| 78 | name TEXT UNIQUE NOT NULL, | 78 | guild_id INTEGER NOT NULL DEFAULT 0, |
| 79 | name TEXT NOT NULL, | ||
| 79 | created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | 80 | created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| 80 | last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 81 | last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| 82 | UNIQUE(guild_id, name) | ||
| 81 | )", | 83 | )", |
| 82 | ) | 84 | ) |
| 83 | .execute(pool) | 85 | .execute(pool) |
| 84 | .await?; | 86 | .await?; |
| 85 | 87 | ||
| 88 | // Add guild_id for pre-existing trigger tables. (The old table also kept a | ||
| 89 | // global UNIQUE(name), so existing databases still require unique trigger | ||
| 90 | // names across guilds; new databases use UNIQUE(guild_id, name).) | ||
| 91 | sqlx::query("ALTER TABLE triggers ADD COLUMN guild_id INTEGER NOT NULL DEFAULT 0") | ||
| 92 | .execute(pool) | ||
| 93 | .await | ||
| 94 | .ok(); | ||
| 95 | |||
| 86 | sqlx::query( | 96 | sqlx::query( |
| 87 | "CREATE TABLE IF NOT EXISTS trigger_keywords ( | 97 | "CREATE TABLE IF NOT EXISTS trigger_keywords ( |
| 88 | id INTEGER PRIMARY KEY AUTOINCREMENT, | 98 | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| @@ -416,6 +426,7 @@ pub async fn set_cron_job_active( | |||
| 416 | #[derive(Debug, Clone, FromRow)] | 426 | #[derive(Debug, Clone, FromRow)] |
| 417 | pub struct Trigger { | 427 | pub struct Trigger { |
| 418 | pub id: i64, | 428 | pub id: i64, |
| 429 | pub guild_id: i64, | ||
| 419 | pub name: String, | 430 | pub name: String, |
| 420 | pub created_at: Option<DateTime<Utc>>, | 431 | pub created_at: Option<DateTime<Utc>>, |
| 421 | pub last_updated: Option<DateTime<Utc>>, | 432 | pub last_updated: Option<DateTime<Utc>>, |
| @@ -437,33 +448,45 @@ pub struct TriggerResponse { | |||
| 437 | pub response_text: String, | 448 | pub response_text: String, |
| 438 | } | 449 | } |
| 439 | 450 | ||
| 440 | pub async fn create_trigger(pool: &DbPool, name: &str) -> Result<i64> { | 451 | pub async fn create_trigger(pool: &DbPool, guild_id: i64, name: &str) -> Result<i64> { |
| 441 | let result = sqlx::query("INSERT INTO triggers (name) VALUES (?)") | 452 | let result = sqlx::query("INSERT INTO triggers (guild_id, name) VALUES (?, ?)") |
| 453 | .bind(guild_id) | ||
| 442 | .bind(name) | 454 | .bind(name) |
| 443 | .execute(pool) | 455 | .execute(pool) |
| 444 | .await?; | 456 | .await?; |
| 445 | Ok(result.last_insert_rowid()) | 457 | Ok(result.last_insert_rowid()) |
| 446 | } | 458 | } |
| 447 | 459 | ||
| 448 | pub async fn delete_trigger(pool: &DbPool, id: i64) -> Result<bool> { | 460 | pub async fn delete_trigger(pool: &DbPool, id: i64, guild_id: i64) -> Result<bool> { |
| 449 | let result = sqlx::query("DELETE FROM triggers WHERE id = ?") | 461 | let result = sqlx::query("DELETE FROM triggers WHERE id = ? AND guild_id = ?") |
| 450 | .bind(id) | 462 | .bind(id) |
| 463 | .bind(guild_id) | ||
| 451 | .execute(pool) | 464 | .execute(pool) |
| 452 | .await?; | 465 | .await?; |
| 453 | Ok(result.rows_affected() > 0) | 466 | Ok(result.rows_affected() > 0) |
| 454 | } | 467 | } |
| 455 | 468 | ||
| 456 | pub async fn get_trigger_by_name(pool: &DbPool, name: &str) -> Result<Option<Trigger>> { | 469 | pub async fn get_trigger_by_name( |
| 457 | Ok(sqlx::query_as("SELECT * FROM triggers WHERE name = ?") | 470 | pool: &DbPool, |
| 458 | .bind(name) | 471 | guild_id: i64, |
| 459 | .fetch_optional(pool) | 472 | name: &str, |
| 460 | .await?) | 473 | ) -> Result<Option<Trigger>> { |
| 474 | Ok( | ||
| 475 | sqlx::query_as("SELECT * FROM triggers WHERE guild_id = ? AND name = ?") | ||
| 476 | .bind(guild_id) | ||
| 477 | .bind(name) | ||
| 478 | .fetch_optional(pool) | ||
| 479 | .await?, | ||
| 480 | ) | ||
| 461 | } | 481 | } |
| 462 | 482 | ||
| 463 | pub async fn list_triggers(pool: &DbPool) -> Result<Vec<Trigger>> { | 483 | pub async fn list_triggers(pool: &DbPool, guild_id: i64) -> Result<Vec<Trigger>> { |
| 464 | Ok(sqlx::query_as("SELECT * FROM triggers ORDER BY name") | 484 | Ok( |
| 465 | .fetch_all(pool) | 485 | sqlx::query_as("SELECT * FROM triggers WHERE guild_id = ? ORDER BY name") |
| 466 | .await?) | 486 | .bind(guild_id) |
| 487 | .fetch_all(pool) | ||
| 488 | .await?, | ||
| 489 | ) | ||
| 467 | } | 490 | } |
| 468 | 491 | ||
| 469 | pub async fn add_keyword(pool: &DbPool, trigger_id: i64, keyword: &str) -> Result<()> { | 492 | pub async fn add_keyword(pool: &DbPool, trigger_id: i64, keyword: &str) -> Result<()> { |
| @@ -526,7 +549,11 @@ pub async fn get_responses(pool: &DbPool, trigger_id: i64) -> Result<Vec<String> | |||
| 526 | pub async fn load_all_triggers_with_keywords_and_responses( | 549 | pub async fn load_all_triggers_with_keywords_and_responses( |
| 527 | pool: &DbPool, | 550 | pool: &DbPool, |
| 528 | ) -> Result<Vec<(Trigger, Vec<String>, Vec<String>)>> { | 551 | ) -> Result<Vec<(Trigger, Vec<String>, Vec<String>)>> { |
| 529 | let triggers = list_triggers(pool).await?; | 552 | // The event cache needs every guild's triggers; `/trigger list` and |
| 553 | // mutations use the guild-scoped helpers above. | ||
| 554 | let triggers: Vec<Trigger> = sqlx::query_as("SELECT * FROM triggers ORDER BY name") | ||
| 555 | .fetch_all(pool) | ||
| 556 | .await?; | ||
| 530 | let mut result = Vec::new(); | 557 | let mut result = Vec::new(); |
| 531 | for t in triggers { | 558 | for t in triggers { |
| 532 | let keywords = get_keywords(pool, t.id).await?; | 559 | let keywords = get_keywords(pool, t.id).await?; |
