grel 0.1.0 → 0.1.1

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 (4) hide show
  1. data/lib/grel/base.rb +128 -8
  2. data/lib/grel/ql.rb +10 -0
  3. data/lib/grel.rb +25 -0
  4. metadata +2 -2
data/lib/grel/base.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module GRel
2
2
 
3
+ # Base class for the graph of ruby objects stored in Stardog
3
4
  class Base
4
5
 
5
6
  include Stardog
@@ -7,6 +8,15 @@ module GRel
7
8
  attr_accessor :connection, :last_query_context
8
9
  attr_reader :db_name, :schema_graph
9
10
 
11
+ # Builds the graph with the provided connection string and options.
12
+ # - endpoint : connection string. localhost:5822 by default.
13
+ # - options: hash of options:
14
+ # Valid options are:
15
+ # - user : user name for authentication
16
+ # - password : password for authentication
17
+ # - validate : should validate integrity constraints
18
+ # - db : name of the db to use
19
+ # Returns the newly built graph object.
10
20
  def initialize(endpoint, options)
11
21
  @options = options
12
22
  @endpoint = endpoint
@@ -17,6 +27,12 @@ module GRel
17
27
  self
18
28
  end
19
29
 
30
+ # Turns on reasoning in queries.
31
+ # The type of reasoning must be provided as an argument.
32
+ # By default 'QL' is provided.
33
+ # Reasoning will remain turned on for all operations in the graph until it is
34
+ # explicitely turned off with the +without_reasoning+ message.
35
+ # It returns the current graph object.
20
36
  def with_reasoning(reasoning="QL")
21
37
  @reasoning = true
22
38
  @connection = stardog(@endpoint,@options.merge(:reasoning => reasoning))
@@ -26,12 +42,21 @@ module GRel
26
42
  self
27
43
  end
28
44
 
45
+ # Turns off reasoning in queries.
46
+ # Reasoning will remain turned off until enabled again with the +with_reasoning+ message.
47
+ # It returns the current graph object.
29
48
  def without_reasoning
30
49
  @reasoning = false
31
50
  @connection = stardog(@endpoint,@options)
32
51
  self
33
52
  end
34
53
 
54
+ # Sets the current Stardog database this graph is connected to.
55
+ # It accepts the name of the database as an argument.
56
+ # If an optional block is provided, operations in the block
57
+ # will be executed in the provided database and the old database
58
+ # will be restored afterwards.
59
+ # It returns the current graph object.
35
60
  def with_db(db_name)
36
61
  ensure_db(db_name) do
37
62
  old_db_name = @db_name
@@ -46,6 +71,12 @@ module GRel
46
71
  end
47
72
 
48
73
 
74
+ # Stores a graph of ruby objects encoded as a nested collection of hashes in a database.
75
+ # Arguments:
76
+ # - data : objects to be stored.
77
+ # - db_name : optional database where this objects will be stored.
78
+ # It returns the current graph object.
79
+ # if a validation fails, a ValidationError will be raised.
49
80
  def store(data, db_name=nil)
50
81
  if(db_name)
51
82
  with_db(db_name) do
@@ -64,6 +95,11 @@ module GRel
64
95
  end
65
96
 
66
97
 
98
+ # Builds a query for the graph of objects.
99
+ # The query is expressed as a pattern of nested hashes that will be matched agains the data
100
+ # stored in the graph.
101
+ # Wildcard values and filters can also be added to the query.
102
+ # It returns the current graph object.
67
103
  def where(query)
68
104
  @last_query_context = QL::QueryContext.new(self)
69
105
  @last_query_context.register_query(query)
@@ -71,6 +107,10 @@ module GRel
71
107
  self
72
108
  end
73
109
 
110
+ # Adds another pattern to the current query being defined.
111
+ # It accepts a query pattern hash identical to the one accepted by the
112
+ # +where+ method.
113
+ # It returns the current graph object.
74
114
  def union(query)
75
115
  union_context = QL::QueryContext.new(self)
76
116
  union_context.register_query(query)
