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.
- data/lib/grel/base.rb +128 -8
- data/lib/grel/ql.rb +10 -0
- data/lib/grel.rb +25 -0
- 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
|
-
|
|
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.
|
|
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-
|
|
12
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: stardog-rb
|