1
Fork 0
mirror of https://github.com/RGBCube/dix synced 2025-07-28 12:17:45 +00:00

feat: Connection newtype

This commit is contained in:
RGBCube 2025-05-08 22:22:43 +03:00 committed by bloxx12
parent db09147da6
commit 574142c4a0
2 changed files with 125 additions and 116 deletions

View file

@ -1,4 +1,24 @@
use std::path::{
Path,
PathBuf,
};
use derive_more::Deref;
use ref_cast::RefCast;
pub mod error; pub mod error;
pub mod print; pub mod print;
pub mod store; pub mod store;
pub mod util; pub mod util;
#[derive(Deref, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DerivationId(i64);
#[derive(RefCast, Deref, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct StorePath(Path);
#[derive(Deref, Debug, Clone, PartialEq, Eq)]
pub struct StorePathBuf(PathBuf);

View file

@ -1,23 +1,21 @@
use std::{ use std::result;
path::{
Path,
PathBuf,
},
result,
};
use anyhow::{ use anyhow::{
Context as _, Context as _,
Result, Result,
}; };
use derive_more::Deref; use derive_more::Deref;
use ref_cast::RefCast;
use rusqlite::Connection;
use rustc_hash::{ use rustc_hash::{
FxBuildHasher, FxBuildHasher,
FxHashMap, FxHashMap,
}; };
use crate::{
DerivationId,
StorePath,
StorePathBuf,
};
macro_rules! path_to_str { macro_rules! path_to_str {
($path:ident) => { ($path:ident) => {
let $path = $path.canonicalize().with_context(|| { let $path = $path.canonicalize().with_context(|| {
@ -36,32 +34,26 @@ macro_rules! path_to_str {
}; };
} }
#[derive(Deref, Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Deref)]
pub struct DerivationId(i64); pub struct Connection(rusqlite::Connection);
#[expect(clippy::module_name_repetitions)]
#[derive(RefCast, Deref, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct StorePath(Path);
#[expect(clippy::module_name_repetitions)]
#[derive(Deref, Debug, Clone, PartialEq, Eq)]
pub struct StorePathBuf(PathBuf);
/// Connects to the Nix database. /// Connects to the Nix database.
pub fn connect() -> Result<Connection> { pub fn connect() -> Result<Connection> {
const DATABASE_PATH: &str = "/nix/var/nix/db/db.sqlite"; const DATABASE_PATH: &str = "/nix/var/nix/db/db.sqlite";
Connection::open(DATABASE_PATH).with_context(|| { let inner = rusqlite::Connection::open(DATABASE_PATH).with_context(|| {
format!("failed to connect to Nix database at {DATABASE_PATH}") format!("failed to connect to Nix database at {DATABASE_PATH}")
}) })?;
Ok(Connection(inner))
} }
/// Gathers all derivations that the given store path depends on. impl Connection {
pub fn query_depdendents( /// Gathers all derivations that the given store path depends on.
connection: &mut Connection, pub fn query_depdendents(
&mut self,
path: &StorePath, path: &StorePath,
) -> Result<Vec<(DerivationId, StorePathBuf)>> { ) -> Result<Vec<(DerivationId, StorePathBuf)>> {
const QUERY: &str = " const QUERY: &str = "
WITH RECURSIVE WITH RECURSIVE
graph(p) AS ( graph(p) AS (
@ -78,8 +70,7 @@ pub fn query_depdendents(
path_to_str!(path); path_to_str!(path);
let packages: result::Result<Vec<(DerivationId, StorePathBuf)>, _> = let packages: result::Result<Vec<(DerivationId, StorePathBuf)>, _> = self
connection
.prepare_cached(QUERY)? .prepare_cached(QUERY)?
.query_map([path], |row| { .query_map([path], |row| {
Ok(( Ok((
@ -90,14 +81,11 @@ pub fn query_depdendents(
.collect(); .collect();
Ok(packages?) Ok(packages?)
} }
/// Gets the total closure size of the given store path by summing up the nar /// Gets the total closure size of the given store path by summing up the nar
/// size of all depdendent derivations. /// size of all depdendent derivations.
pub fn query_closure_size( pub fn query_closure_size(&mut self, path: &StorePath) -> Result<usize> {
connection: &mut Connection,
path: &StorePath,
) -> Result<usize> {
const QUERY: &str = " const QUERY: &str = "
WITH RECURSIVE WITH RECURSIVE
graph(p) AS ( graph(p) AS (
@ -114,23 +102,23 @@ pub fn query_closure_size(
path_to_str!(path); path_to_str!(path);
let closure_size = connection let closure_size = self
.prepare_cached(QUERY)? .prepare_cached(QUERY)?
.query_row([path], |row| row.get(0))?; .query_row([path], |row| row.get(0))?;
Ok(closure_size) Ok(closure_size)
} }
/// Gathers the complete dependency graph of of the store path as an adjacency /// Gathers the complete dependency graph of of the store path as an adjacency
/// list. /// list.
/// ///
/// We might want to collect the paths in the graph directly as /// We might want to collect the paths in the graph directly as
/// well in the future, depending on how much we use them /// well in the future, depending on how much we use them
/// in the operations on the graph. /// in the operations on the graph.
pub fn query_dependency_graph( pub fn query_dependency_graph(
connection: &mut Connection, &mut self,
path: &StorePath, path: &StorePath,
) -> Result<FxHashMap<DerivationId, Vec<DerivationId>>> { ) -> Result<FxHashMap<DerivationId, Vec<DerivationId>>> {
const QUERY: &str = " const QUERY: &str = "
WITH RECURSIVE WITH RECURSIVE
graph(p, c) AS ( graph(p, c) AS (
@ -150,7 +138,7 @@ pub fn query_dependency_graph(
let mut adj = let mut adj =
FxHashMap::<DerivationId, Vec<DerivationId>>::with_hasher(FxBuildHasher); FxHashMap::<DerivationId, Vec<DerivationId>>::with_hasher(FxBuildHasher);
let mut statement = connection.prepare_cached(QUERY)?; let mut statement = self.prepare_cached(QUERY)?;
let edges = statement.query_map([path], |row| { let edges = statement.query_map([path], |row| {
Ok((DerivationId(row.get(0)?), DerivationId(row.get(1)?))) Ok((DerivationId(row.get(0)?), DerivationId(row.get(1)?)))
@ -164,4 +152,5 @@ pub fn query_dependency_graph(
} }
Ok(adj) Ok(adj)
}
} }