@@ -80,25 +120,44 @@ module GRel
80
120
  self
81
121
  end
82
122
 
123
+ # Limits how many triples will be returned from the server.
124
+ # The limit refers to triples, not nodes in the graph.
125
+ # It returns the current graph object.
83
126
  def limit(limit)
84
127
  @last_query_context.limit = limit
85
128
  self
86
129
  end
87
130
 
131
+ # Skip the first offset number of triples in the response returned from
132
+ # the server.
133
+ # The offset refers to triples, not nodes in the graph.
134
+ # It returns the current graph object.
88
135
  def offset(offset)
89
136
  @last_query_context.offset = offset
90
137
  self
91
138
  end
92
-
93
- def order(order)
94
- @last_query_context.order = order
95
- self
96
- end
97
-
139
+
140
+ # def order(order)
141
+ # @last_query_context.order = order
142
+ # self
143
+ # end
144
+
145
+ # Exceutes the current query returning the raw response from the server
146
+ # It returns the a list of JSON-LD linked objects.
98
147
  def run
99
148
  @last_query_context.run
100
149
  end
101
150
 
151
+ # Defines schema meta data that will be used in the processing of queries
152
+ # if reasoning is activated.
153
+ # It accepts a list of definitions as an argument.
154
+ # Valid definitions are:
155
+ # - @subclass definitions
156
+ # - @subproperty definitions
157
+ # - @domain definitions
158
+ # - @range defintions
159
+ # - @cardinality definitions
160
+ # It returns the current graph object.
102
161
  def define(*args)
103
162
  unless(args.length == 3 && !args.first.is_a?(Array))
104
163
  args = args.inject([]) {|a,i| a += i; a }
@@ -115,13 +174,17 @@ module GRel
115
174
  self
116
175
  end
117
176
 
177
+ # Drop definition statements from the schema meta data.
178
+ # It accepts statements equivalent to the ones provided to the +define+ method.
179
+ # It returns the current graph object.
118
180
  def retract_definition(*args)
119
181
  unless(args.length == 3 && !args.first.is_a?(Array))
120
182
  args = args.inject([]) {|a,i| a += i }
121
183
  end
122
- additional_triples = []
123
184
 
124
- triples = QL.to_turtle(args + additional_triples, true)
185
+ args = parse_schema_axioms(args)
186
+
187
+ triples = QL.to_turtle(args, true)
125
188
  GRel::Debugger.debug "REMOVING FROM SCHEMA #{@schema_graph}"
126
189
  GRel::Debugger.debug triples
127
190
  GRel::Debugger.debug "IN"
@@ -130,6 +193,17 @@ module GRel
130
193
  self
131
194
  end
132
195
 
196
+ # Adds a validation statement to the graph.
197
+ # Validations will be checked in every +store+ operation if validations are activated.
198
+ # A ValidationError exception will be raised if a validation fails.
199
+ # It accepts a list of definitions as an argument.
200
+ # Valid definitions are:
201
+ # - @subclass definitions
202
+ # - @subproperty definitions
203
+ # - @domain definitions
204
+ # - @range defintions
205
+ # - @cardinality definitions
206
+ # It returns the current graph object.
133
207
  def validate(*args)
134
208
  unless(args.detect{|e| !e.is_a?(Array)})
135
209
  args = args.inject([]) {|a,i| a += i; a }
@@ -152,6 +226,9 @@ module GRel
152
226
  self
153
227
  end
154
228
 
229
+ # Removes a validation from the graph.
230
+ # It accepts a list of validation statements equivalent to the ones accepted by the +validate+ method.
231
+ # It returns the current graph object.
155
232
  def retract_validation(*args)
156
233
  unless(args.length == 3 && !args.first.is_a?(Array))
157
234
  args = args.inject([]) {|a,i| a += i }
@@ -165,6 +242,11 @@ module GRel
165
242
  self
166
243
  end
167
244
 
