solis 0.71.0 → 0.73.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 +192 -53
- 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: a91e5038f9e0a152b51ad35d25c6bdd99ef383bfb0da8fb7baf1d08baddbf49a
         | 
| 4 | 
            +
              data.tar.gz: b4b1a434aae6a337358815e8b0dc5ff37edea7e0ffb56d85a9d7d1590677ea92
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 35f713d36e731ac83203fec6f3d82bd6ad5f321c68ccf1424fd8f0c6b82183392e2c76d62cdd7eac6542318810c62940d9a4e1badb5dd817177509bf65753c9e
         | 
| 7 | 
            +
              data.tar.gz: 5a9efc223d46e01936aed52e649e856344c7847307f6a39d7b094b48d2b553542a8059ce846bd483634cfb7046f9ab9646ed2130bab81de5c196b43af48b95c2
         | 
    
        data/lib/solis/model.rb
    CHANGED
    
    | @@ -71,9 +71,9 @@ module Solis | |
| 71 71 | 
             
                def query
         | 
| 72 72 | 
             
                  raise "I need a SPARQL endpoint" if self.class.sparql_endpoint.nil?
         | 
| 73 73 |  | 
| 74 | 
            -
                  #before_read_proc&.call(self)
         | 
| 74 | 
            +
                  # before_read_proc&.call(self)
         | 
| 75 75 | 
             
                  result = Solis::Query.new(self)
         | 
| 76 | 
            -
                  #after_read_proc&.call(result)
         | 
| 76 | 
            +
                  # after_read_proc&.call(result)
         | 
| 77 77 | 
             
                  result
         | 
| 78 78 | 
             
                end
         | 
| 79 79 |  | 
| @@ -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 self.exists?(sparql)
         | 
| 140 | 
            +
                    data = 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,48 +174,139 @@ module Solis | |
| 155 174 | 
             
                  updated_klass = original_klass.deep_dup
         | 
| 156 175 |  | 
| 157 176 | 
             
                  attributes.each_pair do |key, value|
         | 
| 158 | 
            -
                     | 
| 177 | 
            +
                    if value.is_a?(Hash)
         | 
| 178 | 
            +
                      embedded = self.class.graph.shape_as_model(original_klass.class.metadata[:attributes][key][:datatype].to_s).new(value)
         | 
| 179 | 
            +
                      if embedded.exists?(sparql)
         | 
| 180 | 
            +
                        embedded_data = properties_to_hash(embedded)
         | 
| 181 | 
            +
                        embedded.update(embedded_data)
         | 
| 182 | 
            +
                      else
         | 
| 183 | 
            +
                        embedded.save
         | 
| 184 | 
            +
                      end
         | 
| 185 | 
            +
                    end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                    updated_klass.instance_variable_set("@#{key}", value)
         | 
| 159 188 | 
             
                  end
         | 
| 160 189 |  | 
| 190 | 
            +
                  # attributes.each_pair do |key, value|
         | 
| 191 | 
            +
                  #   updated_klass.instance_variable_set("@#{key}", value)
         | 
| 192 | 
            +
                  # end
         | 
| 193 | 
            +
                  # properties_original_klass=Model.properties_to_hash(original_klass)
         | 
| 194 | 
            +
                  # properties_updated_klass = Model.properties_to_hash(updated_klass)
         | 
| 195 | 
            +
                  # changes = Hashdiff.diff(properties_original_klass, properties_updated_klass)
         | 
| 196 | 
            +
                  # pp changes
         | 
| 197 | 
            +
                  #
         | 
| 198 | 
            +
                  # #a=self.class.graph.shape_as_model('Identificatienummer').new
         | 
| 199 | 
            +
                  # changes.each do |change|
         | 
| 200 | 
            +
                  #   change_type = change[0]
         | 
| 201 | 
            +
                  #   original_change_entity = change[1]
         | 
| 202 | 
            +
                  #   change_entity = original_change_entity.split('.').last
         | 
| 203 | 
            +
                  #   change[1] = change_object
         | 
| 204 | 
            +
                  #   data = change[2]
         | 
| 205 | 
            +
                  #
         | 
| 206 | 
            +
                  #   case change_type
         | 
| 207 | 
            +
                  #   when '+' # new
         | 
| 208 | 
            +
                  #     new_entity_hash = {} #self.class.graph.shape_as_model(change_object.classify).new
         | 
| 209 | 
            +
                  #     Hashdiff.patch!(new_entity_hash, [change])
         | 
| 210 | 
            +
                  #
         | 
| 211 | 
            +
                  #     new_entity = self.class.graph.shape_as_model(change_entity.classify).new(new_entity_hash[change_entity])
         | 
| 212 | 
            +
                  #     new_entity.save
         | 
| 213 | 
            +
                  #   when '-' # delete
         | 
| 214 | 
            +
                  #   when '~' # change
         | 
| 215 | 
            +
                  #   else
         | 
| 216 | 
            +
                  #     raise RuntimeError, "Unknown change type(#{change_type}) for #{change[1]}"
         | 
| 217 | 
            +
                  #   end
         | 
| 218 | 
            +
                  #
         | 
| 219 | 
            +
                  # end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                  # attributes.each_pair do |key, value|
         | 
| 222 | 
            +
                  #   updated_klass.instance_variable_set("@#{key}", value)
         | 
| 223 | 
            +
                  #   unless original_klass.class.metadata[:attributes][key][:node_kind].nil?
         | 
| 224 | 
            +
                  #     inner_model = self.class.graph.shape_as_model(original_klass.class.metadata[:attributes][key][:datatype].to_s)
         | 
| 225 | 
            +
                  #     if value.is_a?(Hash)
         | 
| 226 | 
            +
                  #       value.each_pair do |inner_key, inner_value|
         | 
| 227 | 
            +
                  #         next unless inner_model.metadata[:attributes][inner_key][:node_kind].is_a?(RDF::URI)
         | 
| 228 | 
            +
                  #         inner_inner_model = self.class.graph.shape_as_model(inner_model.metadata[:attributes][inner_key][:datatype].to_s)
         | 
| 229 | 
            +
                  #         # if inner_inner_model.class.ancestors.include?(Codetabel) && inner_value.key?('id')
         | 
| 230 | 
            +
                  #         #   inner_data = inner_inner_model.query.filter({ language: nil, filters: { id: [inner_value['id']] } }).find_all.map { |m| m }&.first
         | 
| 231 | 
            +
                  #         # else
         | 
| 232 | 
            +
                  #         inner_value = inner_value.first if inner_value.is_a?(Array)
         | 
| 233 | 
            +
                  #           inner_data = inner_inner_model.new(inner_value)
         | 
| 234 | 
            +
                  #           inner_data.save
         | 
| 235 | 
            +
                  #         # end
         | 
| 236 | 
            +
                  #       end
         | 
| 237 | 
            +
                  #     elsif value.is_a?(Array)
         | 
| 238 | 
            +
                  #       data = value.map do |m|
         | 
| 239 | 
            +
                  #         if m.is_a?(Hash)
         | 
| 240 | 
            +
                  #           m.each do |inner_key, inner_value|
         | 
| 241 | 
            +
                  #             #next if inner_model.metadata[:attributes][inner_key][:class].nil?
         | 
| 242 | 
            +
                  #             next unless inner_model.metadata[:attributes][inner_key][:node_kind].is_a?(RDF::URI)
         | 
| 243 | 
            +
                  #             inner_inner_model = self.class.graph.shape_as_model(inner_model.class.metadata[:attributes][inner_key][:datatype].to_s)
         | 
| 244 | 
            +
                  #             # if inner_inner_model.class.ancestors.include?(Codetabel) && inner_value.key?('id')
         | 
| 245 | 
            +
                  #             #   inner_data = inner_inner_model.query.filter({ language: nil, filters: { id: [inner_value['id']] } }).find_all.map { |m| m }&.first
         | 
| 246 | 
            +
                  #             # else
         | 
| 247 | 
            +
                  #               inner_value = inner_value.first if inner_value.is_a?(Array)
         | 
| 248 | 
            +
                  #               inner_data = inner_inner_model.new(inner_value)
         | 
| 249 | 
            +
                  #               inner_data.save
         | 
| 250 | 
            +
                  #             # end
         | 
| 251 | 
            +
                  #
         | 
| 252 | 
            +
                  #             inner_data
         | 
| 253 | 
            +
                  #           end
         | 
| 254 | 
            +
                  #         else
         | 
| 255 | 
            +
                  #           m
         | 
| 256 | 
            +
                  #         end
         | 
| 257 | 
            +
                  #       end
         | 
| 258 | 
            +
                  #     elsif value.is_a?(Object)
         | 
| 259 | 
            +
                  #       value.save
         | 
| 260 | 
            +
                  #     end
         | 
| 261 | 
            +
                  #   end
         | 
| 262 | 
            +
                  # end
         | 
| 263 | 
            +
             | 
| 161 264 | 
             
                  before_update_proc&.call(original_klass, updated_klass)
         | 
| 162 265 |  | 
| 163 | 
            -
                   | 
| 164 | 
            -
                   | 
| 165 | 
            -
             | 
| 266 | 
            +
                  properties_orignal_klass = properties_to_hash(original_klass)
         | 
| 267 | 
            +
                  properties_updated_klsss = properties_to_hash(updated_klass)
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                  if Hashdiff.best_diff(properties_orignal_klass, properties_updated_klsss).empty?
         | 
| 270 | 
            +
                    Solis::LOGGER.info("#{original_klass.class.name} unchanged, skipping")
         | 
| 271 | 
            +
                    data = self.query.filter({ filters: { id: [id] } }).find_all.map { |m| m }&.first
         | 
| 272 | 
            +
                  else
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                    delete_graph = as_graph(original_klass, false)
         | 
| 166 275 |  | 
| 167 | 
            -
             | 
| 276 | 
            +
                    where_graph = RDF::Graph.new(graph_name: RDF::URI("#{self.class.graph_name}#{self.name.tableize}/#{id}"), data: RDF::Repository.new)
         | 
| 168 277 |  | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 278 | 
            +
                    if id.is_a?(Array)
         | 
| 279 | 
            +
                      id.each do |i|
         | 
| 280 | 
            +
                        where_graph << [RDF::URI("#{self.class.graph_name}#{self.name.tableize}/#{i}"), :p, :o]
         | 
| 281 | 
            +
                      end
         | 
| 282 | 
            +
                    else
         | 
| 283 | 
            +
                      where_graph << [RDF::URI("#{self.class.graph_name}#{self.name.tableize}/#{id}"), :p, :o]
         | 
| 172 284 | 
             
                    end
         | 
| 173 | 
            -
                  else
         | 
| 174 | 
            -
                    where_graph << [RDF::URI("#{self.class.graph_name}#{self.name.tableize}/#{id}"), :p, :o]
         | 
| 175 | 
            -
                  end
         | 
| 176 285 |  | 
| 177 | 
            -
             | 
| 286 | 
            +
                    insert_graph = as_graph(updated_klass, true)
         | 
| 178 287 |  | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 181 | 
            -
             | 
| 288 | 
            +
                    # puts delete_graph.dump(:ttl) #if ConfigFile[:debug]
         | 
| 289 | 
            +
                    # puts insert_graph.dump(:ttl) #if ConfigFile[:debug]
         | 
| 290 | 
            +
                    # puts where_graph.dump(:ttl) #if ConfigFile[:debug]
         | 
| 182 291 |  | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 292 | 
            +
                    # if ConfigFile[:debug]
         | 
| 293 | 
            +
                    delete_insert_query = SPARQL::Client::Update::DeleteInsert.new(delete_graph, insert_graph, where_graph, graph: insert_graph.name).to_s
         | 
| 294 | 
            +
                    delete_insert_query.gsub!('_:p', '?p')
         | 
| 295 | 
            +
                    # puts delete_insert_query
         | 
| 296 | 
            +
                    data = sparql.query(delete_insert_query)
         | 
| 297 | 
            +
                    # pp data
         | 
| 298 | 
            +
                    # end
         | 
| 190 299 |  | 
| 191 | 
            -
             | 
| 300 | 
            +
                    #      sparql.delete_insert(delete_graph, insert_graph, where_graph, graph: insert_graph.name)
         | 
| 192 301 |  | 
| 193 | 
            -
                  data = self.query.filter({ filters: { id: [id] } }).find_all.map { |m| m }&.first
         | 
| 194 | 
            -
                  if data.nil?
         | 
| 195 | 
            -
                    sparql.insert_data(insert_graph, graph: insert_graph.name)
         | 
| 196 302 | 
             
                    data = self.query.filter({ filters: { id: [id] } }).find_all.map { |m| m }&.first
         | 
| 303 | 
            +
                    if data.nil?
         | 
| 304 | 
            +
                      sparql.insert_data(insert_graph, graph: insert_graph.name)
         | 
