openlogic-rdf 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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,237 @@
1
+ module RDF; class Query
2
+ ##
3
+ # An RDF basic graph pattern (BGP) query solution sequence.
4
+ #
5
+ # @example Filtering solutions using a hash
6
+ # solutions.filter(:author => RDF::URI("http://ar.to/#self"))
7
+ # solutions.filter(:author => "Arto Bendiken")
8
+ # solutions.filter(:author => [RDF::URI("http://ar.to/#self"), "Arto Bendiken"])
9
+ # solutions.filter(:updated => RDF::Literal(Date.today))
10
+ #
11
+ # @example Filtering solutions using a block
12
+ # solutions.filter { |solution| solution.author.literal? }
13
+ # solutions.filter { |solution| solution.title =~ /^SPARQL/ }
14
+ # solutions.filter { |solution| solution.price < 30.5 }
15
+ # solutions.filter { |solution| solution.bound?(:date) }
16
+ # solutions.filter { |solution| solution.age.datatype == RDF::XSD.integer }
17
+ # solutions.filter { |solution| solution.name.language == :es }
18
+ #
19
+ # @example Reordering solutions based on a variable or proc
20
+ # solutions.order_by(:updated)
21
+ # solutions.order_by(:updated, :created)
22
+ # solutions.order_by(:updated, lambda {|a, b| b <=> a})
23
+ #
24
+ # @example Selecting/Projecting particular variables only
25
+ # solutions.select(:title)
26
+ # solutions.select(:title, :description)
27
+ # solutions.project(:title)
28
+ #
29
+ # @example Eliminating duplicate solutions
30
+ # solutions.distinct
31
+ #
32
+ # @example Limiting the number of solutions
33
+ # solutions.offset(20).limit(10)
34
+ #
35
+ # @example Counting the number of matching solutions
36
+ # solutions.count
37
+ # solutions.count { |solution| solution.price < 30.5 }
38
+ #
39
+ # @example Iterating over all found solutions
40
+ # solutions.each { |solution| puts solution.inspect }
41
+ #
42
+ # @since 0.3.0
43
+ class Solutions < Array
44
+ alias_method :each_solution, :each
45
+
46
+ ##
47
+ # Returns the number of matching query solutions.
48
+ #
49
+ # @overload count
50
+ # @return [Integer]
51
+ #
52
+ # @overload count { |solution| ... }
53
+ # @yield [solution]
54
+ # @yieldparam [RDF::Query::Solution] solution
55
+ # @yieldreturn [Boolean]
56
+ # @return [Integer]
57
+ #
58
+ # @return [Integer]
59
+ def count(&block)
60
+ super
61
+ end
62
+
63
+ ##
64
+ # Returns hash of bindings from each solution. Each bound variable will have
65
+ # an array of bound values representing those from each solution, where a given
66
+ # solution will have just a single value for each bound variable
67
+ # @return [Hash{Symbol => Array<RDF::Term>}]
68
+ def bindings
69
+ bindings = {}
70
+ each do |solution|
71
+ solution.each do |key, value|
72
+ bindings[key] ||= []
73
+ bindings[key] << value
74
+ end
75
+ end
76
+ bindings
77
+ end
78
+
79
+ ##
80
+ # Filters this solution sequence by the given `criteria`.
81
+ #
82
+ # @param [Hash{Symbol => Object}] criteria
83
+ # @yield [solution]
84
+ # @yieldparam [RDF::Query::Solution] solution
85
+ # @yieldreturn [Boolean]
86
+ # @return [void] `self`
87
+ def filter(criteria = {}, &block)
88
+ if block_given?
89
+ self.reject! do |solution|
90
+ !block.call(solution.is_a?(Solution) ? solution : Solution.new(solution))
91
+ end
92
+ else
93
+ self.reject! do |solution|
94
+ solution = solution.is_a?(Solution) ? solution : Solution.new(solution)
95
+ results = criteria.map do |name, value|
96
+ solution[name] == value
97
+ end
98
+ !results.all?
99
+ end
100
+ end
101
+ self
102
+ end
103
+ alias_method :filter!, :filter
104
+
105
+ ##
106
+ # Reorders this solution sequence by the given `variables`.
107
+ #
108
+ # Variables may be symbols or {Query::Variable} instances.
109
+ # A variable may also be a Procedure/Lambda, compatible with {::Enumerable#sort}.
110
+ # This takes two arguments (solutions) and returns -1, 0, or 1 equivalently to <=>.
111
+ #
112
+ # If called with a block, variables are ignored, and the block is invoked with
113
+ # pairs of solutions. The block is expected to return -1, 0, or 1 equivalently to <=>.
114
+ #
115
+ # @param [Array<Proc, Query::Variable, Symbol, #to_sym>] variables
116
+ # @yield [solution]
117
+ # @yieldparam [RDF::Query::Solution] q
118
+ # @yieldparam [RDF::Query::Solution] b
119
+ # @yieldreturn [Integer] -1, 0, or 1 depending on value of comparator
120
+ # @return [void] `self`
121
+ def order(*variables, &block)
122
+ if variables.empty? && !block_given?
123
+ raise ArgumentError, "wrong number of arguments (0 for 1)"
124
+ else
125
+ self.sort! do |a, b|
126
+ if block_given?
127
+ block.call((a.is_a?(Solution) ? a : Solution.new(a)), (b.is_a?(Solution) ? b : Solution.new(b)))
128
+ else
129
+ # Try each variable until a difference is found.
130
+ variables.inject(nil) do |memo, v|
131
+ memo || begin
132
+ comp = v.is_a?(Proc) ? v.call(a, b) : (v = v.to_sym; a[v] <=> b[v])
133
+ comp == 0 ? false : comp
134
+ end
135
+ end || 0
136
+ end
137
+ end
138
+ end
139
+ self
140
+ end
141
+ alias_method :order_by, :order
142
+
143
+ ##
144
+ # Restricts this solution sequence to the given `variables` only.
145
+ #
146
+ # @param [Array<Symbol, #to_sym>] variables
147
+ # @return [void] `self`
148
+ def project(*variables)
149
+ if variables.empty?
150
+ raise ArgumentError, "wrong number of arguments (0 for 1)"
151
+ else
152
+ variables.map!(&:to_sym)
153
+ self.each do |solution|
154
+ solution.bindings.delete_if { |k, v| !variables.include?(k.to_sym) }
155
+ end
156
+ end
157
+ self
158
+ end
159
+ alias_method :select, :project
160
+
161
+ ##
162
+ # Ensures that the solutions in this solution sequence are unique.
163
+ #
164
+ # @return [void] `self`
165
+ def distinct
166
+ self.uniq!
167
+ self
168
+ end
169
+ alias_method :distinct!, :distinct
170
+ alias_method :reduced, :distinct
171
+ alias_method :reduced!, :distinct
172
+
173
+ ##
174
+ # Limits this solution sequence to bindings starting from the `start`
175
+ # offset in the overall solution sequence.
176
+ #
177
+ # @param [Integer, #to_i] start
178
+ # zero or a positive or negative integer
179
+ # @return [void] `self`
180
+ def offset(start)
181
+ case start = start.to_i
182
+ when 0 then nil
183
+ else self.slice!(0...start)
184
+ end
185
+ self
186
+ end
187
+ alias_method :offset!, :offset
188
+
189
+ ##
190
+ # Limits the number of solutions in this solution sequence to a maximum
191
+ # of `length`.
192
+ #
193
+ # @param [Integer, #to_i] length
194
+ # zero or a positive integer
195
+ # @return [void] `self`
196
+ # @raise [ArgumentError] if `length` is negative
197
+ def limit(length)
198
+ length = length.to_i
199
+ raise ArgumentError, "expected zero or a positive integer, got #{length}" if length < 0
200
+ case length
201
+ when 0 then self.clear
202
+ else self.slice!(length..-1) if length < self.size
203
+ end
204
+ self
205
+ end
206
+ alias_method :limit!, :limit
207
+
208
+ ##
209
+ # Returns an array of the distinct variable names used in this solution
210
+ # sequence.
211
+ #
212
+ # @return [Array<Symbol>]
213
+ def variable_names
214
+ variables = self.inject({}) do |result, solution|
215
+ solution.each_name do |name|
216
+ result[name] ||= true
217
+ end
218
+ result
219
+ end
220
+ variables.keys
221
+ end
222
+
223
+ ##
224
+ # Returns `true` if this solution sequence contains bindings for any of
225
+ # the given `variables`.
226
+ #
227
+ # @param [Array<Symbol, #to_sym>] variables
228
+ # an array of variables to check
229
+ # @return [Boolean] `true` or `false`
230
+ # @see RDF::Query::Solution#has_variables?
231
+ # @see RDF::Query#execute
232
+ def have_variables?(variables)
233
+ self.any? { |solution| solution.has_variables?(variables) }
234
+ end
235
+ alias_method :has_variables?, :have_variables?
236
+ end # Solutions
237
+ end; end # RDF::Query
@@ -0,0 +1,221 @@
1
+ class RDF::Query
2
+ ##
3
+ # An RDF query variable.
4
+ #
5
+ # @example Creating a named unbound variable
6
+ # var = RDF::Query::Variable.new(:x)
7
+ # var.unbound? #=> true
8
+ # var.value #=> nil
9
+ #
10
+ # @example Creating an anonymous unbound variable
11
+ # var = RDF::Query::Variable.new
12
+ # var.name #=> :g2166151240
13
+ #
14
+ # @example Unbound variables match any value
15
+ # var === 42 #=> true
16
+ #
17
+ # @example Creating a bound variable
18
+ # var = RDF::Query::Variable.new(:y, 123)
19
+ # var.bound? #=> true
20
+ # var.value #=> 123
21
+ #
22
+ # @example Bound variables match only their actual value
23
+ # var === 42 #=> false
24
+ # var === 123 #=> true
25
+ #
26
+ # @example Getting the variable name
27
+ # var.named? #=> true
28
+ # var.name #=> :y
29
+ # var.to_sym #=> :y
30
+ #
31
+ # @example Rebinding a variable returns the previous value
32
+ # var.bind!(456) #=> 123
33
+ # var.value #=> 456
34
+ #
35
+ # @example Unbinding a previously bound variable
36
+ # var.unbind!
37
+ # var.unbound? #=> true
38
+ #
39
+ # @example Getting the string representation of a variable
40
+ # var = RDF::Query::Variable.new(:x)
41
+ # var.to_s #=> "?x"
42
+ # var = RDF::Query::Variable.new(:y, 123)
43
+ # var.to_s #=> "?y=123"
44
+ #
45
+ class Variable
46
+ include RDF::Term
47
+
48
+ ##
49
+ # The variable's name.
50
+ #
51
+ # @return [Symbol]
52
+ attr_accessor :name
53
+ alias_method :to_sym, :name
54
+
55
+ ##
56
+ # The variable's value.
57
+ #
58
+ # @return [RDF::Term]
59
+ attr_accessor :value
60
+
61
+ ##
62
+ # @param [Symbol, #to_sym] name
63
+ # the variable name
64
+ # @param [RDF::Term] value
65
+ # an optional variable value
66
+ def initialize(name = nil, value = nil)
67
+ @name = (name || "g#{__id__.to_i.abs}").to_sym
68
+ @value = value
69
+ end
70
+
71
+ ##
72
+ # Returns `true`.
73
+ #
74
+ # @return [Boolean]
75
+ # @see RDF::Term#variable?
76
+ # @since 0.1.7
77
+ def variable?
78
+ true
79
+ end
80
+
81
+ ##
82
+ # Returns `true` if this variable has a name.
83
+ #
84
+ # @return [Boolean]
85
+ def named?
86
+ true
87
+ end
88
+
89
+ ##
90
+ # Returns `true` if this variable is bound.
91
+ #
92
+ # @return [Boolean]
93
+ def bound?
94
+ !unbound?
95
+ end
96
+
97
+ ##
98
+ # Returns `true` if this variable is unbound.
99
+ #
100
+ # @return [Boolean]
101
+ def unbound?
102
+ value.nil?
103
+ end
104
+
105
+ ##
106
+ # Returns `true` if this variable is distinguished.
107
+ #
108
+ # @return [Boolean]
109
+ def distinguished?
110
+ @distinguished.nil? || @distinguished
111
+ end
112
+
113
+ ##
114
+ # Sets if variable is distinguished or non-distinguished.
115
+ # By default, variables are distinguished
116
+ #
117
+ # @return [Boolean]
118
+ def distinguished=(value)
119
+ @distinguished = value
120
+ end
121
+
122
+ ##
123
+ # Rebinds this variable to the given `value`.
124
+ #
125
+ # @param [RDF::Term] value
126
+ # @return [RDF::Term] the previous value, if any.
127
+ def bind(value)
128
+ old_value = self.value
129
+ self.value = value
130
+ old_value
131
+ end
132
+ alias_method :bind!, :bind
133
+
134
+ ##
135
+ # Unbinds this variable, discarding any currently bound value.
136
+ #
137
+ # @return [RDF::Term] the previous value, if any.
138
+ def unbind
139
+ old_value = self.value
140
+ self.value = nil
141
+ old_value
142
+ end
143
+ alias_method :unbind!, :unbind
144
+
145
+ ##
146
+ # Returns this variable as `Hash`.
147
+ #
148
+ # @return [Hash{Symbol => RDF::Query::Variable}]
149
+ def variables
150
+ {name => self}
151
+ end
152
+ alias_method :to_hash, :variables
153
+
154
+ ##
155
+ # Returns this variable's bindings (if any) as a `Hash`.
156
+ #
157
+ # @return [Hash{Symbol => RDF::Term}]
158
+ def bindings
159
+ unbound? ? {} : {name => value}
160
+ end
161
+
162
+ ##
163
+ # Returns a hash code for this variable.
164
+ #
165
+ # @return [Fixnum]
166
+ # @since 0.3.0
167
+ def hash
168
+ @name.hash
169
+ end
170
+
171
+ ##
172
+ # Returns `true` if this variable is equivalent to a given `other`
173
+ # variable. Or, to another Term if bound, or to any other Term
174
+ #
175
+ # @param [Object] other
176
+ # @return [Boolean] `true` or `false`
177
+ # @since 0.3.0
178
+ def eql?(other)
179
+ if unbound?
180
+ other.is_a?(RDF::Term) # match any Term when unbound
181
+ elsif other.is_a?(RDF::Query::Variable)
182
+ @name.eql?(other.name)
183
+ else
184
+ value.eql?(other)
185
+ end
186
+ end
187
+ alias_method :==, :eql?
188
+
189
+ ##
190
+ # Compares this variable with the given value.
191
+ #
192
+ # @param [RDF::Term] other
193
+ # @return [Boolean]
194
+ def ===(other)
195
+ if unbound?
196
+ other.is_a?(RDF::Term) # match any Term when unbound
197
+ else
198
+ value === other
199
+ end
200
+ end
201
+
202
+ ##
203
+ # Returns a string representation of this variable.
204
+ #
205
+ # Distinguished variables are indicated with a single `?`.
206
+ #
207
+ # Non-distinguished variables are indicated with a double `??`
208
+ #
209
+ # @example
210
+ # v = Variable.new("a")
211
+ # v.to_s => '?a'
212
+ # v.distinguished = false
213
+ # v.to_s => '??a'
214
+ #
215
+ # @return [String]
216
+ def to_s
217
+ prefix = distinguished? ? '?' : "??"
218
+ unbound? ? "#{prefix}#{name}" : "#{prefix}#{name}=#{value}"
219
+ end
220
+ end # Variable
221
+ end # RDF::Query