Module: Reddy

Defined in:
lib/reddy/bnode.rb,
lib/reddy/graph.rb,
lib/reddy/parser.rb,
lib/reddy/triple.rb,
lib/reddy/uriref.rb,
lib/reddy/literal.rb,
lib/reddy/n3parser.rb,
lib/reddy/namespace.rb,
lib/reddy/exceptions.rb,
lib/reddy/rdfaparser.rb,
lib/reddy/rdfxmlparser.rb,
lib/reddy/store/list_store.rb,
lib/reddy/conjunctive_graph.rb,
lib/reddy/store/memory_store.rb,
lib/reddy/store/abstract_store.rb

Defined Under Namespace

Classes: AbstractStore, BNode, BNodeException, ConjunctiveGraph, Graph, GraphException, InvalidObject, InvalidPredicate, InvalidSubject, ListStore, Literal, MemoryStore, N3Parser, Namespace, Parser, ParserException, RdfException, RdfXmlParser, RdfaParser, StoreException, Triple, TypeError, URIRef

Instance Method Summary collapse

Instance Method Details

#add(triple, context, quoted = false) ⇒ Object

Add a triple to the store Add to default context, if context is nil



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/reddy/store/memory_store.rb', line 62

def add(triple, context, quoted = false)
  context = context.identifier if context.respond_to?(:identifier)
  context ||= @identifier
  return unless triples(triple, context).empty?
  
  # Assign keys for new identifiers
  si = resource_to_int(triple.subject) || gen_key(triple.subject)
  pi = resource_to_int(triple.predicate) || gen_key(triple.predicate)
  oi = resource_to_int(triple.object) || gen_key(triple.object)
  ci = resource_to_int(context) || gen_key(context)
  
  #puts "add: #{si}, #{pi}, #{oi}, #{ci}" if $DEBUG
  set_nested_index(@cspo, ci, si, pi, oi)
  set_nested_index(@cpos, ci, pi, oi, si)
  set_nested_index(@cosp, ci, oi, si, pi)
  
  unless quoted
    set_nested_index(@spo, si, pi, oi, ci)
    set_nested_index(@pos, pi, oi, si, ci)
    set_nested_index(@osp, oi, si, pi, ci)
  end
  #dump if $DEBUG
end

#contains?(triple, context = nil) ⇒ Boolean

Check to see if this store contains the specified triple

Note, if triple contains a Literal object, need to wild-card and check each result individually due to variation in literal comparisons

Returns:

  • (Boolean)


232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/reddy/store/memory_store.rb', line 232

def contains?(triple, context = nil)
  #puts "contains? #{triple}"
  object = triple.object
  if object.is_a?(Literal)
    triple = Triple.new(triple.subject, triple.predicate, nil)
    triples(triple, context) do |t, cg|
      return true if t.object == object
    end
    false
  else
    !triples(triple, context).empty?
  end
end

#contexts(triple = nil) ⇒ Object

Contexts containing the triple (no matching), or total number of contexts in store



267
268
269
270
271
272
273
274
275
# File 'lib/reddy/store/memory_store.rb', line 267

def contexts(triple = nil)
  if triple
    si, pi, oi = triple_to_int(triple)
    value = @spo[si][pi][oi]
    (value && value.keys.map {|ci| int_to_resource(ci)}) || []
  else
    @cspo.keys.map {|ci| int_to_resource(ci)}
  end
end

#dumpObject



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/reddy/store/memory_store.rb', line 48

def dump
  puts "MemoryStore: #{identifier}\n" +
    "  cspo: #{@cspo.inspect}\n" +
    "  cpos: #{@cpos.inspect}\n" +
    "  cosp: #{@cosp.inspect}\n" +
    "  spo: #{@spo.inspect}\n" +
    "  pos: #{@pos.inspect}\n" +
    "  osp: #{@osp.inspect}\n" +
    "  forward: #{@forward.inspect}\n" +
    "  reverse: #{@reverse.inspect}\n"
end

#parse(stream, uri, options = {}, &block) ⇒ Graph

Parse source into Graph.

Merges results into a common Graph

options[:debug]

Array to place debug messages

options[:type]

One of rdfxml, html, or n3

options[:strict]

Raise Error if true, continue with lax parsing, otherwise

Parameters:

  • stream:: (IO, String)

    the RDF IO stream, string, Nokogiri::HTML::Document or Nokogiri::XML::Document

  • uri:: (String)

    the URI of the document

  • options:: (Hash)

    Options from

Returns:

  • (Graph)

    Returns the graph containing parsed triples



324
325
326
# File 'lib/reddy/graph.rb', line 324

def parse(stream, uri, options = {}, &block) # :yields: triple
  Parser.parse(stream, uri, options.merge(:graph => self), &block)
end

#remove(triple, context = nil) ⇒ Object

Remove a triple from the context and store



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/reddy/store/memory_store.rb', line 87

def remove(triple, context = nil)
  context = context.identifier if context.respond_to?(:identifier)
  context = nil if context == @identifier
  
  # Iterate over all matching triples and contexts
  triples(triple, context) do |t, cg|
    si, pi, oi = triple_to_int(t)
    ci = resource_to_int(cg)
    #puts "remove: si=#{si}, pi=#{pi}, oi=#{oi}, ci=#{ci}"
    
    # Remove triple from context
    remove_nested_index(@cspo, ci, si, pi, oi)
    remove_nested_index(@cpos, ci, pi, oi, si)
    remove_nested_index(@cosp, ci, oi, si, pi)

    # Remove context from triple
    remove_nested_index(@spo, si, pi, oi, ci)
    remove_nested_index(@pos, pi, oi, si, ci)
    remove_nested_index(@osp, oi, si, pi, ci)
  end
