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_steps, #build_variables, #source

Constructor Details

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

Returns a new instance of PresenceConstraint.



184
185
186
187
188
# File 'lib/activefacts/cql/compiler/constraint.rb', line 184

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



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/activefacts/cql/compiler/constraint.rb', line 238

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
        debug :binding, "Rebinding #{ref.inspect} to #{candidates[0].inspect} in presence constraint"
        ref.rebind_to(@context, candidates[0])
      end
    end
  end
end

#compileObject



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/activefacts/cql/compiler/constraint.rb', line 190

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
    )
  @enforcement.compile(@constellation, @constraint) if @enforcement
	  debug :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



234
235
236
# File 'lib/activefacts/cql/compiler/constraint.rb', line 234

def loose_binding
  # loose_bind_wherever_possible
end

#to_sObject



254
255
256
# File 'lib/activefacts/cql/compiler/constraint.rb', line 254

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