| 305 | 
            +
                      data = self.query.filter({ filters: { id: [id] } }).find_all.map { |m| m }&.first
         | 
| 306 | 
            +
                    end
         | 
| 197 307 | 
             
                  end
         | 
| 198 | 
            -
             | 
| 199 308 | 
             
                  after_update_proc&.call(updated_klass, data)
         | 
| 309 | 
            +
             | 
| 200 310 | 
             
                  data
         | 
| 201 311 | 
             
                rescue StandardError => e
         | 
| 202 312 | 
             
                  original_graph = as_graph(original_klass, false)
         | 
| @@ -207,10 +317,23 @@ module Solis | |
| 207 317 | 
             
                  raise e
         | 
| 208 318 | 
             
                end
         | 
| 209 319 |  | 
| 320 | 
            +
                def graph_id
         | 
| 321 | 
            +
                  "#{self.class.graph_name}#{self.name.tableize}/#{self.id}"
         | 
| 322 | 
            +
                end
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                def is_referenced?(sparql)
         | 
| 325 | 
            +
                  sparql.query("ASK WHERE { ?s ?p <#{self.graph_id}>. filter (!contains(str(?p), '_audit'))}")
         | 
| 326 | 
            +
                end
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                def exists?(sparql)
         | 
| 329 | 
            +
                  sparql.query("ASK WHERE { <#{self.graph_id}> ?p ?o }")
         | 
| 330 | 
            +
                end
         | 
| 331 | 
            +
             | 
| 210 332 | 
             
                def self.make_id_for(model)
         | 
| 211 333 | 
             
                  id = model.instance_variable_get("@id")
         | 
| 212 334 | 
             
                  if id.nil? || (id.is_a?(String) && id&.empty?)
         | 
| 213 | 
            -
                     | 
| 335 | 
            +
                    id = SecureRandom.uuid
         | 
| 336 | 
            +
                    model.instance_variable_set("@id", id)
         | 
| 214 337 | 
             
                  end
         | 
| 215 338 | 
             
                  model
         | 
| 216 339 | 
             
                end
         | 
| @@ -356,7 +479,7 @@ module Solis | |
| 356 479 |  | 
| 357 480 | 
             
                  graph << [id, RDF::RDFV.type, klass_metadata[:target_class]]
         | 
| 358 481 |  | 
| 359 | 
            -
                  #load existing object and overwrite
         | 
| 482 | 
            +
                  # load existing object and overwrite
         | 
| 360 483 | 
             
                  original_klass = klass.query.filter({ filters: { id: [uuid] } }).find_all { |f| f.id == uuid }.first || nil
         | 
| 361 484 |  | 
| 362 485 | 
             
                  if original_klass.nil?
         | 
| @@ -381,11 +504,9 @@ module Solis | |
| 381 504 | 
             
                def make_graph(graph, hierarchy, id, klass, klass_metadata, resolve_all)
         | 
| 382 505 | 
             
                  klass_metadata[:attributes].each do |attribute, metadata|
         | 
| 383 506 | 
             
                    data = klass.instance_variable_get("@#{attribute}")
         | 
| 384 | 
            -
             | 
| 385 | 
            -
             | 
| 386 | 
            -
             | 
| 387 | 
            -
                      metadata[:mincount] > 0 &&
         | 
| 388 | 
            -
                      graph.query(RDF::Query.new({ attribute.to_sym => { RDF.type => metadata[:node] } })).size == 0
         | 
| 507 | 
            +
                    if data.nil? && metadata[:mincount] > 0 && graph.query(RDF::Query.new({ attribute.to_sym => { RDF.type => metadata[:node] } })).size == 0
         | 
| 508 | 
            +
                      raise Solis::Error::InvalidAttributeError, "#{hierarchy.join('.')}.#{attribute} min=#{metadata[:mincount]} and max=#{metadata[:maxcount]}"
         | 
| 509 | 
            +
                    end
         | 
| 389 510 |  | 
| 390 511 | 
             
                    # skip if nil or an object that is empty
         | 
| 391 512 | 
             
                    next if data.nil? || ([Hash, Array, String].include?(data.class) && data&.empty?)
         | 
| @@ -397,7 +518,7 @@ module Solis | |
| 397 518 | 
             
                      data = data.to_json
         | 
| 398 519 | 
             
                    end
         | 
| 399 520 |  | 
| 400 | 
            -
                    #make it an object
         | 
| 521 | 
            +
                    # make it an object
         | 
| 401 522 | 
             
                    unless metadata[:node_kind].nil?
         | 
| 402 523 | 
             
                      model = self.class.graph.shape_as_model(metadata[:datatype].to_s)
         | 
| 403 524 | 
             
                      if data.is_a?(Hash)
         | 
| @@ -410,7 +531,7 @@ module Solis | |
| 410 531 | 
             
                    data = [data] unless data.is_a?(Array)
         | 
| 411 532 |  | 
| 412 533 | 
             
                    data.each do |d|
         | 
| 413 | 
            -
                      if defined?(d.name) && self.class.graph.shape?(d.name)
         | 
| 534 | 
            +
                      if defined?(d.name) && self.class.graph.shape?(d.name) && resolve_all
         | 
| 414 535 | 
             
                        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 536 | 
             
                          hierarchy.select { |s| s =~ /^#{d.name.to_s}/ }.size == 0
         | 
| 416 537 | 
             
                          internal_resolve = false
         | 
| @@ -419,9 +540,11 @@ module Solis | |
| 419 540 | 
             
                          internal_resolve = false
         | 
| 420 541 | 
             
                          d = build_ttl_objekt2(graph, d, hierarchy, internal_resolve)
         | 
| 421 542 | 
             
                        else
         | 
| 422 | 
            -
                          #d = "#{klass.class.graph_name}#{attribute.tableize}/#{d.id}"
         | 
| 543 | 
            +
                          # d = "#{klass.class.graph_name}#{attribute.tableize}/#{d.id}"
         | 
| 423 544 | 
             
                          d = "#{klass.class.graph_name}#{d.name.tableize}/#{d.id}"
         | 
| 424 545 | 
             
                        end
         | 
| 546 | 
            +
                      elsif defined?(d.name) && self.class.graph.shape?(d.name)
         | 
| 547 | 
            +
                        d = "#{klass.class.graph_name}#{d.name.tableize}/#{d.id}"
         | 
| 425 548 | 
             
                      end
         | 
| 426 549 |  | 
| 427 550 | 
             
                      if d.is_a?(Array) && d.length == 1
         | 
| @@ -522,7 +645,7 @@ module Solis | |
| 522 645 | 
             
                      end
         | 
| 523 646 |  | 
| 524 647 | 
             
                      if model && d.is_a?(Hash)
         | 
| 525 | 
            -
                        #TODO: figure out in what use case we need the parent_model
         | 
| 648 | 
            +
                        # TODO: figure out in what use case we need the parent_model
         | 
| 526 649 | 
             
                        # model_instance = if parent_model
         | 
| 527 650 | 
             
                        #                     parent_model.new(d)
         | 
| 528 651 | 
             
                        #                  else
         | 
| @@ -573,5 +696,21 @@ module Solis | |
| 573 696 | 
             
                  hierarchy.pop
         | 
| 574 697 | 
             
                  id
         | 
| 575 698 | 
             
                end
         | 
| 699 | 
            +
             | 
| 700 | 
            +
                def properties_to_hash(model)
         | 
| 701 | 
            +
                  n = {}
         | 
| 702 | 
            +
                  model.class.metadata[:attributes].each_key do |m|
         | 
| 703 | 
            +
                    if model.instance_variable_get("@#{m}").is_a?(Array)
         | 
| 704 | 
            +
                      n[m] = model.instance_variable_get("@#{m}").map { |iv| iv.class.ancestors.include?(Solis::Model) ? properties_to_hash(iv) : iv }
         | 
| 705 | 
            +
                    elsif model.instance_variable_get("@#{m}").class.ancestors.include?(Solis::Model)
         | 
| 706 | 
            +
                      n[m] = properties_to_hash(model.instance_variable_get("@#{m}"))
         | 
| 707 | 
            +
                    else
         | 
| 708 | 
            +
                      n[m] = model.instance_variable_get("@#{m}")
         | 
| 709 | 
            +
                    end
         | 
| 710 | 
            +
                  end
         | 
| 711 | 
            +
             | 
| 712 | 
            +
                  n.compact!
         | 
| 713 | 
            +
                  n
         | 
| 714 | 
            +
                end
         | 
| 576 715 | 
             
              end
         | 
| 577 716 | 
             
            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.73.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-03-11 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, ...
         |