mirror of
https://github.com/RGBCube/dix
synced 2025-07-28 04:07:46 +00:00
store: Add derivation dependency graph query
This commit is contained in:
parent
719e6eca41
commit
9a2a5cb4ff
2 changed files with 56 additions and 6 deletions
|
@ -97,6 +97,7 @@ fn main() {
|
|||
println!("<<< {}", args.path.to_string_lossy());
|
||||
println!(">>> {}", args.path2.to_string_lossy());
|
||||
|
||||
|
||||
// handles to the threads collecting closure size information
|
||||
// We do this as early as possible because nix is slow.
|
||||
let closure_size_handles = if args.closure_size {
|
||||
|
@ -115,7 +116,7 @@ fn main() {
|
|||
let package_list_pre = match store::get_packages(&args.path) {
|
||||
Ok(packages) => {
|
||||
debug!("Found {} packages in first closure", packages.len());
|
||||
packages
|
||||
packages.into_iter().map(|(_, path)| path).collect()
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
|
@ -135,7 +136,7 @@ fn main() {
|
|||
let package_list_post = match store::get_packages(&args.path2) {
|
||||
Ok(packages) => {
|
||||
debug!("Found {} packages in second closure", packages.len());
|
||||
packages
|
||||
packages.into_iter().map(|(_, path)| path).collect()
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
|
@ -184,6 +185,7 @@ fn main() {
|
|||
|
||||
// Difference gives us added and removed packages
|
||||
let added: HashSet<&str> = &post_keys - &pre_keys;
|
||||
|
||||
let removed: HashSet<&str> = &pre_keys - &post_keys;
|
||||
// Get the intersection of the package names for version changes
|
||||
let changed: HashSet<&str> = &pre_keys & &post_keys;
|
||||
|
|
56
src/store.rs
56
src/store.rs
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::error::AppError;
|
||||
use rusqlite::Connection;
|
||||
|
||||
|
@ -14,7 +16,7 @@ WITH RECURSIVE
|
|||
SELECT reference FROM Refs
|
||||
JOIN graph ON referrer = p
|
||||
)
|
||||
SELECT path from graph
|
||||
SELECT id, path from graph
|
||||
JOIN ValidPaths ON id = p;
|
||||
";
|
||||
|
||||
|
@ -32,18 +34,37 @@ SELECT SUM(narSize) as sum from graph
|
|||
JOIN ValidPaths ON p = id;
|
||||
";
|
||||
|
||||
const QUERY_DEPENDENCY_GRAPH: &str = "
|
||||
WITH RECURSIVE
|
||||
graph(p, c) AS (
|
||||
SELECT id as par, reference as chd
|
||||
FROM ValidPaths
|
||||
JOIN Refs ON referrer = id
|
||||
WHERE path = ?
|
||||
UNION
|
||||
SELECT referrer as par, reference as chd FROM Refs
|
||||
JOIN graph ON referrer = c
|
||||
)
|
||||
SELECT p, c from graph;
|
||||
";
|
||||
|
||||
/// executes a query on the nix db directly
|
||||
/// to gather all derivations that the derivation given by the path
|
||||
/// depends on
|
||||
///
|
||||
/// The ids of the derivations in the database are returned as well, since these
|
||||
/// can be used to later convert nodes (represented by the the ids) of the
|
||||
/// dependency graph to actual paths
|
||||
///
|
||||
/// in the future, we might wan't to switch to async
|
||||
pub fn get_packages(path: &std::path::Path) -> Result<Vec<String>> {
|
||||
pub fn get_packages(path: &std::path::Path) -> Result<Vec<(i64, String)>> {
|
||||
let p: String = path.canonicalize()?.to_string_lossy().into_owned();
|
||||
let conn = Connection::open("/nix/var/nix/db/db.sqlite")?;
|
||||
|
||||
let mut stmt = conn.prepare(QUERY_PKGS)?;
|
||||
let queried_pkgs: std::result::Result<Vec<String>, _> =
|
||||
stmt.query_map([p], |row| row.get(0))?.collect();
|
||||
let queried_pkgs: std::result::Result<Vec<(i64, String)>, _> =
|
||||
stmt.query_map([p], |row| Ok((row.get(0)?, row.get(1)?)))?
|
||||
.collect();
|
||||
Ok(queried_pkgs?)
|
||||
}
|
||||
|
||||
|
@ -61,3 +82,30 @@ pub fn get_closure_size(path: &std::path::Path) -> Result<i64> {
|
|||
let queried_sum = stmt.query_row([p], |row| row.get(0))?;
|
||||
Ok(queried_sum)
|
||||
}
|
||||
|
||||
|
||||
/// returns the complete dependency graph of
|
||||
/// of the derivation as an adjacency list. The nodes are
|
||||
/// represented by the DB ids
|
||||
///
|
||||
/// We might want to collect the paths in the graph directly as
|
||||
/// well in the future, depending on how much we use them
|
||||
/// in the operations on the graph
|
||||
///
|
||||
/// The mapping from id to graph can be obtained by using [get_packages]
|
||||
pub fn get_dependency_graph(path: &std::path::Path) -> Result<HashMap<i64, Vec<i64>>> {
|
||||
let p: String = path.canonicalize()?.to_string_lossy().into_owned();
|
||||
let conn = Connection::open("/nix/var/nix/db/db.sqlite")?;
|
||||
|
||||
let mut stmt = conn.prepare(QUERY_DEPENDENCY_GRAPH)?;
|
||||
let mut adj = HashMap::<i64, Vec<i64>>::new();
|
||||
let queried_sum = stmt.query_map(
|
||||
[p],
|
||||
|row| Ok::<(i64, i64), _>((row.get(0)?, row.get(1)?)))?;
|
||||
for row in queried_sum {
|
||||
let (from, to) = row?;
|
||||
adj.entry(from).or_default().push(to);
|
||||
}
|
||||
|
||||
Ok(adj)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue