Class: Solis::Query
- Inherits:
-
Object
show all
- Includes:
- Enumerable, QueryFilter
- Defined in:
- lib/solis/query.rb,
lib/solis/query/construct.rb
Defined Under Namespace
Classes: Construct, Runner
Class Method Summary
collapse
-
.graph_name ⇒ Object
-
.invalidate_cache_for(model_class_name, cache_dir = nil) ⇒ Object
Invalidate all cached query results for a given model type.
-
.reset_shared_query_cache! ⇒ Object
Reset the shared cache (useful when config changes, e.g., in tests).
-
.run(entity, query, options = {}) ⇒ Object
-
.run_construct(query, id_name, entity, ids, from_cache = '1') ⇒ Object
-
.run_construct_with_file(filename, id_name, entity, ids, from_cache = '1') ⇒ Object
-
.shared_query_cache ⇒ Object
Shared class-level query cache to ensure consistent reads/writes/invalidations.
-
.uuid(key) ⇒ Object
Instance Method Summary
collapse
#filter
Constructor Details
#initialize(model) ⇒ Query
Returns a new instance of Query.
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/solis/query.rb', line 85
def initialize(model)
@construct_cache = File.absolute_path(Solis::Options.instance.get[:cache])
@model = model
@shapes = @model.class.shapes
@metadata = @model.class.metadata
@sparql_endpoint = @model.class.sparql_endpoint
if Solis::Options.instance.get.key?(:graphs) && Solis::Options.instance.get[:graphs].size > 0
@sparql_client = Solis::Store::Sparql::Client.new(@sparql_endpoint)
else
@sparql_client = Solis::Store::Sparql::Client.new(@sparql_endpoint, graph: @model.class.graph_name)
end
@filter = {values: ["VALUES ?type {#{target_class}}"], concepts: ['?concept a ?type .'] }
@sort = 'ORDER BY ?concept'
@sort_select = ''
@language = Graphiti.context[:object]&.language || Solis::Options.instance.get[:language] || 'en'
@query_cache = self.class.shared_query_cache
end
|
Class Method Details
.graph_name ⇒ Object
57
58
59
|
# File 'lib/solis/query.rb', line 57
def self.graph_name
Solis::Options.instance.get.key?(:graphs) ? Solis::Options.instance.get[:graphs].select{|s| s['type'].eql?(:main)}&.first['name'] : ''
end
|
.invalidate_cache_for(model_class_name, cache_dir = nil) ⇒ Object
Invalidate all cached query results for a given model type.
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/solis/query.rb', line 73
def self.invalidate_cache_for(model_class_name, cache_dir = nil)
cache = shared_query_cache
tag_key = "TAG:#{model_class_name}"
if cache.key?(tag_key)
cache[tag_key].each { |key| cache.delete(key) }
cache.delete(tag_key)
Solis::LOGGER.info("CACHE: invalidated entries for #{model_class_name}") if ConfigFile[:debug]
end
rescue StandardError => e
Solis::LOGGER.warn("CACHE: invalidation failed for #{model_class_name}: #{e.message}")
end
|
.reset_shared_query_cache! ⇒ Object
Reset the shared cache (useful when config changes, e.g., in tests)
68
69
70
|
# File 'lib/solis/query.rb', line 68
def self.reset_shared_query_cache!
@shared_query_cache = nil
end
|
.run(entity, query, options = {}) ⇒ Object
14
15
16
|
# File 'lib/solis/query.rb', line 14
def self.run(entity, query, options = {})
Solis::Query::Runner.run(entity, query, options)
end
|
.run_construct(query, id_name, entity, ids, from_cache = '1') ⇒ Object
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
|
# File 'lib/solis/query.rb', line 27
def self.run_construct(query, id_name, entity, ids, from_cache = '1')
raise 'Please supply one or more uuid\'s' if ids.nil? || ids.empty?
result = {}
key = uuid("#{entity}-#{ids}")
if result.nil? || result.empty? || (from_cache.eql?('0'))
ids = ids.split(',') if ids.is_a?(String)
ids = [ids] unless ids.is_a?(Array)
ids = ids.map do |m|
if URI(m).class.eql?(URI::Generic)
"<#{graph_name}#{entity.tableize}/#{m}>"
else
"<#{m}>"
end
end
ids = ids.join(" ")
language = Graphiti.context[:object]&.language || Solis::Options.instance.get[:language] || 'en'
q = query.gsub(/{ ?{ ?VALUES ?} ?}/, "VALUES ?#{id_name} { #{ids} }").gsub(/{ ?{ ?LANGUAGE ?} ?}/, "bind(\"#{language}\" as ?filter_language).").gsub(/{ ?{ ?ENTITY ?} ?}/, "<#{graph_name}#{entity.classify}>")
result = Solis::Query.run(entity, q)
end
result
rescue StandardError => e
puts e.message
raise e
end
|
.run_construct_with_file(filename, id_name, entity, ids, from_cache = '1') ⇒ Object
18
19
20
21
|
# File 'lib/solis/query.rb', line 18
def self.run_construct_with_file(filename, id_name, entity, ids, from_cache = '1')
f = File.read(filename)
run_construct(f, id_name, entity, ids, from_cache)
end
|
.shared_query_cache ⇒ Object
Shared class-level query cache to ensure consistent reads/writes/invalidations
62
63
64
65
|
# File 'lib/solis/query.rb', line 62
def self.shared_query_cache
cache_dir = File.absolute_path(Solis::Options.instance.get[:cache])
@shared_query_cache ||= Moneta.new(:HashFile, dir: cache_dir)
end
|
.uuid(key) ⇒ Object
23
24
25
|
# File 'lib/solis/query.rb', line 23
def self.uuid(key)
UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, key).to_s
end
|
Instance Method Details
#count ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/solis/query.rb', line 144
def count
sparql_client = @sparql_client
if model_construct?
sparql_client = Solis::Query::Construct.new(@model).run
end
relationship = ''
core_query = core_query(relationship)
count_query = core_query.gsub(/SELECT .* WHERE/, 'SELECT (COUNT(distinct ?concept) as ?count) WHERE')
result = sparql_client.query(count_query)
solution = result.first
solution.nil? ? 0 : solution[:count].object || 0
end
|
#each(&block) ⇒ Object
103
104
105
106
107
108
109
110
111
|
# File 'lib/solis/query.rb', line 103
def each(&block)
data = query
return unless data.methods.include?(:each)
data.each(&block)
rescue StandardError => e
message = "Unable to get next record: #{e.message}"
LOGGER.error(message)
raise Error::CursorError, message
end
|
#paging(params = {}) ⇒ Object
134
135
136
137
138
139
140
141
142
|
# File 'lib/solis/query.rb', line 134
def paging(params = {})
current_page = params[:current_page] || 1
per_page = params[:per_page] || 10
@offset = 0
@offset = (current_page - 1) * per_page if current_page > 1
@limit = per_page
self
end
|
#sort(params) ⇒ Object
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/solis/query.rb', line 113
def sort(params)
@sort = ''
@sort_select = ''
if params.key?(:sort)
i = 0
params[:sort].each do |attribute, direction|
path = @model.class.metadata[:attributes][attribute.to_s][:path]
@sort_select += "optional {\n" if @model.class.metadata[:attributes][attribute.to_s][:mincount] == 0
@sort_select += "?concept <#{path}> ?__#{attribute} . "
@sort_select += "}\n" if @model.class.metadata[:attributes][attribute.to_s][:mincount] == 0
@sort += ',' if i.positive?
@sort += "#{direction.to_s.upcase}(?__#{attribute})"
i += 1
end
@sort = "ORDER BY #{@sort}" if i.positive?
end
self
end
|