From 694aa19dc46941d01535f07996320307f74eb84d Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Tue, 15 Mar 2022 18:13:23 +0100 Subject: [PATCH 1/9] add main_languages configuration variable --- lib/goo.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/goo.rb b/lib/goo.rb index 1867c7d6..fedae62e 100644 --- a/lib/goo.rb +++ b/lib/goo.rb @@ -25,6 +25,8 @@ module Goo @@resource_options = Set.new([:persistent]).freeze + # Define the languages from which the properties values will be taken + @@main_languages = %w[en] @@configure_flag = false @@sparql_backends = {} @@model_by_name = {} @@ -42,6 +44,19 @@ module Goo @@slice_loading_size = 500 + + def self.main_languages + @@main_languages + end + def self.main_languages=(lang) + @@main_languages = lang + end + + def self.language_includes(lang) + lang_str = lang.to_s + main_languages.index { |l| lang_str.downcase.eql?(l) || lang_str.upcase.eql?(l)} + end + def self.add_namespace(shortcut, namespace,default=false) if !(namespace.instance_of? RDF::Vocabulary) raise ArgumentError, "Namespace must be a RDF::Vocabulary object" From eec4d6066655ba4657dab173cb6d0765e8ce6e45 Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Tue, 15 Mar 2022 18:15:19 +0100 Subject: [PATCH 2/9] add LanguageFilter class to filter an attribute values by the languages --- lib/goo/sparql/mixins/solution_lang_filter.rb | 83 +++++++++++++++++++ lib/goo/sparql/sparql.rb | 1 + 2 files changed, 84 insertions(+) create mode 100644 lib/goo/sparql/mixins/solution_lang_filter.rb diff --git a/lib/goo/sparql/mixins/solution_lang_filter.rb b/lib/goo/sparql/mixins/solution_lang_filter.rb new file mode 100644 index 00000000..af02b44a --- /dev/null +++ b/lib/goo/sparql/mixins/solution_lang_filter.rb @@ -0,0 +1,83 @@ +module Goo + module SPARQL + module Solution + class LanguageFilter + + def initialize + @other_languages_values = {} + end + + def other_languages_values + @other_languages_values + end + + def main_lang_filter(id, attr, old_values, new_value) + index, value = lang_index old_values, new_value + save_other_lang_val(id, attr, index, new_value) unless index.eql? :no_lang + [index, value] + end + + def fill_models_with_other_languages(models_by_id, list_attributes) + @other_languages_values.each do |id, languages_values| + languages_values.each do |attr, index_values| + model_attribute_val = models_by_id[id].instance_variable_get("@#{attr.to_s}") + values = languages_values_to_set(index_values, model_attribute_val) + + if !values.nil? && list_attributes.include?(attr) + models_by_id[id].send("#{attr.to_s}=", values || [], on_load: true) + elsif !values.nil? + models_by_id[id].send("#{attr.to_s}=", values.first || nil, on_load: true) + end + end + end + end + + def languages_values_to_set(language_values, no_lang_values) + + values = nil + matched_lang, not_matched_lang = matched_languages(language_values, no_lang_values) + if !matched_lang.empty? + main_lang = Array(matched_lang[:'0']) + Array(matched_lang[:no_lang]) + secondary_languages = matched_lang.select { |key| key != :'0' && key != :no_lang }.sort.map { |x| x[1] }.flatten + values = main_lang + secondary_languages + elsif !not_matched_lang.empty? + values = not_matched_lang + end + values + end + + private + + def lang_index(object, new_value) + lang = new_value.language + if lang.nil? + [:no_lang, object] + else + index = Goo.language_includes(lang) + index = index ? index.to_s.to_sym : :not_matched + [index, new_value] + end + end + + def save_other_lang_val(id, attr, index, value) + @other_languages_values[id] ||= {} + @other_languages_values[id][attr] ||= {} + @other_languages_values[id][attr][index] ||= [] + + unless @other_languages_values[id][attr][index].include?(value.to_s) + @other_languages_values[id][attr][index] += Array(value.to_s) + end + end + + + + def matched_languages(index_values, model_attribute_val) + not_matched_lang = index_values[:not_matched] + matched_lang = index_values.reject { |key| key == :not_matched } + matched_lang[:no_lang] = Array(model_attribute_val) unless model_attribute_val.nil? + [matched_lang, not_matched_lang] + end + end + end + end +end diff --git a/lib/goo/sparql/sparql.rb b/lib/goo/sparql/sparql.rb index dfd3d0a6..6fa1d582 100644 --- a/lib/goo/sparql/sparql.rb +++ b/lib/goo/sparql/sparql.rb @@ -1,6 +1,7 @@ require "sparql/client" require_relative "mixins/query_pattern" +require_relative "mixins/solution_lang_filter" require_relative "query_builder" require_relative "solutions_mapper" require_relative "client" From 31b0bb051c1bf52e8fea19bd77a3dd073d0f436f Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Tue, 15 Mar 2022 18:15:44 +0100 Subject: [PATCH 3/9] use LanguageFilter in the solution mapper --- lib/goo/sparql/solutions_mapper.rb | 47 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/goo/sparql/solutions_mapper.rb b/lib/goo/sparql/solutions_mapper.rb index 386b3f18..209bf316 100644 --- a/lib/goo/sparql/solutions_mapper.rb +++ b/lib/goo/sparql/solutions_mapper.rb @@ -19,6 +19,7 @@ def initialize(aggregate_projections, bnode_extraction, embed_struct, @variables = variables @options = options + end def map_each_solutions(select) @@ -31,9 +32,9 @@ def map_each_solutions(select) found = Set.new objects_new = {} - var_set_hash = {} list_attributes = Set.new(klass.attributes(:list)) all_attributes = Set.new(klass.attributes(:all)) + @lang_filter = Goo::SPARQL::Solution::LanguageFilter.new select.each_solution do |sol| next if sol[:some_type] && klass.type_uri(collection) != sol[:some_type] @@ -83,11 +84,13 @@ def map_each_solutions(select) object = object_to_array(id, @klass_struct, @models_by_id, object, v) if list_attributes.include?(v) - model_map_attributes_values(id, var_set_hash, @models_by_id, object, sol, v) unless object.nil? + model_map_attributes_values(id, object, sol, v) end end + @lang_filter.fill_models_with_other_languages(@models_by_id, list_attributes) return @models_by_id if @bnode_extraction + model_set_collection_attributes(collection, klass, @models_by_id, objects_new) #remove from models_by_id elements that were not touched @@ -119,7 +122,6 @@ def model_set_unmapped(models_by_id, sol) end end - def create_struct(bnode_extraction, klass, models_by_id, sol, variables) list_attributes = Set.new(klass.attributes(:list)) struct = klass.range(bnode_extraction).new @@ -144,6 +146,7 @@ def create_class_model(id, klass, klass_struct) klass_model.klass = klass if klass_struct klass_model end + def models_unmapped_to_array(models_by_id) models_by_id.each do |idm, m| m.unmmaped_to_array @@ -215,36 +218,32 @@ def model_set_collection_attributes(collection, klass, models_by_id, objects_new def get_collection_value(collection, klass) collection_value = nil if klass.collection_opts.instance_of?(Symbol) - if collection.is_a?(Array) && (collection.length == 1) - collection_value = collection.first - end - if collection.respond_to? :id - collection_value = collection - end + collection_value = collection.first if collection.is_a?(Array) && (collection.length == 1) + collection_value = collection if collection.respond_to? :id end collection_value end - def model_map_attributes_values(id, var_set_hash, models_by_id, object, sol, v) - if models_by_id[id].respond_to?(:klass) - models_by_id[id][v] = object if models_by_id[id][v].nil? + def model_map_attributes_values(id, object, sol, v) + + if @models_by_id[id].respond_to?(:klass) + @models_by_id[id][v] = object if @models_by_id[id][v].nil? else - model_attribute_val = models_by_id[id].instance_variable_get("@#{v.to_s}") - if (!models_by_id[id].class.handler?(v) || model_attribute_val.nil?) && v != :id + model_attribute_val = @models_by_id[id].instance_variable_get("@#{v.to_s}") + if (!@models_by_id[id].class.handler?(v) || model_attribute_val.nil?) && v != :id # if multiple language values are included for a given property, set the # corresponding model attribute to the English language value - NCBO-1662 if sol[v].kind_of?(RDF::Literal) - key = "#{v}#__#{id.to_s}" - models_by_id[id].send("#{v}=", object, on_load: true) unless var_set_hash[key] - lang = sol[v].language - var_set_hash[key] = true if lang == :EN || lang == :en - else - models_by_id[id].send("#{v}=", object, on_load: true) + index, value = @lang_filter.main_lang_filter id, v, object, sol[v] + @models_by_id[id].send("#{v}=", value, on_load: true) if index.eql? :no_lang + elsif model_attribute_val.nil? + @models_by_id[id].send("#{v}=", object, on_load: true) end end end end + def object_to_array(id, klass_struct, models_by_id, object, v) pre = klass_struct ? models_by_id[id][v] : models_by_id[id].instance_variable_get("@#{v}") @@ -301,11 +300,11 @@ def get_pre_val(id, models_by_id, object, v, read_only) if models_by_id[id] && ((models_by_id[id].respond_to?(:klass) && models_by_id[id]) || models_by_id[id].loaded_attributes.include?(v)) - if !read_only - pre_val = models_by_id[id].instance_variable_get("@#{v}") + pre_val = if !read_only + models_by_id[id].instance_variable_get("@#{v}") else - pre_val = models_by_id[id][v] - end + models_by_id[id][v] + end pre_val = pre_val.select { |x| x.id == object }.first if pre_val.is_a?(Array) end From 55a931367c2ec1dd6c8c07e51db8d01bc8e0a298 Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Tue, 15 Mar 2022 18:18:30 +0100 Subject: [PATCH 4/9] use the LanguageFilter in map_attributes --- lib/goo/base/resource.rb | 206 ++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 110 deletions(-) diff --git a/lib/goo/base/resource.rb b/lib/goo/base/resource.rb index c12f6203..34504069 100644 --- a/lib/goo/base/resource.rb +++ b/lib/goo/base/resource.rb @@ -42,9 +42,7 @@ def valid? self.class.attributes.each do |attr| inst_value = self.instance_variable_get("@#{attr}") attr_errors = Goo::Validators::Enforce.enforce(self,attr,inst_value) - unless attr_errors.nil? - validation_errors[attr] = attr_errors - end + validation_errors[attr] = attr_errors unless attr_errors.nil? end if !@persistent && validation_errors.length == 0 @@ -70,18 +68,14 @@ def valid? end def id=(new_id) - if !@id.nil? and @persistent - raise ArgumentError, "The id of a persistent object cannot be changed." - end + raise ArgumentError, "The id of a persistent object cannot be changed." if !@id.nil? and @persistent raise ArgumentError, "ID must be an RDF::URI" unless new_id.kind_of?(RDF::URI) @id = new_id end def id if @id.nil? - if self.class.name_with == :id - raise IDGenerationError, ":id must be set if configured in name_with" - end + raise IDGenerationError, ":id must be set if configured in name_with" if self.class.name_with == :id custom_name = self.class.name_with if custom_name.instance_of?(Symbol) @id = id_from_attribute() @@ -153,9 +147,7 @@ def unmmaped_to_array def delete(*args) if self.kind_of?(Goo::Base::Enum) - unless args[0] && args[0][:init_enum] - raise ArgumentError, "Enums cannot be deleted" - end + raise ArgumentError, "Enums cannot be deleted" unless args[0] && args[0][:init_enum] end raise ArgumentError, "This object is not persistent and cannot be deleted" if !@persistent @@ -163,9 +155,7 @@ def delete(*args) if !fully_loaded? missing = missing_load_attributes options_load = { models: [ self ], klass: self.class, :include => missing } - if self.class.collection_opts - options_load[:collection] = self.collection - end + options_load[:collection] = self.collection if self.class.collection_opts Goo::SPARQL::Queries.model_load(options_load) end @@ -181,9 +171,7 @@ def delete(*args) end @persistent = false @modified = true - if self.class.inmutable? && self.class.inm_instances - self.class.load_inmutable_instances - end + self.class.load_inmutable_instances if self.class.inmutable? && self.class.inm_instances return nil end @@ -191,15 +179,11 @@ def bring(*opts) opts.each do |k| if k.kind_of?(Hash) k.each do |k2,v| - if self.class.handler?(k2) - raise ArgumentError, "Unable to bring a method based attr #{k2}" - end + raise ArgumentError, "Unable to bring a method based attr #{k2}" if self.class.handler?(k2) self.instance_variable_set("@#{k2}",nil) end else - if self.class.handler?(k) - raise ArgumentError, "Unable to bring a method based attr #{k}" - end + raise ArgumentError, "Unable to bring a method based attr #{k}" if self.class.handler?(k) self.instance_variable_set("@#{k}",nil) end end @@ -214,9 +198,7 @@ def bring(*opts) def graph opts = self.class.collection_opts - if opts.nil? - return self.class.uri_type - end + return self.class.uri_type if opts.nil? col = collection if col.is_a?Array if col.length == 1 @@ -228,79 +210,14 @@ def graph return col ? col.id : nil end - def self.map_attributes(inst,equivalent_predicates=nil) - if (inst.kind_of?(Goo::Base::Resource) && inst.unmapped.nil?) || - (!inst.respond_to?(:unmapped) && inst[:unmapped].nil?) - raise ArgumentError, "Resource.map_attributes only works for :unmapped instances" - end - klass = inst.respond_to?(:klass) ? inst[:klass] : inst.class - unmapped = inst.respond_to?(:klass) ? inst[:unmapped] : inst.unmapped - list_attrs = klass.attributes(:list) - unmapped_string_keys = Hash.new - unmapped.each do |k,v| - unmapped_string_keys[k.to_s] = v - end - klass.attributes.each do |attr| - next if inst.class.collection?(attr) #collection is already there - next unless inst.respond_to?(attr) - attr_uri = klass.attribute_uri(attr,inst.collection).to_s - if unmapped_string_keys.include?(attr_uri.to_s) || - (equivalent_predicates && equivalent_predicates.include?(attr_uri)) - object = nil - if !unmapped_string_keys.include?(attr_uri) - equivalent_predicates[attr_uri].each do |eq_attr| - if object.nil? and !unmapped_string_keys[eq_attr].nil? - object = unmapped_string_keys[eq_attr].dup - else - if object.is_a?Array - if !unmapped_string_keys[eq_attr].nil? - object.concat(unmapped_string_keys[eq_attr]) - end - end - end - end - if object.nil? - inst.send("#{attr}=", - list_attrs.include?(attr) ? [] : nil, on_load: true) - next - end - else - object = unmapped_string_keys[attr_uri] - end - object = object.map { |o| o.is_a?(RDF::URI) ? o : o.object } - if klass.range(attr) - object = object.map { |o| - o.is_a?(RDF::URI) ? klass.range_object(attr,o) : o } - end - unless list_attrs.include?(attr) - object = object.first - end - if inst.respond_to?(:klass) - inst[attr] = object - else - inst.send("#{attr}=",object, on_load: true) - end - else - inst.send("#{attr}=", - list_attrs.include?(attr) ? [] : nil, on_load: true) - if inst.id.to_s == "http://purl.obolibrary.org/obo/IAO_0000415" - if attr == :definition - # binding.pry - end - end - end - end - end def collection opts = self.class.collection_opts if opts.instance_of?(Symbol) if self.class.attributes.include?(opts) value = self.send("#{opts}") - if value.nil? - raise ArgumentError, "Collection `#{opts}` is nil" - end + raise ArgumentError, "Collection `#{opts}` is nil" if value.nil? return value else raise ArgumentError, "Collection `#{opts}` is not an attribute" @@ -315,9 +232,7 @@ def add_aggregate(attribute,aggregate,value) def save(*opts) if self.kind_of?(Goo::Base::Enum) - unless opts[0] && opts[0][:init_enum] - raise ArgumentError, "Enums can only be created on initialization" - end + raise ArgumentError, "Enums can only be created on initialization" unless opts[0] && opts[0][:init_enum] end batch_file = nil if opts && opts.length > 0 @@ -327,9 +242,7 @@ def save(*opts) end if !batch_file - if not modified? - return self - end + return self if not modified? raise Goo::Base::NotValidException, "Object is not valid. Check errors." unless valid? end @@ -368,9 +281,7 @@ def save(*opts) @modified_attributes = Set.new @persistent = true - if self.class.inmutable? && self.class.inm_instances - self.class.load_inmutable_instances - end + self.class.load_inmutable_instances if self.class.inmutable? && self.class.inm_instances return self end @@ -408,9 +319,7 @@ def to_hash end end @unmapped.each do |attr,values| - unless all_attr_uris.include?(attr) - attr_hash[attr] = values.map { |v| v.to_s } - end + attr_hash[attr] = values.map { |v| v.to_s } unless all_attr_uris.include?(attr) end end attr_hash[:id] = @id @@ -430,13 +339,90 @@ def self.range_object(attr,id) return range_object end - def self.find(id, *options) - if !id.instance_of?(RDF::URI) && self.name_with == :id - id = RDF::URI.new(id) + + + def self.map_attributes(inst,equivalent_predicates=nil) + if (inst.kind_of?(Goo::Base::Resource) && inst.unmapped.nil?) || + (!inst.respond_to?(:unmapped) && inst[:unmapped].nil?) + raise ArgumentError, "Resource.map_attributes only works for :unmapped instances" end - unless id.instance_of?(RDF::URI) - id = id_from_unique_attribute(name_with(),id) + klass = inst.respond_to?(:klass) ? inst[:klass] : inst.class + unmapped = inst.respond_to?(:klass) ? inst[:unmapped] : inst.unmapped + list_attrs = klass.attributes(:list) + unmapped_string_keys = Hash.new + unmapped.each do |k,v| + unmapped_string_keys[k.to_s] = v + end + klass.attributes.each do |attr| + next if inst.class.collection?(attr) #collection is already there + next unless inst.respond_to?(attr) + attr_uri = klass.attribute_uri(attr,inst.collection).to_s + if unmapped_string_keys.include?(attr_uri.to_s) || + (equivalent_predicates && equivalent_predicates.include?(attr_uri)) + object = nil + if !unmapped_string_keys.include?(attr_uri) + equivalent_predicates[attr_uri].each do |eq_attr| + if object.nil? and !unmapped_string_keys[eq_attr].nil? + object = unmapped_string_keys[eq_attr].dup + else + if object.is_a?Array + object.concat(unmapped_string_keys[eq_attr]) if !unmapped_string_keys[eq_attr].nil? + end + end + end + if object.nil? + inst.send("#{attr}=", list_attrs.include?(attr) ? [] : nil, on_load: true) + next + end + else + object = unmapped_string_keys[attr_uri] + end + + lang_filter = Goo::SPARQL::Solution::LanguageFilter.new + + object = object.map do |o| + if o.is_a?(RDF::URI) + o + else + literal = o + index, lang_val = lang_filter.main_lang_filter inst.id.to_s, attr, literal, literal + lang_val.to_s if index.eql? :no_lang + end + end + + object = object.compact + + other_languages_values = lang_filter.other_languages_values + other_languages_values = other_languages_values[inst.id.to_s][attr] unless other_languages_values.empty? + unless other_languages_values.nil? + object = lang_filter.languages_values_to_set(other_languages_values, object) + end + + if klass.range(attr) + object = object.map { |o| + o.is_a?(RDF::URI) ? klass.range_object(attr,o) : o } + end + object = object.first unless list_attrs.include?(attr) + if inst.respond_to?(:klass) + inst[attr] = object + else + inst.send("#{attr}=",object, on_load: true) + end + else + inst.send("#{attr}=", + list_attrs.include?(attr) ? [] : nil, on_load: true) + if inst.id.to_s == "http://purl.obolibrary.org/obo/IAO_0000415" + if attr == :definition + # binding.pry + end + end + end + end + end + def self.find(id, *options) + id = RDF::URI.new(id) if !id.instance_of?(RDF::URI) && self.name_with == :id + id = id_from_unique_attribute(name_with(),id) unless id.instance_of?(RDF::URI) if self.inmutable? && self.inm_instances && self.inm_instances[id] w = Goo::Base::Where.new(self) w.instance_variable_set("@result", [self.inm_instances[id]]) From 1108250e41ff37f65ad7659d8aa81ab251b93c8b Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Wed, 16 Mar 2022 08:45:39 +0100 Subject: [PATCH 5/9] add include variable to the solution mapper arguments --- lib/goo/sparql/loader.rb | 7 ++++--- lib/goo/sparql/solutions_mapper.rb | 14 ++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/goo/sparql/loader.rb b/lib/goo/sparql/loader.rb index d877d47d..a542c820 100644 --- a/lib/goo/sparql/loader.rb +++ b/lib/goo/sparql/loader.rb @@ -93,7 +93,8 @@ def self.model_load_sliced(*options) expand_equivalent_predicates(select, equivalent_predicates) solution_mapper = Goo::SPARQL::SolutionMapper.new aggregate_projections, bnode_extraction, embed_struct, incl_embed, klass_struct, models_by_id, - predicates_map, unmapped, variables, options + predicates_map, unmapped, variables, incl, options + solution_mapper.map_each_solutions(select) end @@ -147,10 +148,10 @@ def self.get_predicate_map(predicates) predicates_map = {} uniq_p.each do |p| i = 0 - key = ("var_" + p.last_part + i.to_s).to_sym + key = ("var_#{p.last_part}#{i.to_s}").to_sym while predicates_map.include?(key) i += 1 - key = ("var_" + p.last_part + i.to_s).to_sym + key = ("var_#{p.last_part}#{i.to_s}").to_sym break if i > 10 end predicates_map[key] = p diff --git a/lib/goo/sparql/solutions_mapper.rb b/lib/goo/sparql/solutions_mapper.rb index 209bf316..57303f4d 100644 --- a/lib/goo/sparql/solutions_mapper.rb +++ b/lib/goo/sparql/solutions_mapper.rb @@ -6,7 +6,7 @@ class SolutionMapper def initialize(aggregate_projections, bnode_extraction, embed_struct, incl_embed, klass_struct, models_by_id, - predicates_map, unmapped, variables, options) + predicates_map, unmapped, variables, incl, options) @aggregate_projections = aggregate_projections @bnode_extraction = bnode_extraction @@ -17,6 +17,7 @@ def initialize(aggregate_projections, bnode_extraction, embed_struct, @predicates_map = predicates_map @unmapped = unmapped @variables = variables + @incl = incl @options = options @@ -28,7 +29,7 @@ def map_each_solutions(select) klass = @options[:klass] read_only = @options[:read_only] collection = @options[:collection] - incl = @options[:include] + found = Set.new objects_new = {} @@ -72,7 +73,7 @@ def map_each_solutions(select) object = sol[v] || nil #bnodes - if object.kind_of?(RDF::Node) && object.anonymous? && incl.include?(v) + if object.kind_of?(RDF::Node) && object.anonymous? && @incl.include?(v) initialize_object(id, klass, object, objects_new, v) next end @@ -101,6 +102,7 @@ def map_each_solutions(select) #next level of embed attributes include_embed_attributes(collection, @incl_embed, klass, objects_new) if @incl_embed && !@incl_embed.empty? + #bnodes bnodes = objects_new.select { |id, obj| id.is_a?(RDF::Node) && id.anonymous? } include_bnodes(bnodes, collection, klass, @models_by_id) unless bnodes.empty? @@ -182,7 +184,7 @@ def include_embed_attributes(collection, incl_embed, klass, objects_new) }.values unless range_objs.empty? range_objs.uniq! - attr_range.where().models(range_objs).in(collection).include(*next_attrs).all + attr_range.where.models(range_objs).in(collection).include(*next_attrs).all end end end @@ -225,7 +227,7 @@ def get_collection_value(collection, klass) end def model_map_attributes_values(id, object, sol, v) - + #binding.pry if v.eql? :programs if @models_by_id[id].respond_to?(:klass) @models_by_id[id][v] = object if @models_by_id[id][v].nil? else @@ -236,7 +238,7 @@ def model_map_attributes_values(id, object, sol, v) if sol[v].kind_of?(RDF::Literal) index, value = @lang_filter.main_lang_filter id, v, object, sol[v] @models_by_id[id].send("#{v}=", value, on_load: true) if index.eql? :no_lang - elsif model_attribute_val.nil? + elsif model_attribute_val.nil? || !object.nil? @models_by_id[id].send("#{v}=", object, on_load: true) end end From 7c9aa7260d828e74d780d967d8947eeb49d7015b Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Wed, 16 Mar 2022 14:26:37 +0100 Subject: [PATCH 6/9] change the language filter to take only one language --- lib/goo.rb | 2 ++ lib/goo/sparql/mixins/solution_lang_filter.rb | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/goo.rb b/lib/goo.rb index fedae62e..cf7267ce 100644 --- a/lib/goo.rb +++ b/lib/goo.rb @@ -26,7 +26,9 @@ module Goo @@resource_options = Set.new([:persistent]).freeze # Define the languages from which the properties values will be taken + # It choose the first language that match otherwise return all the values @@main_languages = %w[en] + @@configure_flag = false @@sparql_backends = {} @@model_by_name = {} diff --git a/lib/goo/sparql/mixins/solution_lang_filter.rb b/lib/goo/sparql/mixins/solution_lang_filter.rb index af02b44a..f2bcc4ae 100644 --- a/lib/goo/sparql/mixins/solution_lang_filter.rb +++ b/lib/goo/sparql/mixins/solution_lang_filter.rb @@ -38,8 +38,12 @@ def languages_values_to_set(language_values, no_lang_values) matched_lang, not_matched_lang = matched_languages(language_values, no_lang_values) if !matched_lang.empty? main_lang = Array(matched_lang[:'0']) + Array(matched_lang[:no_lang]) - secondary_languages = matched_lang.select { |key| key != :'0' && key != :no_lang }.sort.map { |x| x[1] }.flatten - values = main_lang + secondary_languages + if main_lang.empty? + secondary_languages = matched_lang.select { |key| key != :'0' && key != :no_lang }.sort.map { |x| x[1] } + values = secondary_languages.first + else + values = main_lang + end elsif !not_matched_lang.empty? values = not_matched_lang end From ba27011fd2b093ff04d522477010d146602d0b62 Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Fri, 18 Mar 2022 18:45:17 +0100 Subject: [PATCH 7/9] add the condition of nil? or empty? before adding the no_lang --- lib/goo/sparql/mixins/solution_lang_filter.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/goo/sparql/mixins/solution_lang_filter.rb b/lib/goo/sparql/mixins/solution_lang_filter.rb index f2bcc4ae..9f0a5568 100644 --- a/lib/goo/sparql/mixins/solution_lang_filter.rb +++ b/lib/goo/sparql/mixins/solution_lang_filter.rb @@ -78,7 +78,9 @@ def save_other_lang_val(id, attr, index, value) def matched_languages(index_values, model_attribute_val) not_matched_lang = index_values[:not_matched] matched_lang = index_values.reject { |key| key == :not_matched } - matched_lang[:no_lang] = Array(model_attribute_val) unless model_attribute_val.nil? + unless model_attribute_val.nil? || model_attribute_val.empty? + matched_lang[:no_lang] = Array(model_attribute_val) + end [matched_lang, not_matched_lang] end end From c7106bd6bb6d602b1aff30447ee34691f5f9984d Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Mon, 16 May 2022 10:54:16 +0200 Subject: [PATCH 8/9] uniquify the language values --- lib/goo/sparql/mixins/solution_lang_filter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/goo/sparql/mixins/solution_lang_filter.rb b/lib/goo/sparql/mixins/solution_lang_filter.rb index 9f0a5568..fb4d116b 100644 --- a/lib/goo/sparql/mixins/solution_lang_filter.rb +++ b/lib/goo/sparql/mixins/solution_lang_filter.rb @@ -47,7 +47,7 @@ def languages_values_to_set(language_values, no_lang_values) elsif !not_matched_lang.empty? values = not_matched_lang end - values + values&.uniq end private From 34a9fdfed3b79e5b796af154ff7407bf63d3411f Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Wed, 23 Nov 2022 09:34:58 +0100 Subject: [PATCH 9/9] force attribute values with lang to be Array --- lib/goo/sparql/mixins/solution_lang_filter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/goo/sparql/mixins/solution_lang_filter.rb b/lib/goo/sparql/mixins/solution_lang_filter.rb index fb4d116b..4fb12292 100644 --- a/lib/goo/sparql/mixins/solution_lang_filter.rb +++ b/lib/goo/sparql/mixins/solution_lang_filter.rb @@ -78,7 +78,7 @@ def save_other_lang_val(id, attr, index, value) def matched_languages(index_values, model_attribute_val) not_matched_lang = index_values[:not_matched] matched_lang = index_values.reject { |key| key == :not_matched } - unless model_attribute_val.nil? || model_attribute_val.empty? + unless model_attribute_val.nil? || Array(model_attribute_val).empty? matched_lang[:no_lang] = Array(model_attribute_val) end [matched_lang, not_matched_lang]