Class: ConceptQL::Operators::Operator
- Inherits:
-
Object
- Object
- ConceptQL::Operators::Operator
show all
- Extended by:
- Metadatable, Forwardable
- Defined in:
- lib/conceptql/operators/operator.rb
Direct Known Subclasses
BinaryOperatorOperator, CastingOperator, ConcurrentWithin, ConditionType, DateRange, DrugTypeConcept, From, FromSeerVisits, Gender, Invalid, Occurrence, OneInTwoOut, PassThru, PlaceOfServiceCode, PlaceOfServiceFilter, Provenance, ProviderFilter, Race, Read, Recall, TimeWindow, ToSeerVisits, VocabularyOperator
Class Attribute Summary collapse
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
allows_many_upstreams, allows_one_upstream, argument, auto_label, basic_type, category, derive_metadata_from_validations, desc, get_desc, humanized_class_name, inherited, just_class_name, no_desc, option, predominant_domains, pref_name, preferred_name, reset_categories, standard_description, to_metadata, validate_at_least_one_upstream_to_metadata, validate_at_most_one_upstream_to_metadata, validate_no_arguments_to_metadata, validate_no_upstreams_to_metadata, validate_one_upstream_to_metadata, validate_required_options_to_metadata, warn_about_missing_metadata
Constructor Details
#initialize(nodifier, *args) ⇒ Operator
Returns a new instance of Operator.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/conceptql/operators/operator.rb', line 153
def initialize(nodifier, *args)
@nodifier = nodifier
@options = {}
while args.last.is_a?(Hash)
@options = @options.merge(args..deep_rekey)
end
args.reject!{|arg| arg.nil? || arg == ''}
@upstreams, @arguments = args.partition { |arg| arg.is_a?(Array) || arg.is_a?(Operator) }
@values = args
scope.nest(self) do
create_upstreams
end
end
|
Class Attribute Details
.codes_regexp ⇒ Object
Returns the value of attribute codes_regexp.
81
82
83
|
# File 'lib/conceptql/operators/operator.rb', line 81
def codes_regexp
@codes_regexp
end
|
.required_columns ⇒ Object
Returns the value of attribute required_columns.
81
82
83
|
# File 'lib/conceptql/operators/operator.rb', line 81
def required_columns
@required_columns
end
|
.validations ⇒ Object
Returns the value of attribute validations.
81
82
83
|
# File 'lib/conceptql/operators/operator.rb', line 81
def validations
@validations
end
|
Instance Attribute Details
#arguments ⇒ Object
Returns the value of attribute arguments.
74
75
76
|
# File 'lib/conceptql/operators/operator.rb', line 74
def arguments
@arguments
end
|
#errors ⇒ Object
Returns the value of attribute errors.
313
314
315
|
# File 'lib/conceptql/operators/operator.rb', line 313
def errors
@errors
end
|
#nodifier ⇒ Object
Returns the value of attribute nodifier.
74
75
76
|
# File 'lib/conceptql/operators/operator.rb', line 74
def nodifier
@nodifier
end
|
#options ⇒ Object
Returns the value of attribute options.
74
75
76
|
# File 'lib/conceptql/operators/operator.rb', line 74
def options
@options
end
|
#upstreams ⇒ Object
Returns the value of attribute upstreams.
74
75
76
|
# File 'lib/conceptql/operators/operator.rb', line 74
def upstreams
@upstreams
end
|
#values ⇒ Object
Returns the value of attribute values.
74
75
76
|
# File 'lib/conceptql/operators/operator.rb', line 74
def values
@values
end
|
Class Method Details
.codes_should_match(format) ⇒ Object
128
129
130
131
|
# File 'lib/conceptql/operators/operator.rb', line 128
def codes_should_match(format)
@codes_regexp = format
validate_codes_match
end
|
.default_query_columns ⇒ Object
96
97
98
99
100
|
# File 'lib/conceptql/operators/operator.rb', line 96
def default_query_columns
define_method(:query_cols) do
dynamic_columns
end
end
|
.inherited(subclass) ⇒ Object
133
134
135
136
137
|
# File 'lib/conceptql/operators/operator.rb', line 133
def inherited(subclass)
super
subclass.instance_variable_set(:@validations, validations.dup)
subclass.instance_variable_set(:@codes_regexp, codes_regexp.dup) if codes_regexp
end
|
.new ⇒ Object
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/conceptql/operators/operator.rb', line 139
def new(*)
operator = super
if operator.label && !operator.errors
operator.scope.add_operator(operator)
operator = Operators::Recall.new(operator.nodifier, operator.label, replaced: true)
end
operator
end
|
.query_columns(*tables) ⇒ Object
90
91
92
93
94
|
# File 'lib/conceptql/operators/operator.rb', line 90
def query_columns(*tables)
define_method(:query_cols) do
table_columns(*tables)
end
end
|
.register(file, *data_models) ⇒ Object
83
84
85
86
87
88
|
# File 'lib/conceptql/operators/operator.rb', line 83
def register(file, *data_models)
data_models = OPERATORS.keys if data_models.empty?
data_models.each do |dm|
OPERATORS[dm][File.basename(file).sub(/\.rb\z/, '')] = self
end
end
|
.require_column(column) ⇒ Object
102
103
104
105
|
# File 'lib/conceptql/operators/operator.rb', line 102
def require_column(column)
@required_columns ||= []
@required_columns << column
end
|
Instance Method Details
#annotate(db, opts = {}) ⇒ Object
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
# File 'lib/conceptql/operators/operator.rb', line 188
def annotate(db, opts = {})
return @annotation if defined?(@annotation)
scope_key = options[:id]||self.class.just_class_name.underscore
annotation = {}
counts = (annotation[:counts] ||= {})
metadata = {:annotation=>annotation}
if name = self.class.preferred_name
metadata[:name] = name
end
res = [operator_name, *annotate_values(db, opts)]
if upstreams_valid?(db, opts) && scope.valid? && include_counts?(db, opts)
scope.with_ctes(evaluate(db), db)
.from_self
.select_group(:criterion_domain)
.select_append{count{}.*.as(:rows)}
.select_append{count(:person_id).distinct.as(:n)}
.each do |h|
counts[h.delete(:criterion_domain).to_sym] = h
end
elsif !errors.empty?
annotation[:errors] = errors
scope.add_errors(scope_key, errors)
end
scope.add_operators(self)
domains(db).each do |domain|
cur_counts = counts[domain] ||= {:rows=>0, :n=>0}
scope.add_counts(scope_key, domain, cur_counts)
end
if defined?(@warnings) && !warnings.empty?
annotation[:warnings] = warnings
scope.add_warnings(scope_key, warnings)
end
if res.last.is_a?(Hash)
res.last.merge!(metadata)
else
res << metadata
end
@annotation = res
end
|
#cast_column(column, value = nil) ⇒ Object
339
340
341
342
343
344
345
346
347
348
349
350
351
|
# File 'lib/conceptql/operators/operator.rb', line 339
def cast_column(column, value = nil)
type = Scope::COLUMN_TYPES.fetch(column)
case type
when String, :String
Sequel.cast_string(value).as(column)
when Date, :Date
Sequel.cast(value, type).as(column)
when Float, :Bigint, :Float
Sequel.cast_numeric(value, type).as(column)
else
raise "Unexpected type: '#{type.inspect}' for column: '#{column}'"
end
end
|
#code_list(db) ⇒ Object
233
234
235
236
237
238
|
# File 'lib/conceptql/operators/operator.rb', line 233
def code_list(db)
code_lists = @upstreams.map do | upstream_op |
upstream_op.code_list(db)
end
code_lists.flatten(1)
end
|
#columns(query, local_domain) ⇒ Object
291
292
293
294
295
296
297
298
299
300
301
302
303
304
|
# File 'lib/conceptql/operators/operator.rb', line 291
def columns(query, local_domain)
criterion_domain = :criterion_domain
if local_domain
criterion_domain = cast_column(:criterion_domain, local_domain.to_s)
end
columns = [:person_id,
domain_id(local_domain),
criterion_domain]
columns += date_columns(query, local_domain)
columns += [ source_value(query, local_domain) ]
columns += additional_columns(query, local_domain)
end
|
#create_upstreams ⇒ Object
168
169
170
|
# File 'lib/conceptql/operators/operator.rb', line 168
def create_upstreams
@upstreams.map!{|stmt| to_op(stmt)}
end
|
#data_model ⇒ Object
331
332
333
|
# File 'lib/conceptql/operators/operator.rb', line 331
def data_model
nodifier.data_model
end
|
#database_type ⇒ Object
335
336
337
|
# File 'lib/conceptql/operators/operator.rb', line 335
def database_type
nodifier.database_type
end
|
#domains(db) ⇒ Object
278
279
280
|
# File 'lib/conceptql/operators/operator.rb', line 278
def domains(db)
@domains ||= determine_domains(db)
end
|
#dup_values(args) ⇒ Object
240
241
242
|
# File 'lib/conceptql/operators/operator.rb', line 240
def dup_values(args)
self.class.new(nodifier, *args)
end
|
#dynamic_columns ⇒ Object
184
185
186
|
# File 'lib/conceptql/operators/operator.rb', line 184
def dynamic_columns
scope.query_columns
end
|
#evaluate(db) ⇒ Object
248
249
250
|
# File 'lib/conceptql/operators/operator.rb', line 248
def evaluate(db)
select_it(query(db))
end
|
#inspect ⇒ Object
244
245
246
|
# File 'lib/conceptql/operators/operator.rb', line 244
def inspect
"<##{self.class} upstreams=[#{upstreams.map(&:inspect).join(', ')}] arguments=[#{arguments.map(&:inspect).join(', ')}]>"
end
|
#label ⇒ Object
306
307
308
309
310
311
|
# File 'lib/conceptql/operators/operator.rb', line 306
def label
@label ||= begin
options.delete(:label) if options[:label] && options[:label].to_s.strip.empty?
options[:label].respond_to?(:strip) ? options[:label].strip : options[:label]
end
end
|
#operator_name ⇒ Object
176
177
178
|
# File 'lib/conceptql/operators/operator.rb', line 176
def operator_name
self.class.just_class_name.underscore
end
|
#optimized ⇒ Object
256
257
258
|
# File 'lib/conceptql/operators/operator.rb', line 256
def optimized
dup_values(values.map{|x| x.is_a?(Operator) ? x.optimized : x})
end
|
#required_columns ⇒ Object
180
181
182
|
# File 'lib/conceptql/operators/operator.rb', line 180
def required_columns
self.class.required_columns
end
|
#scope ⇒ Object
327
328
329
|
# File 'lib/conceptql/operators/operator.rb', line 327
def scope
nodifier.scope
end
|
#select_it(query, specific_domain = nil) ⇒ Object
264
265
266
267
268
269
270
271
272
273
274
275
276
|
# File 'lib/conceptql/operators/operator.rb', line 264
def select_it(query, specific_domain = nil)
if specific_domain.nil? && respond_to?(:domain) && TABLE_COLUMNS.keys.include?(domain)
specific_domain = domain
end
q = setup_select(query, specific_domain)
if scope && scope.person_ids && upstreams.empty?
q = q.where(person_id: scope.person_ids).from_self
end
q
end
|
#setup_select(query, local_domain = nil) ⇒ Object
286
287
288
289
|
# File 'lib/conceptql/operators/operator.rb', line 286
def setup_select(query, local_domain = nil)
query = modify_query(query, local_domain)
query.select(*columns(query, local_domain))
end
|
#sql(db) ⇒ Object
252
253
254
|
# File 'lib/conceptql/operators/operator.rb', line 252
def sql(db)
evaluate(db).sql
end
|
#stream ⇒ Object
282
283
284
|
# File 'lib/conceptql/operators/operator.rb', line 282
def stream
@stream ||= upstreams.first
end
|
#to_op(stmt) ⇒ Object
172
173
174
|
# File 'lib/conceptql/operators/operator.rb', line 172
def to_op(stmt)
stmt.is_a?(Operator) ? stmt : nodifier.create(*stmt)
end
|
#unionable?(other) ⇒ Boolean
260
261
262
|
# File 'lib/conceptql/operators/operator.rb', line 260
def unionable?(other)
false
end
|
#upstreams_valid?(db, opts = {}) ⇒ Boolean
323
324
325
|
# File 'lib/conceptql/operators/operator.rb', line 323
def upstreams_valid?(db, opts = {})
valid?(db, opts) && upstreams.all?{|u| u.upstreams_valid?(db, opts)}
end
|
#valid?(db, opts = {}) ⇒ Boolean
315
316
317
318
319
320
321
|
# File 'lib/conceptql/operators/operator.rb', line 315
def valid?(db, opts = {})
return @errors.empty? if defined?(@errors)
@errors = []
@warnings = []
validate(db, opts)
errors.empty?
end
|