245
+ # Removes data from the graph of objects.
246
+ # If no arguments are provided, the nodes returned from the last executed query will
247
+ # be removed from the graph.
248
+ # If a graph of objects are provided, the equivalent statements will be removed instead.
249
+ # It returns the current graph object.
168
250
  def remove(data = nil, options = {})
169
251
  if data
170
252
  GRel::Debugger.debug "REMMOVING"
@@ -184,6 +266,10 @@ module GRel
184
266
  self
185
267
  end
186
268
 
269
+ # Executes the current defined query and returns a list of matching noes from the graph.
270
+ # Nodes will be correctly linked in the returned list.
271
+ # if the option +:unlinked+ is provided with true value, only the top level nodes that has not incoming links
272
+ # will be returned.
187
273
  def all(options = {})
188
274
  unlinked = options[:unlinked] || false
189
275
 
@@ -219,6 +305,8 @@ module GRel
219
305
  #end
220
306
  end
221
307
 
308
+ # Executes the current defined query returning a list of hashes where pairs key,value
309
+ # are bound to the tuple variables in the query hash and retrived values for those variables.
222
310
  def tuples
223
311
  results = run_tuples(@last_query_context.to_sparql_select)
224
312
  results["results"]["bindings"].map do |h|
@@ -230,10 +318,13 @@ module GRel
230
318
  end
231
319
  end
232
320
 
321
+ # Returns only the first node from the list of retrieved nodes in an all query.
233
322
  def first(options = {})
234
323
  all(options).first
235
324
  end
236
325
 
326
+ # Executes a raw SPARQL DESCRIBE query for the current defined query.
327
+ # It returns the results of the query without any other processing.
237
328
  def query(query, options = {})
238
329
  GRel::Debugger.debug "QUERYING DESCRIBE..."
239
330
  GRel::Debugger.debug query
@@ -247,6 +338,8 @@ module GRel
247
338
  @connection.query(@db_name,query, args).body
248
339
  end
249
340
 
341
+ # Executes a raw SPARQL SELECT query for the current defined query.
342
+ # It returns the results of the query without any other processing.
250
343
  def run_tuples(query, options = {})
251
344
  GRel::Debugger.debug "QUERYING SELECT..."
252
345
  GRel::Debugger.debug query
@@ -260,6 +353,9 @@ module GRel
260
353
  @connection.query(@db_name,query, args).body
261
354
  end
262
355
 
356
+ # It turns on validations for any insertion in the graph.
357
+ # Validations will remain turned on until they are disabled using the +without_validations+ message.
358
+ # It returns the current graph.
263
359
  def with_validations(state = true)
264
360
  @validations = state
265
361
  @connection.offline_db(@db_name)
@@ -269,10 +365,34 @@ module GRel
269
365
  self
270
366
  end
271
367
 
368
+ # It disables validations for any insertion in the graph.
369
+ # Validations will remain turned off until they are enabled again using the +with_validations+ message.
370
+ # It returns the current graph.
272
371
  def without_validations
273
372
  with_validations(false)
274
373
  end
275
374
 
375
+ # Removes connection to a node in the graph.
376
+ # It accepts a list of node IDs that will be unlinked.
377
+ def unlink(ids)
378
+ ids = [ids] if(ids.is_a?(String))
379
+ query = QL.unlink_sparql_query(ids)
380
+ results = @connection.query(@db_name, query,{}).body
381
+ triples = results["results"]["bindings"].map do |h|
382
+ "<#{h['S']['value']}> <#{h['P']['value']}> <#{h['O']['value']}>"
383
+ end
384
+
385
+ if(triples.length > 0)
386
+ triples = "#{triples.join('.')} ."
387
+ GRel::Debugger.debug "REMMOVING"
388
+ GRel::Debugger.debug triples
389
+ GRel::Debugger.debug "IN"
390
+ GRel::Debugger.debug @db_name
391
+ @connection.remove(@db_name, triples, nil, "text/turtle")
392
+ end
393
+ self
394
+ end
395
+
276
396
  private
277
397
 
278
398
  def ensure_db(db_name)
