### Create and query a GratefulDead graph Source: https://flatgraph.joern.io/index.html Uses the generated domain classes to create an empty graph, build a diff graph with two artists and one song, add edges, apply the diff, and run type-safe queries. Demonstrates that nodes referenced in edges do not need separate addNode calls. ```scala val gratefulDead = GratefulDead.empty // create a simple graph with two nodes and two edges val diffGraph = GratefulDead.newDiffGraphBuilder val garcia = NewArtist().name("Garcia") val boDiddley = NewArtist().name("Bo_Diddley") val heyBoDiddley = NewSong().name("HEY BO DIDDLEY").songtype("cover").performances(5) // n.b. if nodes are referenced in edges, they don't need to be added separately via `diffGraph.addNode` diffGraph.addEdge(src = heyBoDiddley, dst = boDiddley, Writtenby.Label) diffGraph.addEdge(src = heyBoDiddley, dst = garcia, Sungby.Label) DiffGraphApplier.applyDiff(gratefulDead.graph, diffGraph) // now query it in the typesafe domain-specific query language gratefulDead.artist.name.sorted shouldBe List("Bo_Diddley", "Garcia") gratefulDead.artist.name("Garcia").sang.name.l shouldBe List("HEY BO DIDDLEY") gratefulDead.song.writtenBy.name.l shouldBe List("Bo_Diddley") ``` -------------------------------- ### Define GratefulDead schema with SchemaBuilder Source: https://flatgraph.joern.io/index.html Defines the GratefulDead domain schema: properties 'name' and 'songType', node types 'artist' and 'song', and an edge type 'sungBy' with cardinality One. The schema is used by the code generator to produce domain-specific classes. ```scala val builder = new SchemaBuilder("GratefulDead", basePackage = "testdomains.gratefuldead") val name = builder.addProperty("name", ValueType.String).mandatory(default = "") val songType = builder.addProperty("songType", ValueType.String) val artist = builder.addNodeType("artist").addProperty(name) val song = builder.addNodeType("song").addProperty(name).addProperty(songType) val sungBy = builder.addEdgeType("sungBy") song.addOutEdge( sungBy, inNode = artist, cardinalityOut = Cardinality.One, stepNameOut = "sungBy", stepNameIn = "sang") ``` -------------------------------- ### Map Step for Property Extraction Source: https://flatgraph.joern.io/traversals/index.html Uses the map step to extract the IS_EXTERNAL and NAME properties from METHOD nodes in the Code Property Graph. ```scala joern> cpg.method.map(node => (node.isExternal, node.name)).toList res6: List[(Boolean, String)] = List( (false, "main"), (true, "fprintf"), (true, "exit"), (true, ".logicalAnd"), (true, ".equals"), (true, ".greaterThan"), (true, "strcmp"), (true, ".indirectIndexAccess"), (true, "printf") ) ``` -------------------------------- ### Filter METHOD nodes by IS_EXTERNAL property Source: https://flatgraph.joern.io/traversals/index.html These three queries return the names of METHOD nodes with IS_EXTERNAL set to false. The first uses the filter step with a lambda predicate; the second uses the property-filter step isExternal(false); the third rewrites the same query using the where step with a traversal predicate. All produce the same result: List("main"). ```scala joern> cpg.method.filter(_.isExternal == false).name.toList res11: List[String] = List("main") ``` ```scala joern> cpg.method.isExternal(false).name.toList res11: List[String] = List("main") ``` ```scala joern> cpg.method.where(_.isExternal(false)).name.toList res24: List[String] = List("main") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.