solis 0.71.0 → 0.72.0
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.
- checksums.yaml +4 -4
- data/lib/solis/model.rb +71 -23
- data/lib/solis/query/filter.rb +7 -2
- data/lib/solis/query.rb +2 -2
- data/lib/solis/shape/reader/sheet.rb +40 -40
- data/lib/solis/version.rb +1 -1
- data/solis.gemspec +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa7c729b1acbe8c1881ebf3cc00ac228830bf04d269447f55b2f029c7eef703c
|
4
|
+
data.tar.gz: 81ceb99f9f6284b8c4163bfe4d263f6703edbe1733eb42fcc6c31530be2c8d91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a5fe949952a2931c1189644690446ddc0b63ca719eb2f4b15f5cab83779d81b50872c3b57d4b677278cc4c6ca1e54ff8f14ff4b8c09ce842e8e5a3226835177
|
7
|
+
data.tar.gz: 03af55e0505d6e987522e8d799450be43a83b9968c60f7741b7c5bb2d75f0874d7d127b955f31ad028a35b2993b2ecdefb91653edf5e9941c4e7dfc796658696
|
data/lib/solis/model.rb
CHANGED
@@ -108,30 +108,49 @@ module Solis
|
|
108
108
|
|
109
109
|
def destroy
|
110
110
|
raise "I need a SPARQL endpoint" if self.class.sparql_endpoint.nil?
|
111
|
-
before_delete_proc&.call(self)
|
112
|
-
|
113
111
|
sparql = SPARQL::Client.new(self.class.sparql_endpoint)
|
114
|
-
graph = as_graph(klass = self, resolve_all = false)
|
115
|
-
Solis::LOGGER.info graph.dump(:ttl) if ConfigFile[:debug]
|
116
112
|
|
117
|
-
|
113
|
+
raise Solis::Error::QueryError, "#{self.id} is still referenced, refusing to delete" if is_referenced?(sparql)
|
114
|
+
#sparql.query('delete{}')
|
115
|
+
before_delete_proc&.call(self)
|
116
|
+
# graph = as_graph(self, false)
|
117
|
+
# Solis::LOGGER.info graph.dump(:ttl) if ConfigFile[:debug]
|
118
|
+
|
119
|
+
query = %(
|
120
|
+
with <#{self.class.graph_name}>
|
121
|
+
delete {?s ?p ?o}
|
122
|
+
where {
|
123
|
+
values ?s {<#{self.graph_id}>}
|
124
|
+
?s ?p ?o }
|
125
|
+
)
|
126
|
+
result = sparql.query(query)
|
127
|
+
|
128
|
+
# result = sparql.delete_data(graph, graph: graph.name)
|
118
129
|
after_delete_proc&.call(result)
|
119
130
|
result
|
120
131
|
end
|
121
132
|
|
122
133
|
def save(validate_dependencies = true)
|
123
134
|
raise "I need a SPARQL endpoint" if self.class.sparql_endpoint.nil?
|
135
|
+
sparql = SPARQL::Client.new(self.class.sparql_endpoint)
|
124
136
|
|
125
137
|
before_create_proc&.call(self)
|
126
|
-
sparql = SPARQL::Client.new(self.class.sparql_endpoint)
|
127
|
-
graph = as_graph(self, validate_dependencies)
|
128
138
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
139
|
+
if exists?(sparql)
|
140
|
+
data = Model.properties_to_hash(self)
|
141
|
+
|
142
|
+
result = update(data)
|
143
|
+
else
|
144
|
+
graph = as_graph(self, validate_dependencies)
|
145
|
+
|
146
|
+
# File.open('/Users/mehmetc/Dropbox/AllSources/LP/graphiti-api/save.ttl', 'wb') do |file|
|
147
|
+
# file.puts graph.dump(:ttl)
|
148
|
+
# end
|
149
|
+
Solis::LOGGER.info SPARQL::Client::Update::InsertData.new(graph, graph: graph.name).to_s if ConfigFile[:debug]
|
150
|
+
|
151
|
+
result = sparql.insert_data(graph, graph: graph.name)
|
152
|
+
end
|
133
153
|
|
134
|
-
result = sparql.insert_data(graph, graph: graph.name)
|
135
154
|
after_create_proc&.call(result)
|
136
155
|
result
|
137
156
|
rescue StandardError => e
|
@@ -144,7 +163,7 @@ module Solis
|
|
144
163
|
raise Solis::Error::GeneralError, "I need a SPARQL endpoint" if self.class.sparql_endpoint.nil?
|
145
164
|
|
146
165
|
attributes = data.include?('attributes') ? data['attributes'] : data
|
147
|
-
raise "id is mandatory
|
166
|
+
raise "id is mandatory when updating" unless attributes.keys.include?('id')
|
148
167
|
|
149
168
|
id = attributes.delete('id')
|
150
169
|
|
@@ -155,14 +174,12 @@ module Solis
|
|
155
174
|
updated_klass = original_klass.deep_dup
|
156
175
|
|
157
176
|
attributes.each_pair do |key, value|
|
158
|
-
updated_klass.
|
177
|
+
updated_klass.instance_variable_set("@#{key}", value)
|
159
178
|
end
|
160
179
|
|
161
180
|
before_update_proc&.call(original_klass, updated_klass)
|
162
181
|
|
163
182
|
delete_graph = as_graph(original_klass, false)
|
164
|
-
# where_graph = RDF::Graph.new
|
165
|
-
# where_graph.name = RDF::URI(self.class.graph_name)
|
166
183
|
|
167
184
|
where_graph = RDF::Graph.new(graph_name: RDF::URI("#{self.class.graph_name}#{self.name.tableize}/#{id}"), data: RDF::Repository.new)
|
168
185
|
|
@@ -176,16 +193,16 @@ module Solis
|
|
176
193
|
|
177
194
|
insert_graph = as_graph(updated_klass, true)
|
178
195
|
|
179
|
-
|
180
|
-
|
181
|
-
|
196
|
+
puts delete_graph.dump(:ttl) #if ConfigFile[:debug]
|
197
|
+
puts insert_graph.dump(:ttl) #if ConfigFile[:debug]
|
198
|
+
puts where_graph.dump(:ttl) #if ConfigFile[:debug]
|
182
199
|
|
183
200
|
#if ConfigFile[:debug]
|
184
201
|
delete_insert_query = SPARQL::Client::Update::DeleteInsert.new(delete_graph, insert_graph, where_graph, graph: insert_graph.name).to_s
|
185
202
|
delete_insert_query.gsub!('_:p', '?p')
|
186
|
-
|
203
|
+
puts delete_insert_query
|
187
204
|
data = sparql.query(delete_insert_query)
|
188
|
-
pp data
|
205
|
+
#pp data
|
189
206
|
#end
|
190
207
|
|
191
208
|
# sparql.delete_insert(delete_graph, insert_graph, where_graph, graph: insert_graph.name)
|
@@ -207,10 +224,23 @@ module Solis
|
|
207
224
|
raise e
|
208
225
|
end
|
209
226
|
|
227
|
+
def graph_id
|
228
|
+
"#{self.class.graph_name}#{self.name.tableize}/#{self.id}"
|
229
|
+
end
|
230
|
+
|
231
|
+
def is_referenced?(sparql)
|
232
|
+
sparql.query("ASK WHERE { ?s ?p <#{self.graph_id}>. filter (!contains(str(?p), '_audit'))}")
|
233
|
+
end
|
234
|
+
|
235
|
+
def exists?(sparql)
|
236
|
+
sparql.query("ASK WHERE { <#{self.graph_id}> ?p ?o }")
|
237
|
+
end
|
238
|
+
|
210
239
|
def self.make_id_for(model)
|
211
240
|
id = model.instance_variable_get("@id")
|
212
241
|
if id.nil? || (id.is_a?(String) && id&.empty?)
|
213
|
-
|
242
|
+
id = SecureRandom.uuid
|
243
|
+
model.instance_variable_set("@id", id)
|
214
244
|
end
|
215
245
|
model
|
216
246
|
end
|
@@ -410,7 +440,7 @@ module Solis
|
|
410
440
|
data = [data] unless data.is_a?(Array)
|
411
441
|
|
412
442
|
data.each do |d|
|
413
|
-
if defined?(d.name) && self.class.graph.shape?(d.name)
|
443
|
+
if defined?(d.name) && self.class.graph.shape?(d.name) && resolve_all
|
414
444
|
if self.class.graph.shape_as_model(d.name.to_s).metadata[:attributes].select { |_, v| v[:node_kind].is_a?(RDF::URI) }.size > 0 &&
|
415
445
|
hierarchy.select { |s| s =~ /^#{d.name.to_s}/ }.size == 0
|
416
446
|
internal_resolve = false
|
@@ -422,6 +452,8 @@ module Solis
|
|
422
452
|
#d = "#{klass.class.graph_name}#{attribute.tableize}/#{d.id}"
|
423
453
|
d = "#{klass.class.graph_name}#{d.name.tableize}/#{d.id}"
|
424
454
|
end
|
455
|
+
elsif defined?(d.name) && self.class.graph.shape?(d.name)
|
456
|
+
d = "#{klass.class.graph_name}#{d.name.tableize}/#{d.id}"
|
425
457
|
end
|
426
458
|
|
427
459
|
if d.is_a?(Array) && d.length == 1
|
@@ -573,5 +605,21 @@ module Solis
|
|
573
605
|
hierarchy.pop
|
574
606
|
id
|
575
607
|
end
|
608
|
+
|
609
|
+
def self.properties_to_hash(model)
|
610
|
+
n = {}
|
611
|
+
model.class.metadata[:attributes].each_key do |m|
|
612
|
+
if model.instance_variable_get("@#{m}").is_a?(Array)
|
613
|
+
n[m] = model.instance_variable_get("@#{m}").map { |iv| iv.class.ancestors.include?(Solis::Model) ? properties_to_hash(iv) : iv }
|
614
|
+
elsif model.instance_variable_get("@#{m}").class.ancestors.include?(Solis::Model)
|
615
|
+
n[m] = properties_to_hash(model.instance_variable_get("@#{m}"))
|
616
|
+
else
|
617
|
+
n[m] = model.instance_variable_get("@#{m}")
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
n.compact!
|
622
|
+
n
|
623
|
+
end
|
576
624
|
end
|
577
625
|
end
|
data/lib/solis/query/filter.rb
CHANGED
@@ -101,8 +101,13 @@ module Solis
|
|
101
101
|
value[:value].each do |v|
|
102
102
|
if metadata[:datatype_rdf].eql?('http://www.w3.org/1999/02/22-rdf-syntax-ns#langString')
|
103
103
|
filter = "?concept <#{metadata[:path]}> ?__search#{i} "
|
104
|
-
|
105
|
-
|
104
|
+
if v.is_a?(Hash)
|
105
|
+
filter += "FILTER(langMatches( lang(?__search#{i}), \"#{v[:"@language"]}\" )). "
|
106
|
+
search_for = v[:"@value"].is_a?(Array) ? v[:"@value"].first : v[:"@value"]
|
107
|
+
else
|
108
|
+
search_for = v
|
109
|
+
end
|
110
|
+
|
106
111
|
search_for = normalize_string(search_for)
|
107
112
|
filter += "FILTER(str(?__search#{i}) #{not_operator}#{value[:operator]} \"#{search_for}\"#{datatype}) .\n"
|
108
113
|
else
|
data/lib/solis/query.rb
CHANGED
@@ -43,8 +43,8 @@ module Solis
|
|
43
43
|
end
|
44
44
|
ids = ids.join(" ")
|
45
45
|
|
46
|
-
|
47
|
-
q = query.gsub(/{ ?{ ?VALUES ?} ?}/, "VALUES ?#{id_name} { #{ids} }")
|
46
|
+
language = Graphiti.context[:object]&.language || Solis::Options.instance.get[:language] || 'en'
|
47
|
+
q = query.gsub(/{ ?{ ?VALUES ?} ?}/, "VALUES ?#{id_name} { #{ids} }").gsub(/{ ?{ ?LANGUAGE ?} ?}/, "bind(\"#{language}\" as ?filter_language).")
|
48
48
|
|
49
49
|
result = Solis::Query.run(entity, q)
|
50
50
|
end
|
@@ -156,7 +156,7 @@ module Solis
|
|
156
156
|
datatype: p['datatype'],
|
157
157
|
path: "#{graph_prefix}:#{property_name.to_s.classify}",
|
158
158
|
cardinality: { min: min_max['min'], max: min_max['max'] },
|
159
|
-
same_as: p['
|
159
|
+
same_as: p['sameas'],
|
160
160
|
description: p['description']
|
161
161
|
}
|
162
162
|
|
@@ -337,50 +337,50 @@ hide empty members
|
|
337
337
|
datas.first[:ontologies][:all].each { |k, v| all_prefixes[k] = v[:uri] }
|
338
338
|
|
339
339
|
datas.each do |data|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
}
|
347
|
-
|
348
|
-
metadata[:properties].each do |property, property_metadata|
|
349
|
-
attribute = property.to_s.strip
|
350
|
-
description = property_metadata[:description]
|
351
|
-
path = "#{graph_name}#{attribute}"
|
352
|
-
datatype = property_metadata[:datatype]
|
353
|
-
|
354
|
-
schema_data = datatype_properties[attribute] || {}
|
355
|
-
domain = schema_data[:domain] || []
|
356
|
-
domain << "#{graph_name}#{entity_name}"
|
357
|
-
datatype_properties[attribute] = {
|
358
|
-
domain: domain,
|
359
|
-
comment: description,
|
360
|
-
label: attribute.to_s,
|
361
|
-
range: datatype,
|
362
|
-
type: 'rdf:Property'
|
340
|
+
data[:entities].each do |entity_name, metadata|
|
341
|
+
classes[entity_name] = {
|
342
|
+
comment: metadata[:description],
|
343
|
+
label: entity_name.to_s,
|
344
|
+
type: 'owl:Class',
|
345
|
+
subClassOf: metadata[:sub_class_of]
|
363
346
|
}
|
364
|
-
unless property_metadata[:same_as].nil? || property_metadata[:same_as].empty?
|
365
|
-
datatype_properties[attribute]['owl:sameAs'] =
|
366
|
-
property_metadata[:same_as]
|
367
|
-
end
|
368
347
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
348
|
+
metadata[:properties].each do |property, property_metadata|
|
349
|
+
attribute = property.to_s.strip
|
350
|
+
description = property_metadata[:description]
|
351
|
+
path = "#{graph_name}#{attribute}"
|
352
|
+
datatype = property_metadata[:datatype]
|
353
|
+
|
354
|
+
schema_data = datatype_properties[attribute] || {}
|
355
|
+
domain = schema_data[:domain] || []
|
356
|
+
domain << "#{graph_name}#{entity_name}"
|
357
|
+
datatype_properties[attribute] = {
|
358
|
+
domain: domain,
|
359
|
+
comment: description,
|
360
|
+
label: attribute.to_s,
|
361
|
+
range: datatype,
|
362
|
+
type: 'rdf:Property'
|
363
|
+
}
|
364
|
+
unless property_metadata[:same_as].nil? || property_metadata[:same_as].empty?
|
365
|
+
datatype_properties[attribute]['owl:sameAs'] =
|
366
|
+
property_metadata[:same_as]
|
367
|
+
end
|
368
|
+
|
369
|
+
subclass_data = data[:entities][entity_name][:sub_class_of] || []
|
370
|
+
unless property_metadata[:cardinality][:min].empty?
|
371
|
+
subclass_data << RDF::Vocabulary.term(type: 'owl:Restriction',
|
372
|
+
onProperty: path,
|
373
|
+
minCardinality: property_metadata[:cardinality][:min])
|
374
|
+
end
|
375
|
+
unless property_metadata[:cardinality][:max].empty?
|
376
|
+
subclass_data << RDF::Vocabulary.term(type: 'owl:Restriction',
|
377
|
+
onProperty: path,
|
378
|
+
maxCardinality: property_metadata[:cardinality][:max])
|
379
|
+
end
|
380
|
+
data[:entities][entity_name][:sub_class_of] = subclass_data
|
379
381
|
end
|
380
|
-
data[:entities][entity_name][:sub_class_of] = subclass_data
|
381
382
|
end
|
382
383
|
end
|
383
|
-
end
|
384
384
|
|
385
385
|
lp = RDF::StrictVocabulary(graph_name)
|
386
386
|
o = ::Class.new(lp) do
|
data/lib/solis/version.rb
CHANGED
data/solis.gemspec
CHANGED
@@ -40,6 +40,7 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_runtime_dependency 'uuidtools', '~> 2.2.0'
|
41
41
|
spec.add_runtime_dependency 'dry-struct', '~> 1.6'
|
42
42
|
spec.add_runtime_dependency 'psych', '~> 5.1'
|
43
|
+
#spec.add_runtime_dependency 'hashdiff', '~> 1.1'
|
43
44
|
|
44
45
|
spec.add_development_dependency 'rake', '~> 13.0'
|
45
46
|
spec.add_development_dependency 'minitest', '~> 5.19'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.72.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mehmet Celik
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -295,7 +295,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
295
295
|
- !ruby/object:Gem::Version
|
296
296
|
version: '0'
|
297
297
|
requirements: []
|
298
|
-
rubygems_version: 3.
|
298
|
+
rubygems_version: 3.5.6
|
299
299
|
signing_key:
|
300
300
|
specification_version: 4
|
301
301
|
summary: Turn any SHACL file into an API, ORM, documentation, ...
|