grel 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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