Class: ActiveFacts::CQL::Compiler::PresenceConstraint

Inherits:
Constraint show all
Defined in:
lib/activefacts/cql/compiler/constraint.rb

Instance Attribute Summary

Attributes inherited from Definition

#constellation, #tree, #vocabulary

Instance Method Summary collapse

Methods inherited from Constraint

#bind_clauses, #common_bindings, #loose_bind, #loose_bind_wherever_possible, #warn_ignored_queries

Methods inherited from Definition

#all_bindings_in_clauses, #build_all_steps, #build_step, #build_variables, #source

Constructor Details

#initialize(context_note, enforcement, clauses_lists, refs, quantifier) ⇒ PresenceConstraint

Returns a new instance of PresenceConstraint.



192
193
194
195
196
# File 'lib/activefacts/cql/compiler/constraint.rb', line 192

def initialize context_note, enforcement, clauses_lists, refs, quantifier
  super context_note, enforcement, clauses_lists
  @refs = refs || []
  @quantifier = quantifier
end

Instance Method Details

#bind_constrained_rolesObject



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/activefacts/cql/compiler/constraint.rb', line 251

def bind_constrained_roles
  @refs.each do |ref|
    if ref.binding.refs.size == 1
      # Apply loose binding over the constrained roles
      candidates =
        @clauses.map do |clause|
          clause.refs.select{ |vr| vr.player == ref.player }
        end.flatten
      if candidates.size == 1
        trace :binding, "Rebinding #{ref.inspect} to #{candidates[0].inspect} in presence constraint"
        ref.rebind_to(@context, candidates[0])
      end
    end
  end
end

#compileObject



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
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/activefacts/cql/compiler/constraint.rb', line 198

def compile
  @clauses = @clauses_lists.map do |clauses_list|
    raise "REVISIT: join presence constraints not supported yet" if clauses_list.size > 1 or
      clauses_list.detect{|clause| clause.refs.detect{|vr| vr.nested_clauses } }
    clauses_list[0]
  end

  bind_clauses @refs

  if @refs.size > 0
    bind_constrained_roles
  else
    cb = common_bindings
    raise "Either/or must have only one duplicated role, not #{cb.inspect}" unless cb.size == 1
    @refs = cb[0].refs.reverse # REVISIT: Should have order these by clause, not like this
  end

  role_sequence = @constellation.RoleSequence(:new)
  @refs.each do |ref|
    raise "The constrained role #{ref.inspect} was not found in the invoked fact types" if ref.binding.refs.size == 1
    (ref.binding.refs-[ref]).each do |ref|
      role = (ref.role_ref && ref.role_ref.role) || ref.role
      raise "FactType role not found for #{ref.inspect}" unless role
      @constellation.RoleRef(role_sequence, role_sequence.all_role_ref.size, :role => role)
    end
  end

  @constraint =
    @constellation.PresenceConstraint(
      :new,
      :name => '',
      :vocabulary => @vocabulary,
      :role_sequence => role_sequence,
      :min_frequency => @quantifier.min,
      :max_frequency => @quantifier.max,
      :is_preferred_identifier => false,
      :is_mandatory => @quantifier.min && @quantifier.min > 0
    )
  if @quantifier.pragmas
    @quantifier.pragmas.each do |p|
      @constellation.ConceptAnnotation(:concept => @constraint.concept, :mapping_annotation => p)
    end
  end
  @enforcement.compile(@constellation, @constraint) if @enforcement
  trace :constraint, "Made new PC GUID=#{@constraint.concept.guid} min=#{@quantifier.min.inspect} max=#{@quantifier.max.inspect} over #{role_sequence.describe}"
  super
end

#loose_bindingObject

In a PresenceConstraint, each role in “each XYZ” must occur in exactly one clauses_list



247
248
249
# File 'lib/activefacts/cql/compiler/constraint.rb', line 247

def loose_binding
  # loose_bind_wherever_possible
end

#to_sObject



267
268
269
# File 'lib/activefacts/cql/compiler/constraint.rb', line 267

def to_s
  "#{super} #{@quantifier.min}-#{@quantifier.max} over (#{@refs.map{|vr| vr.inspect}*', '})"
end