data/lib/grel/ql.rb CHANGED
@@ -1,5 +1,15 @@
1
1
  module GRel
2
2
  module QL
3
+
4
+ def self.unlink_sparql_query(ids)
5
+ conditions = ids.map do |id|
6
+ id = "@id(#{id})" if id && id.is_a?(String) && id.index("@id(").nil?
7
+ id = QL.to_query(id)
8
+ "(?S = #{id} && isIRI(?O) && ?P != <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>) || ?O = #{id}"
9
+ end
10
+ "SELECT ?S ?P ?O WHERE { ?S ?P ?O . FILTER (#{conditions.join(' || ')}) } "
11
+ end
12
+
3
13
  def self.to_id(obj)
4
14
  if(obj =~ ID_REGEX)
5
15
  "<http://grel.org/ids/id/#{URI.encode(ID_REGEX.match(obj)[1])}>"
data/lib/grel.rb CHANGED
@@ -4,6 +4,8 @@ require 'uri'
4
4
  require 'securerandom'
5
5
 
6
6
  class Array
7
+ # When using an array of arrays to hold list of triples,
8
+ # returns the first triple subject.
7
9
  def triples_id
8
10
  self.first.first
9
11
  end
@@ -11,6 +13,8 @@ end
11
13
 
12
14
  module GRel
13
15
 
16
+ # Exception raised to signal a validation error due to a
17
+ # Stardog ICV.
14
18
  class ValidationError < Stardog::ICVException
15
19
  attr_accessor :icv_exception
16
20
  def initialize(msg, exception)
@@ -21,19 +25,25 @@ module GRel
21
25
 
22
26
  DEBUG = ENV["GREL_DEBUG"] || false
23
27
 
28
+ # Wrapper for the debugging logger method.
24
29
  class Debugger
25
30
  def self.debug(msg)
26
31
  puts msg if DEBUG
27
32
  end
28
33
  end
29
34
 
35
+ # Common namespace for all URIs generated by GRel.
30
36
  NAMESPACE = "http://grel.org/vocabulary#"
37
+ # Used to match valid ID strings
31
38
  ID_REGEX = /^\@id\((\w+)\)$/
39
+ # A URI denoting a ruby nil value
32
40
  NIL = "\"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil\""
33
41
  BNODE = "BNODE"
34
42
 
43
+ # XML Scheam NonNegativeInteger type
35
44
  class NonNegativeInteger
36
45
 
46
+ # Just wraps a numeric type
37
47
  def initialize(number)
38
48
  @number = number
39
49
  end
@@ -49,25 +59,40 @@ module GRel
49
59
 
50
60
  end
51
61
 
62
+ # RDF Blank nodes
52
63
  class BlankId
53
64
 
65
+ # The ID of the blank node.
54
66
  attr_reader :blank_id
55
67
 
68
+ # Creates a new BlankId object with an unique ID for
69
+ # this execution.
56
70
  def initialize
57
71
  @blank_id = BlankId.next_id
58
72
  end
59
73
 
74
+ # Unique IDs generator.
60
75
  def self.next_id
61
76
  next_id = (@counter ||= 0)
62
77
  @counter += 1
63
78
  next_id
64
79
  end
65
80
 
81
+ # Turtle represenation of the blank node.
66
82
  def to_s
67
83
  "_:#{@blank_id}"
68
84
  end
69
85
  end
70
86
 
87
+ # Creates a new graph object connected to the provided Stardog server.
88
+ # Arguments:
89
+ # - name : connection string. localhost:5822 by default.
90
+ # - options: hash of options:
91
+ # + user : user name for authentication
92
+ # + password : password for authentication
93
+ # + validate : should validate integrity constraints
94
+ # + db : name of the db to use
95
+ # Returns the newly built graph object.
71
96
  def graph(name='http://localhost:5822/',options = {})
72
97
  options[:user] ||= "admin"
73
98
  options[:password] ||= "admin"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-22 00:00:00.000000000 Z
12
+ date: 2013-03-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: stardog-rb