Class: RDF::AggregateRepo

Inherits:
Dataset
  • Object
show all
Defined in:
lib/rdf/aggregate_repo.rb

Overview

TODO:

Allow graph names to reassigned with queryable

An aggregated RDF datset.

Aggregates the default and named graphs from one or more instances implementing RDF::Queryable. By default, the aggregate projects no default or named graphs, which must be added explicitly.

Adding the existing default graph (identified with the name ‘false`) adds the merge of all default graphs from the specified `queryable` instances.

Adding a named graph, adds the last graph found having that name from the specified ‘queryable` instances.

Updating a previously non-existing named graph, appends to the last source. Updating the default graph updates to the merge of the graphs.

Examples:

Constructing an aggregate with arguments

aggregate = RDF::AggregateRepo.new(repo1, repo2)

Constructing an aggregate with closure

aggregate = RDF::AggregateRepo.new do
  source repo1
  source repo2
  default false
  named   RDF::URI("http://example/")
  named   RDF::URI("http://other/")
end

Defined Under Namespace

Modules: VERSION

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(queryable = [], options = {}) {|aggregation| ... } ⇒ AggregateRepo

Create a new aggregation instance.

Parameters:

  • queryable (Array<RDF::Queryable>) (defaults to: [])

    ([])

  • options (Hash{Symbol => Object}) (defaults to: {})

    ({})

Yields:

  • aggregation

Yield Parameters:

Yield Returns:

  • (void)

    ignored



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rdf/aggregate_repo.rb', line 61

def initialize(*queryable, &block)
  @options = queryable.last.is_a?(Hash) ? queryable.pop.dup : {}
  @sources = queryable
  @defaults = []
  @named_graphs = []

  if block_given?
    case block.arity
      when 1 then block.call(self)
      else instance_eval(&block)
    end
  end
end

Instance Attribute Details

#defaultsArray<RDF::URI, false> (readonly)

Names of the named graphs making up the default graph, or false, if it is made up from the merger of all default graphs

Returns:

  • (Array<RDF::URI, false>)


50
51
52
# File 'lib/rdf/aggregate_repo.rb', line 50

def defaults
  @defaults
end

#sourcesArray<RDF::Queryable> (readonly)

The set of aggregated ‘queryable` instances included in this aggregate

Returns:

  • (Array<RDF::Queryable>)


42
43
44
# File 'lib/rdf/aggregate_repo.rb', line 42

def sources
  @sources
end

Instance Method Details

#countInteger

Returns the number of RDF statements in all constituent graphs.

Returns:

  • (Integer)

See Also:

  • Countable#count


156
157
158
# File 'lib/rdf/aggregate_repo.rb', line 156

def count
  each_graph.to_a.reduce(0) {|memo, g| memo += g.count}
end

#default(*names) ⇒ RDF::AggregateRepo

Set the default graph based on zero or more named graphs, or the merge of all default graphs if ‘false`

Parameters:

  • names (Array<RDF::Resource>, false)

Returns:



93
94
95
96
97
98
99
# File 'lib/rdf/aggregate_repo.rb', line 93

def default(*names)
  if names.any? {|n| n == false} && names.length > 1
    raise ArgumentError, "If using merge of default graphs, there can be only one"
  end
  @default_graph = nil
  @defaults = names
end

#default_graphRDF::Graph

Default graph of this aggregate, either a projection of the source default graph (if ‘false`), a particular named graph from the last source in which it appears, or a MergeGraph composed of the graphs which compose it.

Returns:

  • (RDF::Graph)


259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/rdf/aggregate_repo.rb', line 259

def default_graph
  @default_graph ||= begin
    case
    when sources.length == 0 || defaults.length == 0
      RDF::Graph.new
    when defaults == [false] && sources.length == 1
      # Trivial case
      RDF::Graph.new(data: sources.first)
    else
      # Otherwise, create a MergeGraph from the set of pairs of source and graph_name
      RDF::MergeGraph.new(name: nil) do |graph|
        if defaults == [false]
          graph.sources.each do |s|
            # Add default graph from each source
            source s, false
          end
        else
          defaults.each do |graph_name|
            # add the named graph
            graph.source sources.reverse.detect {|s| s.has_graph?(graph_name)}, graph_name
          end
        end
      end
    end
  end
end

#durable?Boolean

Returns ‘true` all constituent graphs are durable.

Returns:

  • (Boolean)

See Also:

  • Durable#durable?


138
139
140
# File 'lib/rdf/aggregate_repo.rb', line 138

def durable?
  sources.all?(&:durable?)
end

#each {|statement| ... } ⇒ Enumerator

Enumerates each RDF statement in constituent graphs

Yields:

  • (statement)

Yield Parameters:

  • statement (Statement)

Returns:

  • (Enumerator)

See Also:

  • Enumerable#each


205
206
207
208
# File 'lib/rdf/aggregate_repo.rb', line 205

def each(&block)
  return to_enum unless block_given?
  each_graph {|g| g.each(&block)}
end

#each_graph {|graph| ... } ⇒ void #each_graphEnumerator<RDF::Graph>

Iterate over each graph, in order, finding named graphs from the most recently added ‘source`.

If no block was given, returns an enumerator.

The order in which graphs are yielded is undefined.

Overloads:

  • #each_graph {|graph| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (graph)

      each graph

    Yield Parameters:

    • graph (RDF::Graph)

    Yield Returns:

    • (void)

      ignored

  • #each_graphEnumerator<RDF::Graph>

    Returns:

    • (Enumerator<RDF::Graph>)

See Also:

  • Enumerable#each_graph


239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/rdf/aggregate_repo.rb', line 239

def each_graph(&block)
  if block_given?
    yield default_graph

    # Send graph from appropriate source
    @named_graphs.each do |graph_name|
      source  = sources.reverse.detect {|s| s.has_graph?(graph_name)}
      block.call(RDF::Graph.new(graph_name: graph_name, data: source))
    end
  end
  enum_graph
end

#each_statement {|statement| ... } ⇒ void #each_statementEnumerator

This method returns an undefined value.

Iterates the given block for each RDF statement.

If no block was given, returns an enumerator.

The order in which statements are yielded is undefined.

Overloads:

  • #each_statement {|statement| ... } ⇒ void

    This method returns an undefined value.

    Yields:

    • (statement)

      each statement

    Yield Parameters:

    • statement (RDF::Statement)

    Yield Returns:

    • (void)

      ignored

  • #each_statementEnumerator

    Returns:

    • (Enumerator)

See Also:

  • Repository#each_statement
  • Enumerable#each_statement


190
191
192
193
194
195
196
# File 'lib/rdf/aggregate_repo.rb', line 190

def each_statement(&block)
  if block_given?
    # Invoke {#each} in the containing class:
    each(&block)
  end
  enum_statement
end

#empty?Boolean

Returns ‘true` if all constituent graphs are empty.

Returns:

  • (Boolean)

See Also:

  • Countable#empty?


147
148
149
# File 'lib/rdf/aggregate_repo.rb', line 147

def empty?
  count == 0
end

#has_graph?(value) ⇒ Boolean

Returns ‘true` if any constituent grahp contains the given RDF graph.

Parameters:

  • value (RDF::Resource, false)

    Use value ‘false` to query for the default graph

Returns:

  • (Boolean)

See Also:

  • Enumerable#has_graph?


217
218
219
# File 'lib/rdf/aggregate_repo.rb', line 217

def has_graph?(value)
  @named_graphs.include?(value)
end

#has_statement?(statement) ⇒ Boolean

Returns ‘true` if any constituent graph contains the given RDF statement.

Parameters:

  • statement (RDF::Statement)

Returns:

  • (Boolean)

See Also:

  • Enumerable#has_statement?


166
167
168
# File 'lib/rdf/aggregate_repo.rb', line 166

def has_statement?(statement)
  each_graph.any? {|g| g.has_statement?(statement) && statement.graph_name == g.graph_name}
end

#named(name) ⇒ RDF::AggregateRepo

Add a named graph projection. Dynamically binds to the last ‘queryable` having a matching graph.

Parameters:

  • name (RDF::Resource)

Returns:

Raises:

  • (ArgumentError)


107
108
109
110
111
# File 'lib/rdf/aggregate_repo.rb', line 107

def named(name)
  raise ArgumentError, "name must be an RDF::Resource: #{name.inspect}" unless name.is_a?(RDF::Resource)
  raise ArgumentError, "name does not exist in loaded sources" unless sources.any?{|s| s.has_graph?(name)}
  @named_graphs << name
end

#source(queryable) ⇒ RDF::AggregateRepo Also known as: add

Add a queryable to the set of constituent queryable instances

Parameters:

  • queryable (RDF::Queryable)

Returns:



80
81
82
83
84
# File 'lib/rdf/aggregate_repo.rb', line 80

def source(queryable)
  @sources << queryable
  @default_graph = nil
  self
end

#supports?(feature) ⇒ Boolean

Returns:

  • (Boolean)

See Also:

  • Enumerable#supports?


118
119
120
121
122
123
124
125
# File 'lib/rdf/aggregate_repo.rb', line 118

def supports?(feature)
  case feature.to_sym
  when :graph_name        then @options[:with_graph_name]
  when :validity          then @options.fetch(:with_validity, true)
  when :literal_equality  then sources.all? {|s| s.supports?(:literal_equality)}
  else false
  end
end

#writable?false

Not writable

Returns:

  • (false)


131
# File 'lib/rdf/aggregate_repo.rb', line 131

def writable?; false; end