diff --git a/entity/src/relationship.rs b/entity/src/relationship.rs index 669221cb7..3415bf47d 100644 --- a/entity/src/relationship.rs +++ b/entity/src/relationship.rs @@ -50,6 +50,8 @@ pub enum Relationship { #[sea_orm(num_value = 14)] PackageOf, #[sea_orm(num_value = 15)] + Contains, + #[sea_orm(num_value = 16)] Undefined, } diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 2f902e110..cbcf43901 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -101,6 +101,7 @@ mod m0000810_fix_get_purl; mod m0000820_create_conversation; mod m0000830_perf_indexes; mod m0000840_add_relationship_14_15; +mod m0000850_normalise_relationships; pub struct Migrator; @@ -209,6 +210,7 @@ impl MigratorTrait for Migrator { Box::new(m0000820_create_conversation::Migration), Box::new(m0000830_perf_indexes::Migration), Box::new(m0000840_add_relationship_14_15::Migration), + Box::new(m0000850_normalise_relationships::Migration), ] } } diff --git a/migration/src/m0000850_normalise_relationships.rs b/migration/src/m0000850_normalise_relationships.rs new file mode 100644 index 000000000..bd0da90ff --- /dev/null +++ b/migration/src/m0000850_normalise_relationships.rs @@ -0,0 +1,41 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; +const DATA: [(i32, &str); 1] = [(16, "Contains")]; +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + for (id, description) in DATA { + let insert = Query::insert() + .into_table(Relationship::Table) + .columns([Relationship::Id, Relationship::Description]) + .values_panic([id.into(), description.into()]) + .to_owned(); + + manager.exec_stmt(insert).await?; + } + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + for (id, _) in DATA { + let insert = Query::delete() + .from_table(Relationship::Table) + .and_where(Expr::col(Relationship::Id).lt(id)) + .to_owned(); + + manager.exec_stmt(insert).await?; + } + + Ok(()) + } +} + +#[derive(DeriveIden)] +pub enum Relationship { + Table, + Id, + Description, +} diff --git a/modules/analysis/src/service/mod.rs b/modules/analysis/src/service/mod.rs index eff7d26ae..c52b35f90 100644 --- a/modules/analysis/src/service/mod.rs +++ b/modules/analysis/src/service/mod.rs @@ -56,11 +56,11 @@ pub fn dep_nodes( return; } visited.insert(node); - for neighbor in graph.neighbors_directed(node, Direction::Incoming) { + for neighbor in graph.neighbors_directed(node, Direction::Outgoing) { if let Some(dep_packagenode) = graph.node_weight(neighbor).cloned() { // Attempt to find the edge and get the relationship in a more elegant way if let Some(relationship) = graph - .find_edge(neighbor, node) + .find_edge(node, neighbor) .and_then(|edge_index| graph.edge_weight(edge_index)) { let dep_node = DepNode { @@ -102,10 +102,10 @@ pub fn ancestor_nodes( while let Some(node) = stack.pop() { if discovered.visit(node) { - for succ in graph.neighbors_directed(node, Direction::Outgoing) { + for succ in graph.neighbors_directed(node, Direction::Incoming) { if !discovered.is_visited(&succ) { if let Some(anc_packagenode) = graph.node_weight(succ).cloned() { - if let Some(edge) = graph.find_edge(node, succ) { + if let Some(edge) = graph.find_edge(succ, node) { if let Some(relationship) = graph.edge_weight(edge) { let anc_node = AncNode { sbom_id: anc_packagenode.sbom_id, @@ -133,7 +133,7 @@ pub fn ancestor_nodes( } } } - if graph.neighbors_directed(node, Direction::Outgoing).count() == 0 { + if graph.neighbors_directed(node, Direction::Incoming).count() == 0 { continue; // we are at the root } } diff --git a/modules/ingestor/src/graph/sbom/spdx.rs b/modules/ingestor/src/graph/sbom/spdx.rs index 12a86780f..97972df76 100644 --- a/modules/ingestor/src/graph/sbom/spdx.rs +++ b/modules/ingestor/src/graph/sbom/spdx.rs @@ -252,8 +252,8 @@ impl<'spdx> TryFrom<(&'spdx str, &'spdx RelationshipType, &'spdx str)> for SpdxR match rel { RelationshipType::AncestorOf => Ok((left, Relationship::AncestorOf, right)), RelationshipType::BuildToolOf => Ok((left, Relationship::BuildToolOf, right)), - RelationshipType::ContainedBy => Ok((left, Relationship::ContainedBy, right)), - RelationshipType::Contains => Ok((right, Relationship::ContainedBy, left)), + RelationshipType::ContainedBy => Ok((right, Relationship::Contains, left)), + RelationshipType::Contains => Ok((left, Relationship::Contains, right)), RelationshipType::DependencyOf => Ok((left, Relationship::DependencyOf, right)), RelationshipType::DependsOn => Ok((right, Relationship::DependencyOf, left)), RelationshipType::DescendantOf => Ok((right, Relationship::AncestorOf, left)),