openlogic-rdf 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +9 -0
  3. data/README +361 -0
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/rdf +18 -0
  7. data/etc/doap.nt +62 -0
  8. data/lib/df.rb +1 -0
  9. data/lib/rdf/cli.rb +200 -0
  10. data/lib/rdf/format.rb +383 -0
  11. data/lib/rdf/mixin/countable.rb +39 -0
  12. data/lib/rdf/mixin/durable.rb +31 -0
  13. data/lib/rdf/mixin/enumerable.rb +637 -0
  14. data/lib/rdf/mixin/indexable.rb +26 -0
  15. data/lib/rdf/mixin/inferable.rb +5 -0
  16. data/lib/rdf/mixin/mutable.rb +191 -0
  17. data/lib/rdf/mixin/queryable.rb +265 -0
  18. data/lib/rdf/mixin/readable.rb +15 -0
  19. data/lib/rdf/mixin/type_check.rb +21 -0
  20. data/lib/rdf/mixin/writable.rb +152 -0
  21. data/lib/rdf/model/graph.rb +263 -0
  22. data/lib/rdf/model/list.rb +731 -0
  23. data/lib/rdf/model/literal/boolean.rb +121 -0
  24. data/lib/rdf/model/literal/date.rb +73 -0
  25. data/lib/rdf/model/literal/datetime.rb +72 -0
  26. data/lib/rdf/model/literal/decimal.rb +86 -0
  27. data/lib/rdf/model/literal/double.rb +189 -0
  28. data/lib/rdf/model/literal/integer.rb +126 -0
  29. data/lib/rdf/model/literal/numeric.rb +184 -0
  30. data/lib/rdf/model/literal/time.rb +87 -0
  31. data/lib/rdf/model/literal/token.rb +47 -0
  32. data/lib/rdf/model/literal/xml.rb +39 -0
  33. data/lib/rdf/model/literal.rb +373 -0
  34. data/lib/rdf/model/node.rb +156 -0
  35. data/lib/rdf/model/resource.rb +28 -0
  36. data/lib/rdf/model/statement.rb +296 -0
  37. data/lib/rdf/model/term.rb +77 -0
  38. data/lib/rdf/model/uri.rb +570 -0
  39. data/lib/rdf/model/value.rb +133 -0
  40. data/lib/rdf/nquads.rb +152 -0
  41. data/lib/rdf/ntriples/format.rb +48 -0
  42. data/lib/rdf/ntriples/reader.rb +239 -0
  43. data/lib/rdf/ntriples/writer.rb +219 -0
  44. data/lib/rdf/ntriples.rb +104 -0
  45. data/lib/rdf/query/pattern.rb +329 -0
  46. data/lib/rdf/query/solution.rb +252 -0
  47. data/lib/rdf/query/solutions.rb +237 -0
  48. data/lib/rdf/query/variable.rb +221 -0
  49. data/lib/rdf/query.rb +404 -0
  50. data/lib/rdf/reader.rb +511 -0
  51. data/lib/rdf/repository.rb +389 -0
  52. data/lib/rdf/transaction.rb +161 -0
  53. data/lib/rdf/util/aliasing.rb +63 -0
  54. data/lib/rdf/util/cache.rb +139 -0
  55. data/lib/rdf/util/file.rb +38 -0
  56. data/lib/rdf/util/uuid.rb +36 -0
  57. data/lib/rdf/util.rb +6 -0
  58. data/lib/rdf/version.rb +19 -0
  59. data/lib/rdf/vocab/cc.rb +18 -0
  60. data/lib/rdf/vocab/cert.rb +13 -0
  61. data/lib/rdf/vocab/dc.rb +63 -0
  62. data/lib/rdf/vocab/dc11.rb +23 -0
  63. data/lib/rdf/vocab/doap.rb +45 -0
  64. data/lib/rdf/vocab/exif.rb +168 -0
  65. data/lib/rdf/vocab/foaf.rb +69 -0
  66. data/lib/rdf/vocab/geo.rb +13 -0
  67. data/lib/rdf/vocab/http.rb +26 -0
  68. data/lib/rdf/vocab/owl.rb +59 -0
  69. data/lib/rdf/vocab/rdfs.rb +17 -0
  70. data/lib/rdf/vocab/rsa.rb +12 -0
  71. data/lib/rdf/vocab/rss.rb +14 -0
  72. data/lib/rdf/vocab/sioc.rb +93 -0
  73. data/lib/rdf/vocab/skos.rb +36 -0
  74. data/lib/rdf/vocab/wot.rb +21 -0
  75. data/lib/rdf/vocab/xhtml.rb +9 -0
  76. data/lib/rdf/vocab/xsd.rb +58 -0
  77. data/lib/rdf/vocab.rb +215 -0
  78. data/lib/rdf/writer.rb +475 -0
  79. data/lib/rdf.rb +192 -0
  80. metadata +173 -0
