use sqlx::PgPool;
pub async fn init_db(pool: &PgPool) -> Result<(), sqlx::Error> {
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS transfer_matrices (
config_hash VARCHAR(64) PRIMARY KEY,
station_count INTEGER NOT NULL,
launch_velocity_kms REAL NOT NULL,
matrix_bytes BYTEA NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
accessed_at TIMESTAMPTZ DEFAULT NOW()
);
"#,
)
.execute(pool)
.await?;
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS cached_routes (
id SERIAL PRIMARY KEY,
config_hash VARCHAR(64) REFERENCES transfer_matrices(config_hash) ON DELETE CASCADE,
from_station INTEGER NOT NULL,
to_station INTEGER NOT NULL,
route_json JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(config_hash, from_station, to_station)
);
"#,
)
.execute(pool)
.await?;
tracing::info!("Database tables initialized");
Ok(())
}
pub async fn store_matrix(
pool: &PgPool,
config_hash: &str,
station_count: i32,
launch_velocity_kms: f32,
matrix_bytes: &[u8],
) -> Result<(), sqlx::Error> {
sqlx::query(
r#"
INSERT INTO transfer_matrices (config_hash, station_count, launch_velocity_kms, matrix_bytes)
VALUES ($1, $2, $3, $4)
ON CONFLICT (config_hash) DO UPDATE
SET station_count = EXCLUDED.station_count,
launch_velocity_kms = EXCLUDED.launch_velocity_kms,
matrix_bytes = EXCLUDED.matrix_bytes,
accessed_at = NOW()
"#,
)
.bind(config_hash)
.bind(station_count)
.bind(launch_velocity_kms)
.bind(matrix_bytes)
.execute(pool)
.await?;
Ok(())
}
pub async fn get_matrix(
pool: &PgPool,
config_hash: &str,
) -> Result