riftenlabs-indexer/src/db/cauldron/config.rs
Dagur Valberg Johannsson ec49bf765b
Improve pool visitor queries; make price a visitor
This adds a big performance boost to pool visitor queries, also moving
token price queries to use the visitor model.
2025-08-19 02:37:28 +02:00

118 lines
3.3 KiB
Rust

// Copyright (C) 2024 Riften Labs AS
//
// This software is licensed under the GNU Affero General Public License (AGPL), version 3.0 or later.
// A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html
use anyhow::{bail, Result};
use rusqlite::{params, Connection};
pub const DB_VERSION: u32 = 4;
const DB_VERSION_KEY: &str = "db_version";
/// Create the config table
pub fn create_table(conn: &Connection) {
conn.execute(
"CREATE TABLE config (
key TEXT PRIMARY KEY,
value TEXT
)",
[],
)
.expect("failed to create config table");
}
/// Add or update config entry
pub fn config_set(conn: &Connection, key: &str, value: &str) {
let mut stmt = conn
.prepare("INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)")
.unwrap();
stmt.execute(params![key, value]).unwrap();
}
/// Get config entry
pub fn config_get(conn: &Connection, key: &str) -> Result<Option<String>> {
let mut stmt = conn.prepare("SELECT value FROM config WHERE key = ?")?;
let mut row = stmt.query([key])?;
if let Some(r) = row.next()? {
Ok(r.get(0)?)
} else {
Ok(None)
}
}
/// Check database version and panic if it doesn't match expected version
pub fn check_db_version(conn: &Connection) -> Result<()> {
let version_str = config_get(conn, DB_VERSION_KEY)?;
match version_str {
Some(version_str) => {
let version: u32 = version_str.parse().unwrap_or(0);
if version != DB_VERSION {
bail!(
"Database version mismatch. Expected {}, got {}",
DB_VERSION,
version
);
}
}
None => {
bail!(
"Database version not found. Expected version {}",
DB_VERSION
);
}
}
Ok(())
}
/// Set database version
pub fn set_db_version(conn: &Connection) {
config_set(conn, DB_VERSION_KEY, &DB_VERSION.to_string());
}
#[cfg(test)]
mod tests {
use super::*;
use rusqlite::Connection;
#[test]
fn test_db_version_functionality() {
// Create a new in-memory database
let conn = Connection::open_in_memory().unwrap();
// Create the config table using the shared function
create_table(&conn);
// Test setting the version
set_db_version(&conn);
// Test getting the version
let version_str = config_get(&conn, DB_VERSION_KEY).unwrap().unwrap();
let version: u32 = version_str.parse().unwrap();
assert_eq!(version, DB_VERSION);
// Test version check should pass
check_db_version(&conn).unwrap();
// Test with wrong version
config_set(&conn, DB_VERSION_KEY, "1");
let result = check_db_version(&conn);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Database version mismatch"));
// Test with missing version
conn.execute("DELETE FROM config WHERE key = ?", [DB_VERSION_KEY])
.unwrap();
let result = check_db_version(&conn);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Database version not found"));
}
}