@@ -0,0 +1,637 @@
1
+ module RDF
2
+ ##
3
+ # An RDF statement enumeration mixin.
4
+ #
5
+ # Classes that include this module must implement an `#each` method that
6
+ # yields {RDF::Statement RDF statements}.
7
+ #
8
+ # @example Checking whether any statements exist
9
+ # enumerable.empty?
10
+ #
11
+ # @example Checking how many statements exist
12
+ # enumerable.count
13
+ #
14
+ # @example Checking whether a specific statement exists
15
+ # enumerable.has_statement?(RDF::Statement(subject, predicate, object))
16
+ # enumerable.has_triple?([subject, predicate, object])
17
+ # enumerable.has_quad?([subject, predicate, object, context])
18
+ #
19
+ # @example Checking whether a specific value exists
20
+ # enumerable.has_subject?(RDF::URI("http://rdf.rubyforge.org/"))
21
+ # enumerable.has_predicate?(RDF::DC.creator)
22
+ # enumerable.has_object?(RDF::Literal("Hello!", :language => :en))
23
+ # enumerable.has_context?(RDF::URI("http://rubyforge.org/"))
24
+ #
25
+ # @example Enumerating all statements
26
+ # enumerable.each_statement do |statement|
27
+ # puts statement.inspect
28
+ # end
29
+ #
30
+ # @example Enumerating all statements in the form of triples
31
+ # enumerable.each_triple do |subject, predicate, object|
32
+ # puts [subject, predicate, object].inspect
33
+ # end
34
+ #
35
+ # @example Enumerating all statements in the form of quads
36
+ # enumerable.each_quad do |subject, predicate, object, context|
37
+ # puts [subject, predicate, object, context].inspect
38
+ # end
39
+ #
40
+ # @example Enumerating all terms
41
+ # enumerable.each_subject { |term| puts term.inspect }
42
+ # enumerable.each_predicate { |term| puts term.inspect }
43
+ # enumerable.each_object { |term| puts term.inspect }
44
+ # enumerable.each_context { |term| puts term.inspect }
45
+ #
46
+ # @example Obtaining all statements
47
+ # enumerable.statements #=> [RDF::Statement(subject1, predicate1, object1), ...]
48
+ # enumerable.triples #=> [[subject1, predicate1, object1], ...]
49
+ # enumerable.quads #=> [[subject1, predicate1, object1, context1], ...]
50
+ #
51
+ # @example Obtaining all unique values
52
+ # enumerable.subjects #=> [subject1, subject2, subject3, ...]
53
+ # enumerable.predicates #=> [predicate1, predicate2, predicate3, ...]
54
+ # enumerable.objects #=> [object1, object2, object3, ...]
55
+ # enumerable.contexts #=> [context1, context2, context3, ...]
56
+ #
57
+ # @see RDF::Graph
58
+ # @see RDF::Repository
59
+ module Enumerable
60
+ extend RDF::Util::Aliasing::LateBound
61
+ include ::Enumerable
62
+ include RDF::Countable # NOTE: must come after ::Enumerable
63
+
64
+ ##
65
+ # Returns `true` if this repository supports the given `feature`.
66
+ #
67
+ # Supported features include:
68
+ # * `:context` supports statements with a context, allowing multiple contexts
69
+ # * `:inferrence` supports RDFS inferrence of queryable contents.
70
+ #
71
+ # @param [Symbol, #to_sym] feature
72
+ # @return [Boolean]
73
+ # @since 0.3.5
74
+ def supports?(feature)
75
+ false
76
+ end
77
+
78
+ ##
79
+ # Returns all RDF statements.
80
+ #
81
+ # @param [Hash{Symbol => Boolean}] options
82
+ # @return [Enumerator<RDF::Statement>]
83
+ # @see #each_statement
84
+ # @see #enum_statement
85
+ def statements(options = {})
86
+ enum_statement
87
+ end
88
+
89
+ ##
90
+ # Returns `true` if `self` contains the given RDF statement.
91
+ #
92
+ # @param [RDF::Statement] statement
93
+ # @return [Boolean]
94
+ def has_statement?(statement)
95
+ !enum_statement.find { |s| s.eql?(statement) }.nil?
96
+ end
97
+ alias_method :include?, :has_statement?
98
+
99
+ ##
100
+ # Iterates the given block for each RDF statement.
101
+ #
102
+ # If no block was given, returns an enumerator.
103
+ #
104
+ # The order in which statements are yielded is undefined.
105
+ #
106
+ # @overload each_statement
107
+ # @yield [statement]
108
+ # each statement
109
+ # @yieldparam [RDF::Statement] statement
110
+ # @yieldreturn [void] ignored
111
+ # @return [void]
112
+ #
113
+ # @overload each_statement
114
+ # @return [Enumerator]
115
+ #
116
+ # @return [void]
117
+ # @see #enum_statement
118
+ def each_statement(&block)
119
+ if block_given?
120
+ # Invoke {#each} in the containing class:
121
+ each(&block)
122
+ end
123
+ enum_statement
124
+ end
125
+
126
+ ##
127
+ # Returns an enumerator for {#each_statement}.
128
+ #
129
+ # @return [Enumerator]
130
+ # @see #each_statement
131
+ def enum_statement
132
+ enum_for(:each_statement).extend(RDF::Queryable, RDF::Enumerable)
133
+ end
134
+ alias_method :enum_statements, :enum_statement
135
+
136
+ ##
137
+ # Returns all RDF triples.
138
+ #
139
+ # @param [Hash{Symbol => Boolean}] options
140
+ # @return [Enumerator<Array(RDF::Resource, RDF::URI, RDF::Term)>]
141
+ # @see #each_triple
142
+ # @see #enum_triple
143
+ def triples(options = {})
144
+ enum_statement.map(&:to_triple).to_enum # TODO: optimize
145
+ end
146
+
147
+ ##
148
+ # Returns `true` if `self` contains the given RDF triple.
149
+ #
150
+ # @param [Array(RDF::Resource, RDF::URI, RDF::Term)] triple
151
+ # @return [Boolean]
152
+ def has_triple?(triple)
153
+ triples.include?(triple)
154
+ end
155
+
156
+ ##
157
+ # Iterates the given block for each RDF triple.
158
+ #
159
+ # If no block was given, returns an enumerator.
160
+ #
161
+ # The order in which triples are yielded is undefined.
162
+ #
163
+ # @overload each_triple
164
+ # @yield [subject, predicate, object]
165
+ # each triple
166
+ # @yieldparam [RDF::Resource] subject
167
+ # @yieldparam [RDF::URI] predicate
168
+ # @yieldparam [RDF::Term] object
169
+ # @yieldreturn [void] ignored
170
+ # @return [void]
171
+ #
172
+ # @overload each_triple
173
+ # @return [Enumerator]
174
+ #
175
+ # @return [void]
176
+ # @see #enum_triple
177
+ def each_triple(&block)
178
+ if block_given?
179
+ each_statement do |statement|
180
+ block.call(*statement.to_triple)
181
+ end
182
+ end
183
+ enum_triple
184
+ end
185
+
186
+ ##
187
+ # Returns an enumerator for {#each_triple}.
188
+ #
189
+ # @return [Enumerator]
190
+ # @see #each_triple
191
+ def enum_triple
192
+ enum_for(:each_triple)
193
+ end
194
+ alias_method :enum_triples, :enum_triple
195
+
196
+ ##
197
+ # Returns all RDF quads.
198
+ #
199
+ # @param [Hash{Symbol => Boolean}] options
200
+ # @return [Enumerator<Array(RDF::Resource, RDF::URI, RDF::Term, RDF::Resource)>]
201
+ # @see #each_quad
202
+ # @see #enum_quad
203
+ def quads(options = {})
204
+ enum_statement.map(&:to_quad).to_enum # TODO: optimize
205
+ end
206
+
207
+ ##
208
+ # Returns `true` if `self` contains the given RDF quad.
209
+ #
210
+ # @param [Array(RDF::Resource, RDF::URI, RDF::Term, RDF::Resource)] quad
211
+ # @return [Boolean]
212
+ def has_quad?(quad)
213
+ quads.include?(quad)
214
+ end
215
+
216
+ ##
217
+ # Iterates the given block for each RDF quad.
218
+ #
219
+ # If no block was given, returns an enumerator.
220
+ #
221
+ # The order in which quads are yielded is undefined.
222
+ #
223
+ # @overload each_quad
224
+ # @yield [subject, predicate, object, context]
225
+ # each quad
226
+ # @yieldparam [RDF::Resource] subject
227
+ # @yieldparam [RDF::URI] predicate
228
+ # @yieldparam [RDF::Term] object
229
+ # @yieldparam [RDF::Resource] context
230
+ # @yieldreturn [void] ignored
231
+ # @return [void]
232
+ #
233
+ # @overload each_quad
234
+ # @return [Enumerator]
235
+ #
236
+ # @return [void]
237
+ # @see #enum_quad
238
+ def each_quad(&block)
239
+ if block_given?
240
+ each_statement do |statement|
241
+ block.call(*statement.to_quad)
242
+ end
243
+ end
244
+ enum_quad
245
+ end
246
+
247
+ ##
248
+ # Returns an enumerator for {#each_quad}.
249
+ #
250
+ # @return [Enumerator]
251
+ # @see #each_quad
252
+ def enum_quad
253
+ enum_for(:each_quad)
254
+ end
255
+ alias_method :enum_quads, :enum_quad
256
+
257
+ ##
258
+ # Returns all unique RDF subject terms.
259
+ #
260
+ # @param [Hash{Symbol => Boolean}] options
261
+ # @option options [Boolean] :unique (true)
262
+ # @return [Enumerator<RDF::Resource>]
263
+ # @see #each_subject
264
+ # @see #enum_subject
265
+ def subjects(options = {})
266
+ if options[:unique] == false
267
+ enum_statement.map(&:subject).to_enum # TODO: optimize
268
+ else
269
+ enum_subject
270
+ end
271
+ end
272
+
273
+ ##
274
+ # Returns `true` if `self` contains the given RDF subject term.
275
+ #
276
+ # @param [RDF::Resource] value
277
+ # @return [Boolean]
278
+ def has_subject?(value)
279
+ enum_subject.include?(value)
280
+ end
281
+
282
+ ##
283
+ # Iterates the given block for each unique RDF subject term.
284
+ #
285
+ # If no block was given, returns an enumerator.
286
+ #
287
+ # The order in which values are yielded is undefined.
288
+ #
289
+ # @overload each_subject
290
+ # @yield [subject]
291
+ # each subject term
292
+ # @yieldparam [RDF::Resource] subject
293
+ # @yieldreturn [void] ignored
294
+ # @return [void]
295
+ #
296
+ # @overload each_subject
297
+ # @return [Enumerator]
298
+ #
299
+ # @return [void]
300
+ # @see #enum_subject
301
+ def each_subject(&block)
302
+ if block_given?
303
+ values = {}
304
+ each_statement do |statement|
305
+ value = statement.subject
306
+ unless value.nil? || values.include?(value.to_s)
307
+ values[value.to_s] = true
308
+ block.call(value)
309
+ end
310
+ end
311
+ end
312
+ enum_subject
313
+ end
314
+
315
+ ##
316
+ # Returns an enumerator for {#each_subject}.
317
+ #
318
+ # @return [Enumerator]
319
+ # @see #each_subject
320
+ def enum_subject
321
+ enum_for(:each_subject)
322
+ end
323
+ alias_method :enum_subjects, :enum_subject
324
+
325
+ ##
326
+ # Returns all unique RDF predicate terms.
327
+ #
328
+ # @param [Hash{Symbol => Boolean}] options
329
+ # @option options [Boolean] :unique (true)
330
+ # @return [Enumerator<RDF::URI>]
331
+ # @see #each_predicate
332
+ # @see #enum_predicate
333
+ def predicates(options = {})
334
+ if options[:unique] == false
335
+ enum_statement.map(&:predicate).to_enum # TODO: optimize
336
+ else
337
+ enum_predicate
338
+ end
339
+ end
340
+
341
+ ##
342
+ # Returns `true` if `self` contains the given RDF predicate term.
343
+ #
344
+ # @param [RDF::URI] value
345
+ # @return [Boolean]
346
+ def has_predicate?(value)
347
+ enum_predicate.include?(value)
348
+ end
349
+
350
+ ##
351
+ # Iterates the given block for each unique RDF predicate term.
352
+ #
353
+ # If no block was given, returns an enumerator.
354
+ #
355
+ # The order in which values are yielded is undefined.
356
+ #
357
+ # @overload each_predicate
358
+ # @yield [predicate]
359
+ # each predicate term
360
+ # @yieldparam [RDF::URI] predicate
361
+ # @yieldreturn [void] ignored
362
+ # @return [void]
363
+ #
364
+ # @overload each_predicate
365
+ # @return [Enumerator]
366
+ #
367
+ # @return [void]
368
+ # @see #enum_predicate
369
+ def each_predicate(&block)
370
+ if block_given?
371
+ values = {}
372
+ each_statement do |statement|
373
+ value = statement.predicate
374
+ unless value.nil? || values.include?(value.to_s)
375
+ values[value.to_s] = true
376
+ block.call(value)
377
+ end
378
+ end
379
+ end
380
+ enum_predicate
381
+ end
382
+
383
+ ##
384
+ # Returns an enumerator for {#each_predicate}.
385
+ #
386
+ # @return [Enumerator]
387
+ # @see #each_predicate
388
+ def enum_predicate
389
+ enum_for(:each_predicate)
390
+ end
391
+ alias_method :enum_predicates, :enum_predicate
392
+
393
+ ##
394
+ # Returns all unique RDF object terms.
395
+ #
396
+ # @param [Hash{Symbol => Boolean}] options
397
+ # @option options [Boolean] :unique (true)
398
+ # @return [Enumerator<RDF::Term>]
399
+ # @see #each_object
400
+ # @see #enum_object
401
+ def objects(options = {})
402
+ if options[:unique] == false
403
+ enum_statement.map(&:object).to_enum # TODO: optimize
404
+ else
405
+ enum_object
406
+ end
407
+ end
408
+
409
+ ##
410
+ # Returns `true` if `self` contains the given RDF object term.
411
+ #
412
+ # @param [RDF::Term] value
413
+ # @return [Boolean]
414
+ def has_object?(value)
415
+ enum_object.include?(value)
416
+ end
417
+
418
+ ##
419
+ # Iterates the given block for each unique RDF object term.
420
+ #
421
+ # If no block was given, returns an enumerator.
422
+ #
423
+ # The order in which values are yielded is undefined.
424
+ #
425
+ # @overload each_object
426
+ # @yield [object]
427
+ # each object term
428
+ # @yieldparam [RDF::Term] object
429
+ # @yieldreturn [void] ignored
430
+ # @return [void]
431
+ #
432
+ # @overload each_object
433
+ # @return [Enumerator]
434
+ #
435
+ # @return [void]
436
+ # @see #enum_object
437
+ def each_object(&block) # FIXME: deduplication
438
+ if block_given?
439
+ values = {}
440
+ each_statement do |statement|
441
+ value = statement.object
442
+ unless value.nil? || values.include?(value)
443
+ values[value] = true
444
+ block.call(value)
445
+ end
446
+ end
447
+ end
448
+ enum_object
449
+ end
450
+
451
+ ##
452
+ # Returns an enumerator for {#each_object}.
453
+ #
454
+ # @return [Enumerator]
455
+ # @see #each_object
456
+ def enum_object
457
+ enum_for(:each_object)
458
+ end
459
+ alias_method :enum_objects, :enum_object
460
+
461
+ ##
462
+ # Returns all unique RDF contexts.
463
+ #
464
+ # @param [Hash{Symbol => Boolean}] options
465
+ # @option options [Boolean] :unique (true)
466
+ # @return [Enumerator<RDF::Resource>]
467
+ # @see #each_context
468
+ # @see #enum_context
469
+ def contexts(options = {})
470
+ if options[:unique] == false
471
+ enum_statement.map(&:context).to_enum # TODO: optimize
472
+ else
473
+ enum_context
474
+ end
475
+ end
476
+
477
+ ##
478
+ # Returns `true` if `self` contains the given RDF context.
479
+ #
480
+ # @param [RDF::Resource] value
481
+ # @return [Boolean]
482
+ def has_context?(value)
483
+ enum_context.include?(value)
484
+ end
485
+
486
+ ##
487
+ # Iterates the given block for each unique RDF context.
488
+ #
489
+ # If no block was given, returns an enumerator.
490
+ #
491
+ # The order in which values are yielded is undefined.
492
+ #
493
+ # @overload each_context
494
+ # @yield [context]
495
+ # each context term
496
+ # @yieldparam [RDF::Resource] context
497
+ # @yieldreturn [void] ignored
498
+ # @return [void]
499
+ #
500
+ # @overload each_context
501
+ # @return [Enumerator]
502
+ #
503
+ # @return [void]
504
+ # @see #enum_context
505
+ def each_context(&block)
506
+ if block_given?
507
+ values = {}
508
+ each_statement do |statement|
509
+ value = statement.context
510
+ unless value.nil? || values.include?(value)
511
+ values[value] = true
512
+ block.call(value)
513
+ end
514
+ end
515
+ end
516
+ enum_context
517
+ end
518
+
519
+ ##
520
+ # Returns an enumerator for {#each_context}.
521
+ #
522
+ # @return [Enumerator]
523
+ # @see #each_context
524
+ def enum_context
525
+ enum_for(:each_context)
526
+ end
527
+ alias_method :enum_contexts, :enum_context
528
+
529
+ ##
530
+ # Iterates the given block for each RDF graph in `self`.
531
+ #
532
+ # If no block was given, returns an enumerator.
533
+ #
534
+ # The order in which graphs are yielded is undefined.
535
+ #
536
+ # @overload each_graph
537
+ # @yield [graph]
538
+ # each graph
539
+ # @yieldparam [RDF::Graph] graph
540
+ # @yieldreturn [void] ignored
541
+ # @return [void]
542
+ #
543
+ # @overload each_graph
544
+ # @return [Enumerator]
545
+ #
546
+ # @return [void]
547
+ # @see #enum_graph
548
+ # @since 0.1.9
549
+ def each_graph(&block)
550
+ if block_given?
551
+ block.call(RDF::Graph.new(nil, :data => self))
552
+ each_context do |context|
553
+ block.call(RDF::Graph.new(context, :data => self))
554
+ end
555
+ end
556
+ enum_graph
557
+ end
558
+
559
+ ##
560
+ # Returns an enumerator for {#each_graph}.
561
+ #
562
+ # @return [Enumerator]
563
+ # @see #each_graph
564
+ # @since 0.1.9
565
+ def enum_graph
566
+ enum_for(:each_graph)
567
+ end
568
+ alias_method :enum_graphs, :enum_graph
569
+
570
+ ##
571
+ # Returns all RDF statements in `self` as an array.
572
+ #
573
+ # Mixes in `RDF::Enumerable` into the returned object.
574
+ #
575
+ # @return [Array]
576
+ # @since 0.2.0
577
+ def to_a
578
+ super.extend(RDF::Enumerable)
579
+ end
580
+
581
+ ##
582
+ # Returns all RDF statements in `self` as a set.
583
+ #
584
+ # Mixes in `RDF::Enumerable` into the returned object.
585
+ #
586
+ # @return [Set]
587
+ # @since 0.2.0
588
+ def to_set
589
+ require 'set' unless defined?(::Set)
590
+ super.extend(RDF::Enumerable)
591
+ end
592
+
593
+ ##
594
+ # Returns all RDF object terms indexed by their subject and predicate
595
+ # terms.
596
+ #
597
+ # The return value is a `Hash` instance that has the structure:
598
+ # `{subject => {predicate => [*objects]}}`.
599
+ #
600
+ # @return [Hash]
601
+ def to_hash
602
+ result = {}
603
+ each_statement do |statement|
604
+ next if statement.invalid? # skip any incomplete statements
605
+
606
+ result[statement.subject] ||= {}
607
+ values = (result[statement.subject][statement.predicate] ||= [])
608
+ values << statement.object unless values.include?(statement.object)
609
+ end
610
+ result
611
+ end
612
+
613
+ ##
614
+ # Returns a serialized string representation of `self`.
615
+ #
616
+ # Before calling this method you may need to explicitly require a
617
+ # serialization plugin for the specified format.
618
+ #
619
+ # @example Serializing into N-Triples format
620
+ # require 'rdf/ntriples'
621
+ # ntriples = enumerable.dump(:ntriples)
622
+ #
623
+ # @param [Array<Object>] args
624
+ # if the last argument is a hash, it is passed as options to
625
+ # {RDF::Writer.dump}.
626
+ # @return [String]
627
+ # @see RDF::Writer.dump
628
+ # @raise [RDF::WriterError] if no writer found
629
+ # @since 0.2.0
630
+ def dump(*args)
631
+ options = args.last.is_a?(Hash) ? args.pop : {}
632
+ writer = RDF::Writer.for(*args)
633
+ raise RDF::WriterError, "No writer found using #{args.inspect}" unless writer
634
+ writer.dump(self, nil, options)
635
+ end
636
+ end # Enumerable
637
+ end # RDF
@@ -0,0 +1,26 @@
1
+ module RDF
2
+ ##
3
+ # A mixin that can be used to mark RDF repository implementations as
4
+ # indexable.
5
+ #
6
+ # @since 0.3.0
7
+ module Indexable
8
+ ##
9
+ # Returns `true` if `self` is indexed at present.
10
+ #
11
+ # @abstract
12
+ # @return [Boolean]
13
+ def indexed?
14
+ false
15
+ end
16
+
17
+ ##
18
+ # Indexes `self`.
19
+ #
20
+ # @abstract
21
+ # @return [void]
22
+ def index!
23
+ raise NotImplementedError, "#{self.class}#index!"
24
+ end
25
+ end # Indexable
26
+ end # RDF
@@ -0,0 +1,5 @@
1
+ module RDF
2
+ ##
3
+ # @see http://github.com/bendiken/rdfs
4
+ module Inferable; end
5
+ end