end

#result(v, si, pi, oi, ctx) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/reddy/store/memory_store.rb', line 133

def result(v, si, pi, oi, ctx)
  t = int_to_triple(si, pi, oi)
  if block_given?
    if v.is_a?(Hash)
      # keys are contexts
      v.keys.each do |ci|
        yield t, int_to_resource(ci)
      end
    else
      #puts "ctx: #{ctx}"
      yield t, ctx
    end
  end
  t
end

#size(context = nil) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/reddy/store/memory_store.rb', line 246

def size(context = nil)
  context = context.identifier if context.respond_to?(:identifier)
  context = nil if context == @identifier
  
  if context.nil?
    spo = @spo
  else
    ci = resource_to_int(context)
    return 0 unless ci
    spo = @cspo[ci]
    return 0 unless spo.is_a?(Hash)
  end
  
  count = 0
  spo.values.each do |po|
     count += po.length
  end
  count
end

#triples(triple, context = nil, &block) ⇒ Object

A generator over all matching triples



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/reddy/store/memory_store.rb', line 110

def triples(triple, context = nil, &block)
  context = context.identifier if context.respond_to?(:identifier)
  context = nil if context == @identifier
  
  if context.nil?
    spo = @spo
    pos = @pos
    osp = @osp
  else
    ci = resource_to_int(context)
    return [] unless ci
    spo = @cspo[ci]
    pos = @cpos[ci]
    osp = @cosp[ci]
    return [] unless spo && pos && osp
  end

  #self.dump
  
  results = []
  si, pi, oi = triple_to_int(triple)
  puts "triples: si=#{si}, pi=#{pi}, oi=#{oi}, ci=#{ci}" if $DEBUG

  def result(v, si, pi, oi, ctx)
    t = int_to_triple(si, pi, oi)
    if block_given?
      if v.is_a?(Hash)
        # keys are contexts
        v.keys.each do |ci|
          yield t, int_to_resource(ci)
        end
      else
        #puts "ctx: #{ctx}"
        yield t, ctx
      end
    end
    t
  end
  
  if si # subject is given
    if spo.has_key?(si)
      #puts "spo[#{si}] = #{spo[si].inspect}" if $DEBUG
      if pi # subject+predicate is given
        if spo[si].has_key?(pi)
          if oi # subject+predicate+object is given
            #puts "spo[#{si}][#{pi}][#{oi}] = #{spo[si][pi][oi].inspect}"
            results << result(spo[si][pi][oi], si, pi, oi, context, &block) if spo[si][pi].has_key?(oi)
          elsif triple.object.nil? # subject+predicate is given, object unbound
            spo[si][pi].each_pair do |oi, value|
              results << result(value, si, pi, oi, context, &block)
            end
            oi = nil
          end
        end
      elsif triple.predicate.nil? # subject given, predicate unbound
        spo[si].keys.each do |pi|
          #puts "spo[#{si}][#{pi}] = #{spo[si][pi].inspect}" if $DEBUG
          if oi # object is given
            results << result(spo[si][pi][oi], si, pi, oi, context, &block) if spo[si][pi].has_key?(oi)
          else # object unbound
            #puts "spo[#{si}][#{pi}] = #{spo[si][pi].inspect}"
            spo[si][pi].each_pair do |oi, value|
              #puts "spo[#{si}][#{pi}][#{oi}] = #{spo[si][pi][oi].inspect}" if $DEBUG
              results << result(value, si, pi, oi, context, &block)
            end
            oi = nil
          end
        end
      end
    end
  elsif !triple.subject.nil?
    # Subject specified, but not found, skip
  elsif pi # subject unbound, predicate given
    if pos.has_key?(pi)
      if oi # subject unbound, predicate+object given
        if pos[pi].has_key?(oi)
          pos[pi][oi].each_pair do |si, value|
            results << result(value, si, pi, oi, context, &block)
          end
        end
      elsif triple.object.nil? # subject unbound, predicate given, object unbound
        pos[pi].keys.each do |oi|
          pos[pi][oi].each_pair do |si, value|
            results << result(value, si, pi, oi, context, &block)
          end
        end
        oi = nil
      end
    end
  elsif !triple.predicate.nil?
    # Subject unspecified, predicate specified but not found, skip
  elsif oi # subject+predicate unbound, object given
    if osp.has_key?(oi)
      osp[oi].keys.each do |si|
        osp[oi][si].each_pair do |pi, value|
          results << result(value, si, pi, oi, context, &block)
        end
      end
    end
  elsif !triple.object.nil?
    # Subject+predicate unspecified, object specified but not found, skip
  else # subject+predicate+object unbound
    puts "spo = #{spo.inspect}" if $DEBUG
    spo.keys.each do |si|
      puts "spo[#{si}] = #{spo[si].inspect}" if $DEBUG
      spo[si].keys.each do |pi|
        puts "spo[#{si}][#{pi}] = #{spo[si][pi].inspect}" if $DEBUG
        spo[si][pi].each_pair do |oi, value|
          puts "spo[#{si}][#{pi}][#{oi}] = #{spo[si][pi][oi].inspect}" if $DEBUG
          results << result(value, si, pi, oi, context, &block)
        end
      end
    end
  end
  results
end