Class: Solis::Graph
- Inherits:
-
Object
- Object
- Solis::Graph
- Defined in:
- lib/solis/graph.rb
Instance Attribute Summary collapse
-
#default_after_create ⇒ Object
Returns the value of attribute default_after_create.
-
#default_after_delete ⇒ Object
Returns the value of attribute default_after_delete.
-
#default_after_read ⇒ Object
Returns the value of attribute default_after_read.
-
#default_after_update ⇒ Object
Returns the value of attribute default_after_update.
-
#default_before_create ⇒ Object
Returns the value of attribute default_before_create.
-
#default_before_delete ⇒ Object
Returns the value of attribute default_before_delete.
-
#default_before_read ⇒ Object
Returns the value of attribute default_before_read.
-
#default_before_update ⇒ Object
Returns the value of attribute default_before_update.
-
#options ⇒ Object
Returns the value of attribute options.
Instance Method Summary collapse
- #flush_all(graph_name = nil, force = false) ⇒ Object
-
#initialize(graph, options = {}) ⇒ Graph
constructor
A new instance of Graph.
- #jsonapi_schema ⇒ Object
- #list_shapes ⇒ Object
- #shape?(key) ⇒ Boolean
- #shape_as_model(shape_name) ⇒ Object
- #shape_as_resource(shape_name, stack_level = []) ⇒ Object
Constructor Details
#initialize(graph, options = {}) ⇒ Graph
Returns a new instance of Graph.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/solis/graph.rb', line 15 def initialize(graph, = {}) raise "Please provide a graph_name, graph_prefix and sparql_endpoint option" if .nil? || .empty? = .clone Solis::Options.instance.set = @global_resource_stack = [] @graph = graph @graph_name = .delete(:graph_name) || '/' @graph_prefix = .delete(:graph_prefix) || 'pf0' @sparql_endpoint = .delete(:sparql_endpoint) || nil if &.key?(:hooks) && [:hooks].is_a?(Hash) hooks = [:hooks] if hooks.key?(:read) if hooks[:read].key?(:before) @default_before_read = hooks[:read][:before] end if hooks[:read].key?(:after) @default_after_read = hooks[:read][:after] end end if hooks.key?(:create) if hooks[:create].key?(:before) @default_before_create = hooks[:create][:before] end if hooks[:create].key?(:after) @default_after_create = hooks[:create][:after] end end if hooks.key?(:update) if hooks[:update].key?(:before) @default_before_update = hooks[:update][:before] end if hooks[:update].key?(:after) @default_after_update = hooks[:update][:after] end end if hooks.key?(:delete) if hooks[:delete].key?(:before) @default_before_delete = hooks[:delete][:before] end if hooks[:delete].key?(:after) @default_after_delete = hooks[:delete][:after] end end end unless @sparql_endpoint.nil? uri = URI.parse(@sparql_endpoint) @sparql_endpoint = RDF::Repository.new(uri: RDF::URI(@graph_name), title: uri.host) if uri.scheme.eql?('repository') end @inflections = .delete(:inflections) || nil @shapes = Solis::Shape.from_graph(graph) @language = .delete(:language) || 'en' unless @inflections.nil? raise "Inflection file not found #{File.absolute_path(@inflections)}" unless File.exist?(@inflections) JSON.parse(File.read(@inflections)).each do |s, p| raise "No plural found" if s.nil? && p.nil? raise "No plural found for #{p}" if s.nil? raise "No plural found for #{s}" if p.nil? ActiveSupport::Inflector.inflections.irregular(s, p) end end @shape_tree = {} shape_keys = @shapes.map do |shape_name, _| if shape_name.empty? LOGGER.warn("Dangling entity found #{_[:target_class].to_s} removing") next end #@shapes[shape_name][:attributes].select { |_, metadata| metadata.key?(:node_kind) && !metadata[:node_kind].nil? }.values.map { |m| m[:datatype].to_s.split('#').last } @shapes[shape_name][:attributes].select { |_, | .key?(:node_kind) && ![:node_kind].nil? }.values.map { |m| m[:datatype].to_s } end shape_keys += @shapes.keys shape_keys = shape_keys.flatten.compact.sort.uniq shape_keys.each do |shape_name| d = @shape_tree.key?(shape_name) ? @shape_tree[shape_name] : 0 d += 1 @shape_tree[shape_name] = d end @shape_tree = @shape_tree.sort_by(&:last).reverse.to_h shape_keys.each do |s| shape_as_model(s) end @shape_tree.each do |shape_name, _| shape_as_resource(shape_name) end Graphiti.configure do |config| config.pagination_links = true config.context_for_endpoint= ->(path, action) { Solis::NoopEndpoint.new(path, action) } end Graphiti.setup! end |
Instance Attribute Details
#default_after_create ⇒ Object
Returns the value of attribute default_after_create.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_after_create @default_after_create end |
#default_after_delete ⇒ Object
Returns the value of attribute default_after_delete.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_after_delete @default_after_delete end |
#default_after_read ⇒ Object
Returns the value of attribute default_after_read.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_after_read @default_after_read end |
#default_after_update ⇒ Object
Returns the value of attribute default_after_update.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_after_update @default_after_update end |
#default_before_create ⇒ Object
Returns the value of attribute default_before_create.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_before_create @default_before_create end |
#default_before_delete ⇒ Object
Returns the value of attribute default_before_delete.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_before_delete @default_before_delete end |
#default_before_read ⇒ Object
Returns the value of attribute default_before_read.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_before_read @default_before_read end |
#default_before_update ⇒ Object
Returns the value of attribute default_before_update.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def default_before_update @default_before_update end |
#options ⇒ Object
Returns the value of attribute options.
13 14 15 |
# File 'lib/solis/graph.rb', line 13 def @options end |
Instance Method Details
#flush_all(graph_name = nil, force = false) ⇒ Object
350 351 352 353 354 355 356 357 |
# File 'lib/solis/graph.rb', line 350 def flush_all(graph_name=nil, force = false) raise Solis::Error::NotFoundError, "Supplied graph_name '#{graph_name}' does not equal graph name defined in config file '#{@graph_name}', set force to true" unless graph_name.eql?(@graph_name) && !force @sparql_client = SPARQL::Client.new(@sparql_endpoint) result = @sparql_client.query("with <#{graph_name}> delete {?s ?p ?o} where{?s ?p ?o}") LOGGER.info(result) true end |
#jsonapi_schema ⇒ Object
135 136 137 |
# File 'lib/solis/graph.rb', line 135 def jsonapi_schema Graphiti::Schema.generate.to_json end |
#list_shapes ⇒ Object
127 128 129 |
# File 'lib/solis/graph.rb', line 127 def list_shapes @shapes.keys.sort end |
#shape?(key) ⇒ Boolean
131 132 133 |
# File 'lib/solis/graph.rb', line 131 def shape?(key) @shapes.key?(key) end |
#shape_as_model(shape_name) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/solis/graph.rb', line 139 def shape_as_model(shape_name) raise Solis::Error::NotFoundError, "'#{shape_name}' not found. Available classes are #{list_shapes.join(', ')}" unless shape?(shape_name) return Object.const_get(shape_name) if Object.const_defined?(shape_name) LOGGER.info("Creating model #{shape_name}") attributes = @shapes[shape_name][:attributes].keys.map { |m| m.to_sym } model = nil parent_model = nil if @shapes[shape_name].key?(:target_node) && @shapes[shape_name][:target_node].value =~ /^#{@graph_name}(.*)Shape$/ parent_shape_model = $1 parent_model = shape_as_model(parent_shape_model) model = Object.const_set(shape_name, ::Class.new(parent_model) do attr_accessor(*attributes) end) else model = Object.const_set(shape_name, ::Class.new(Solis::Model) do attr_accessor(*attributes) end) end model.graph_name = @graph_name model.graph_prefix = @graph_prefix model.shapes = @shapes model. = @shapes[shape_name] #model.language = Graphiti.context[:object]&.language || Solis::Options.instance.get[:language] || @language || 'en' unless parent_model.nil? parent_model.[:attributes].each do |k, v| unless model.[:attributes].key?(k) model.[:attributes][k] = v end end end model.sparql_endpoint = @sparql_endpoint model.graph = self model.model_before_read do |original_class| @default_before_read.call(original_class) end if @default_before_read model.model_after_read do |persisted_class| @default_after_read.call(persisted_class) end if @default_after_read model.model_before_create do |original_class| @default_before_create.call(original_class) end if @default_before_create model.model_after_create do |persisted_class| @default_after_create.call(persisted_class) end if @default_after_create model.model_before_update do |original_class, updated_class| @default_before_update.call(original_class, updated_class) end if @default_before_update model.model_after_update do |updated_class, persisted_class| @default_after_update.call(updated_class, persisted_class) end if @default_after_update model.model_before_delete do |updated_class| @default_before_delete.call(updated_class) end if @default_before_delete model.model_after_delete do |persisted_class| @default_after_delete.call(persisted_class) end if @default_after_delete model end |
#shape_as_resource(shape_name, stack_level = []) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/solis/graph.rb', line 211 def shape_as_resource(shape_name, stack_level = []) model = shape_as_model(shape_name) resource_name = "#{shape_name}Resource" raise Solis::Error::NotFoundError, "#{shape_name} not found. Available classes are #{list_shapes.join(', ')}" unless shape?(shape_name) return Object.const_get(resource_name) if Object.const_defined?(resource_name) LOGGER.info("Creating resource #{resource_name}") attributes = @shapes[shape_name][:attributes].select { |_, | .key?(:node_kind) && [:node_kind].nil? } relations = @shapes[shape_name][:attributes].select { |_, | .key?(:node_kind) && ![:node_kind].nil? } @global_resource_stack << resource_name relations.each_key do |k| next if relations[k][:node_kind].is_a?(RDF::URI) && relations[k][:class].value.gsub(@graph_name, '').gsub('Shape', '').eql?(shape_name) relation_shape = relations[k][:class].value.gsub(@graph_name, '').gsub('Shape', '') if relation_shape =~ /\// relation_shape = relations[k][:class].value.split('/').last.gsub('Shape','') end shape_as_resource(relation_shape, stack_level << relation_shape) unless stack_level.include?(relation_shape) end description = @shapes[shape_name][:comment] parent_resource = Resource descendants = ObjectSpace.each_object(Class).select { |klass| klass < model }.map { |m| "#{m.to_s}Resource" } graph = self #Resource if Object.const_defined?(resource_name) resource = Object.const_get(resource_name) else ################### # Define new resource resource = Object.const_set(resource_name, ::Class.new(Resource) do if descendants.length > 0 self.polymorphic = descendants self.polymorphic << resource_name self.polymorphic.uniq! end self.model = model self.type = model.name.demodulize.underscore.pluralize.to_sym self.description = description attributes.each do |key, | next if key.nil? || key.empty? if key.eql?('id') attribute key.to_sym, :uuid, description: [:comment] else if ([:maxcount] && [:maxcount] > 1 || [:maxcount].nil?) && ![:boolean, :hash, :array].include?([:datatype]) datatype = "array_of_#{[:datatype]}s".to_sym else datatype = [:datatype] end LOGGER.info "\t#{resource_name}.#{key}(#{datatype})" attribute key.to_sym, datatype, description: [:comment] end end end) relations.each do |key, value| # next if value[:datatype].to_s.classify.eql?(shape_name) #why skip self relations... if (value[:mincount] && value[:mincount] > 1 || value[:mincount].nil?) || (value[:maxcount] && value[:maxcount] > 1 || value[:maxcount].nil?) belongs_to_resource_name = value[:datatype].nil? ? value[:class].value.gsub(self.model.graph_name, '') : value[:datatype].to_s.tableize.classify LOGGER.info "\t\t\t#{resource_name}(#{resource_name.gsub('Resource','').tableize.singularize}) belongs_to #{belongs_to_resource_name}(#{key})" resource.belongs_to(key.to_sym, foreign_key: :id, resource: graph.shape_as_resource("#{belongs_to_resource_name}", stack_level << belongs_to_resource_name)) do #resource.attribute key.to_sym, :string, only: [:filterable] link do |resource| remote_resources = resource.instance_variable_get("@#{key}") if remote_resources remote_resources = [remote_resources] unless remote_resources.is_a?(Array) resource_ids = remote_resources.map do |remote_resource| remote_resource.id =~ /^http/ ? remote_resource.id.split('/').last : remote_resource.id end end "#{resource.class.graph_name.gsub(/\/$/,'')}/#{belongs_to_resource_name.tableize}?filter[id]=#{resource_ids.join(',')}" unless remote_resources.nil? || resource_ids.empty? end end else has_many_resource_name = value[:datatype].nil? ? value[:class].gsub(self.model.graph_name, '') : value[:datatype].to_s.classify LOGGER.info "\t\t\t#{resource_name}(#{resource_name.gsub('Resource','').tableize.singularize}) has_many #{has_many_resource_name}(#{key})" resource.has_many(key.to_sym, foreign_key: :id, primary_key: :id, resource: graph.shape_as_resource("#{has_many_resource_name}", stack_level << has_many_resource_name)) do belongs_to_resource = graph.shape_as_resource("#{has_many_resource_name}") belongs_to_resource.belongs_to(resource.model.name.tableize.singularize, foreign_key: :id, primary_key: :id, resource: graph.shape_as_resource(resource.model.name)) do link do |resource| ids=[] remote_resources = resource.instance_variable_get("@#{shape_name.tableize.singularize}") if remote_resources remote_resources = [remote_resources] unless remote_resources.is_a?(Array) resource_ids = remote_resources.map do |remote_resource| remote_resource.id =~ /^http/ ? remote_resource.id.split('/').last : remote_resource.id end end #"#{resource.class.graph_name.gsub(/\/$/,'')}/#{belongs_to_resource.name.tableize}?filter[id]=#{resource_ids.join(',')}" unless remote_resources.nil? || resource_ids.empty? "#{resource.class.graph_name.gsub(/\/$/,'')}/#{remote_resources.first.name.tableize}?filter[id]=#{resource_ids.join(',')}" unless remote_resources.nil? || resource_ids.empty? end end # link do |resource| remote_resources = resource.instance_variable_get("@#{key}") if remote_resources remote_resources = [remote_resources] unless remote_resources.is_a?(Array) resource_ids = remote_resources.map do |remote_resource| remote_resource.id =~ /^http/ ? remote_resource.id.split('/').last : remote_resource.id end end "#{resource.class.graph_name.gsub(/\/$/,'')}/#{remote_resources.first.name.tableize}?filter[id]=#{resource_ids.join(',')}" unless remote_resources.nil? || resource_ids.empty? end end end resource.filter :"#{key}_id", :string, single: true, only: [:eq, :not_eq] do eq do |scope, filter_value| scope[:filters][key.to_sym] = filter_value scope end not_eq do |scope, filter_value| scope[:filters][key.to_sym] = {value: [filter_value], operator: '=', is_not: true} scope end end end end resource.sparql_endpoint = @sparql_endpoint resource.endpoint_namespace = "#{resource.model.graph_name.gsub(/\/$/,'')}#{Solis::Options.instance.get[:base_path]}" resource end |