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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16ed244eaf62cd747c1e2c2ea369066dcd6a03e529d3932916b4f7791a29b956
4
- data.tar.gz: ef2a72fd541967ccf54ae75ca4f18abb21727cf9398c4da38b9aff3a8b9b5ca7
3
+ metadata.gz: fa7c729b1acbe8c1881ebf3cc00ac228830bf04d269447f55b2f029c7eef703c
4
+ data.tar.gz: 81ceb99f9f6284b8c4163bfe4d263f6703edbe1733eb42fcc6c31530be2c8d91
5
5
  SHA512:
6
- metadata.gz: b955562d76f6ca7942d634098b430c4e19c21c64323c8c676fcacbc494949b9d38aaf6d271c197fd3e8ed49bf200534c1ab473fd56aa883d3bbeda9136482427
7
- data.tar.gz: f80157b099693522c7afa1a0ce607d174ab164a76ad94a69f359a8331588a858710b3a98ee2360cc6d10ef8e7c1299383eb7a129eac7c94773295bc95604fae1
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
- result = sparql.delete_data(graph, graph: graph.name)
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
- # File.open('/Users/mehmetc/Dropbox/AllSources/LP/graphiti-api/save.ttl', 'wb') do |file|
130
- # file.puts graph.dump(:ttl)
131
- # end
132
- Solis::LOGGER.info SPARQL::Client::Update::InsertData.new(graph, graph: graph.name).to_s if ConfigFile[:debug]
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 in attributes" unless attributes.keys.include?('id')
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.send(:"#{key}=", value)
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
- #Solis::LOGGER.info delete_graph.dump(:ttl) if ConfigFile[:debug]
180
- #Solis::LOGGER.info insert_graph.dump(:ttl) if ConfigFile[:debug]
181
- #Solis::LOGGER.info where_graph.dump(:ttl) if ConfigFile[:debug]
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
- Solis::LOGGER.info delete_insert_query
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
- model.instance_variable_set("@id", SecureRandom.uuid)
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
@@ -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
- filter += "FILTER(langMatches( lang(?__search#{i}), \"#{v[:"@language"]}\" )). "
105
- search_for = v[:"@value"].is_a?(Array) ? v[:"@value"].first : v[:"@value"]
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['sameAs'],
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
- 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]
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
- 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])
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
@@ -1,3 +1,3 @@
1
1
  module Solis
2
- VERSION = "0.71.0"
2
+ VERSION = "0.72.0"
3
3
  end
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.71.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: 2023-09-22 00:00:00.000000000 Z
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.4.19
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, ...