module SPARQL; module Algebra class Operator ## # The SPARQL GraphPattern `graph` operator. # # This is a wrapper to add a `graph_name` to the query, or an array of statements. # # @example of a query # (prefix ((: )) # (graph ?g # (bgp (triple ?s ?p ?o)))) # # @example named set of statements # (prefix ((: )) # (graph :g # ((triple :s :p :o)))) # # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra class Graph < Operator::Binary include Query NAME = [:graph] ## # A `graph` is an RDF::Query with a graph_name. It can also be used as a container of statements or patterns, or other queryable operators (see GraphGraphPattern) # # @overload self.new(name, bgp) # @param [RDF::Resource] name # @param [RDF::Query] patterns # A sub-query (bgp) # @overload self.new(name, bgp) # @param [RDF::Resource] name # @param [Operator] patterns # A sub-query (GraphGraphPattern) # @overload self.new(name, patterns) # @param [RDF::Resource] name # @param [Array] patterns # Quads # @return [RDF::Query] def self.new(name, patterns, &block) case patterns when RDF::Query # Record that the argument as a (bgp) for re-serialization back to SSE RDF::Query.new(*patterns.patterns, graph_name: name, &block) when Operator super else RDF::Query.new(*patterns, graph_name: name, as_container: true, &block) end end ## # If the second operand is a Query operator: # Executes this query on the given `queryable` graph or repository. # Applies the given `graph_name` to the query, limiting the scope of the query to the specified `graph`, which may be an `RDF::URI` or `RDF::Query::Variable`. # # @param [RDF::Queryable] queryable # the graph or repository to query # @param [Hash{Symbol => Object}] options # any additional keyword options # @yield [solution] # each matching solution # @yieldparam [RDF::Query::Solution] solution # @yieldreturn [void] ignored # @return [RDF::Query::Solutions] # the resulting solution sequence # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra def execute(queryable, options = {}, &block) debug(options) {"Graph #{operands.first}"} graph_name, query = operands.first, operands.last @solutions = queryable.query(query, options.merge(graph_name: graph_name), &block) end ## # Returns an optimized version of this query. # # Return optimized query # # @return [Union, RDF::Query] `self` def optimize operands = operands.map(&:optimize) end ## # Don't do any more rewriting # FIXME: if ooperator is JOIN, and rewritten sub-operators are queries, can do simple merge of sub-graphs # @return [SPARQL::Algebra::Expression] `self` def rewrite(&block) self end end # Graph end # Operator end; end # SPARQL::Algebra