Skip to content

Commit

Permalink
fix circular deps and add purl migration for get_purl psql func
Browse files Browse the repository at this point in the history
  • Loading branch information
JimFuller-RedHat committed Nov 18, 2024
1 parent 0e3a828 commit e8341b7
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 13 deletions.
2 changes: 2 additions & 0 deletions migration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ mod m0000700_advisory_add_reserved;
mod m0000710_create_user_prefs;
mod m0000720_alter_sbom_fix_null_array;
mod m0000730_alter_importer_add_progress;
mod m0000740_ensure_get_purl_fns;

pub struct Migrator;

Expand Down Expand Up @@ -189,6 +190,7 @@ impl MigratorTrait for Migrator {
Box::new(m0000710_create_user_prefs::Migration),
Box::new(m0000720_alter_sbom_fix_null_array::Migration),
Box::new(m0000730_alter_importer_add_progress::Migration),
Box::new(m0000740_ensure_get_purl_fns::Migration),
]
}
}
Expand Down
26 changes: 26 additions & 0 deletions migration/src/m0000740_ensure_get_purl_fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.get_connection()
.execute_unprepared(include_str!("m0000740_ensure_get_purl_fns/get_purl.sql"))
.await
.map(|_| ())?;

Ok(())
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.get_connection()
.execute_unprepared(include_str!("m0000590_get_purl_fns/get_purl.sql"))
.await?;

Ok(())
}
}
33 changes: 33 additions & 0 deletions migration/src/m0000740_ensure_get_purl_fns/get_purl.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
CREATE OR REPLACE FUNCTION get_purl(qualified_purl_id UUID)
RETURNS TEXT AS $$
DECLARE
result TEXT;
BEGIN
SELECT
COALESCE(
'pkg:' || bp.type ||
'/' || COALESCE(bp.namespace, '') || '/' ||
bp.name ||
'@' || vp.version ||
CASE
WHEN qp.qualifiers IS NOT NULL AND qp.qualifiers <> '{}'::jsonb THEN
'?' || (
SELECT string_agg(key || '=' || value, '&')
FROM jsonb_each_text(qp.qualifiers)
)
ELSE
''
END,
qualified_purl_id::text
)
INTO result
FROM
qualified_purl qp
LEFT JOIN versioned_purl vp ON vp.id = qp.versioned_purl_id
LEFT JOIN base_purl bp ON bp.id = vp.base_purl_id
WHERE
qp.id = qualified_purl_id;

RETURN result;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;
1 change: 1 addition & 0 deletions modules/analysis/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct AncestorSummary {
pub struct DepNode {
pub sbom_id: String,
pub node_id: String,
pub relationship: String,
pub purl: String,
pub name: String,
pub version: String,
Expand Down
33 changes: 20 additions & 13 deletions modules/analysis/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ pub struct AnalysisService {
pub fn dep_nodes(
graph: &petgraph::Graph<PackageNode, Relationship, petgraph::Directed>,
node: NodeIndex,
visited: &mut HashSet<NodeIndex>,
) -> Vec<DepNode> {
let mut depnodes = Vec::new();
let mut visited = HashSet::new();
fn dfs(
graph: &petgraph::Graph<PackageNode, Relationship, petgraph::Directed>,
node: NodeIndex,
Expand All @@ -51,16 +51,23 @@ pub fn dep_nodes(
visited.insert(node);
for neighbor in graph.neighbors_directed(node, Direction::Incoming) {
if let Some(dep_packagenode) = graph.node_weight(neighbor).cloned() {
let dep_node = DepNode {
sbom_id: dep_packagenode.sbom_id,
node_id: dep_packagenode.node_id,
purl: dep_packagenode.purl.to_string(),
name: dep_packagenode.name.to_string(),
version: dep_packagenode.version.to_string(),
deps: Vec::new(), // Avoid recursive call to dep_nodes
};
depnodes.push(dep_node);
dfs(graph, neighbor, depnodes, visited);
// Attempt to find the edge and get the relationship in a more elegant way
if let Some(relationship) = graph
.find_edge(neighbor, node)
.and_then(|edge_index| graph.edge_weight(edge_index))
{
let dep_node = DepNode {
sbom_id: dep_packagenode.sbom_id,
node_id: dep_packagenode.node_id,
relationship: relationship.to_string(),
purl: dep_packagenode.purl.to_string(),
name: dep_packagenode.name.to_string(),
version: dep_packagenode.version.to_string(),
deps: dep_nodes(graph, neighbor, visited),
};
depnodes.push(dep_node);
dfs(graph, neighbor, depnodes, visited);
}
} else {
log::warn!(
"Processing descendants node weight for neighbor {:?} not found",
Expand All @@ -69,7 +76,7 @@ pub fn dep_nodes(
}
}
}
dfs(graph, node, &mut depnodes, &mut visited);
dfs(graph, node, &mut depnodes, visited);
depnodes
}

Expand Down Expand Up @@ -530,7 +537,7 @@ impl AnalysisService {
product_version: find_match_package_node
.product_version
.to_string(),
deps: dep_nodes(graph, node_index),
deps: dep_nodes(graph, node_index, &mut HashSet::new()),
});
}
}
Expand Down
3 changes: 3 additions & 0 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2457,6 +2457,7 @@ components:
required:
- sbom_id
- node_id
- relationship
- purl
- name
- version
Expand All @@ -2472,6 +2473,8 @@ components:
type: string
purl:
type: string
relationship:
type: string
sbom_id:
type: string
version:
Expand Down

0 comments on commit e8341b7

Please sign in to comment.