| 526 | } |
| 527 | |
| 528 | fn has_migration<C: Deref<Target = Connection>>( |
| 529 | conn: &C, |
| 530 | version: usize, |
| 531 | max_version: Option<i64>, |
| 532 | ) -> Result<bool, DatabaseError> { |
| 533 | // IMPORTANT: Due to a bug with the first 7 migrations, we have to check manually |
| 534 | // |
| 535 | // Background: the migrations table stores two identifying keys: the sqlite auto-generated |
| 536 | // auto-incrementing key `id`, and the `version` which is the index of the `MIGRATIONS` |
| 537 | // constant. |
| 538 | // |
| 539 | // Checking whether a migration exists would compare id with version, but since id is 1-indexed |
| 540 | // and version is 0-indexed, we would actually skip the last migration! Therefore, it's |
| 541 | // possible users are missing a critical migration (namely, auth_kv table creation) when |
| 542 | // upgrading to the qchat build (which includes two new migrations). Hence, we have to check |
| 543 | // all migrations until version 7 to make sure that nothing is missed. |
| 544 | if version <= 7 { |
| 545 | let mut stmt = match conn.prepare("SELECT COUNT(*) FROM migrations WHERE version = ?1") { |
| 546 | Ok(stmt) => stmt, |
| 547 | // If the migrations table does not exist, then we can reasonably say no migrations |
| 548 | // will exist. |
| 549 | Err(Error::SqliteFailure(_, Some(msg))) if msg.contains("no such table") => { |
| 550 | return Ok(false); |
| 551 | }, |
| 552 | Err(err) => return Err(err.into()), |
| 553 | }; |
| 554 | let count: i32 = stmt.query_row([version], |row| row.get(0))?; |
| 555 | return Ok(count >= 1); |
| 556 | } |
| 557 | |
| 558 | // Continuing from the previously implemented logic - any migrations after the 7th can have a simple |
| 559 | // maximum version check, since we can reasonably assume if any version >=7 will have all |
| 560 | // migrations prior to it. |
| 561 | #[allow(clippy::match_like_matches_macro)] |
| 562 | Ok(match max_version { |
| 563 | Some(max_version) if max_version >= version as i64 => true, |
| 564 | _ => false, |
| 565 | }) |
| 566 | } |
| 567 | |
| 568 | #[cfg(test)] |
| 569 | mod tests { |