Class: ActiveFacts::CQL::Compiler::Definition

Inherits:
Object
  • Object
show all
Defined in:
lib/activefacts/cql/compiler/query.rb,
lib/activefacts/cql/compiler/shared.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#constellationObject

Returns the value of attribute constellation.



99
100
101
# File 'lib/activefacts/cql/compiler/shared.rb', line 99

def constellation
  @constellation
end

#treeObject

Returns the value of attribute tree.



99
100
101
# File 'lib/activefacts/cql/compiler/shared.rb', line 99

def tree
  @tree
end

#vocabularyObject

Returns the value of attribute vocabulary.



99
100
101
# File 'lib/activefacts/cql/compiler/shared.rb', line 99

def vocabulary
  @vocabulary
end

Instance Method Details

#all_bindings_in_clauses(clauses) ⇒ Object

Return the unique array of all bindings in these clauses, including in objectification steps



97
98
99
100
101
102
103
104
105
106
# File 'lib/activefacts/cql/compiler/query.rb', line 97

def all_bindings_in_clauses clauses
  clauses.map do |clause|
    clause.refs.map do |ref|
      raise "Binding reference #{ref.inspect} is not bound to a binding" unless ref.binding
      [ref.binding] + (ref.nested_clauses ? all_bindings_in_clauses(ref.nested_clauses) : [])
    end
  end.
    flatten.
    uniq
end

#build_all_steps(query, clauses_list) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/activefacts/cql/compiler/query.rb', line 29

def build_all_steps(query, clauses_list)
  roles_by_binding = {}
  trace :query, "Building steps" do
    clauses_list.each do |clause|
      build_step(query, clause, roles_by_binding)
    end
  end
  roles_by_binding
end

#build_step(query, clause, roles_by_binding = {}, parent_variable = nil) ⇒ Object



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
# File 'lib/activefacts/cql/compiler/query.rb', line 39

def build_step query, clause, roles_by_binding = {}, parent_variable = nil
  return unless clause.refs.size > 0  # Empty clause... really?

  step = @constellation.Step(
      query, query.all_step.size,
      :fact_type => clause.fact_type,
      :alternative_set => nil,
      :is_disallowed => clause.certainty == false,
      :is_optional => clause.certainty == nil
    )

  trace :query, "Creating Plays for #{clause.inspect} with #{clause.refs.size} refs" do
    is_input = true
    clause.refs.each do |ref|
      # These refs are the Compiler::References, which have associated Metamodel::RoleRefs,
      # but we need to create Plays for those roles.
      # REVISIT: Plays may need to save residual_adjectives
      binding = ref.binding
      role = (ref && ref.role) || (ref.role_ref && ref.role_ref.role)

      objectification_step = nil
      if ref.nested_clauses
        ref.nested_clauses.each do |nested_clause|
          objectification_step = build_step(query, nested_clause, roles_by_binding)
          if ref.binding.player.is_a?(ActiveFacts::Metamodel::EntityType) and
              ref.binding.player.fact_type == nested_clause.fact_type
            objectification_step.objectification_variable = binding.variable
          end
        end
      end
      if clause.is_naked_object_type
        raise "#{self} lacks a proper objectification" if clause.refs[0].nested_clauses and !objectification_step
        return objectification_step
      end

      if binding.variable.object_type != role.object_type         # Type mismatch
        if binding.variable.object_type.common_supertype(role.object_type)
          # REVISIT: there's an implicit subtyping step here, create it; then always raise the error here.
          # I don't want to do this for now because the verbaliser will always verbalise all steps.
          # raise "Disallowing implicit subtyping step from #{role.object_type.name} to #{binding.variable.object_type.name} in #{clause.fact_type.default_reading.inspect}"
        else
          raise "A #{role.object_type.name} cannot satisfy #{binding.variable.object_type.name} in #{clause.fact_type.default_reading.inspect}"
        end
      end

      trace :query, "Creating Play for #{ref.inspect}"
      play = @constellation.Play(:step => step, :role => role, :variable => binding.variable)
      play.is_input = is_input
      is_input = false

      roles_by_binding[binding] = [role, play]
    end
  end

  step
end

#build_variables(clauses_list) ⇒ Object

Make a Variable for every binding present in these clauses



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/activefacts/cql/compiler/query.rb', line 6

def build_variables(clauses_list)
  trace :query, "Building variables" do
    query = @constellation.Query(:new)
    all_bindings_in_clauses(clauses_list).
      each do |binding|
        var_name = (r = binding.refs.select{|r| r.is_a?(Reference)}.first) ? r.var_name : nil
        trace :query, "Creating variable #{query.all_variable.size} for #{binding.inspect} with role_name #{var_name}"
        binding.variable = @constellation.Variable(
          query, query.all_variable.size, :object_type => binding.player, role_name: var_name
        )
        if literal = binding.refs.detect{|r| r.literal}
          if literal.kind_of?(ActiveFacts::CQL::Compiler::Reference)
            # REVISIT: Fix this crappy ad-hoc polymorphism hack
            literal = literal.literal
          end
          unit = @constellation.Unit.detect{|k, v| [v.name, v.plural_name].include? literal.unit} if literal.unit
          binding.variable.value = [literal.literal.to_s, literal.literal.is_a?(String), unit]
        end
      end
    query
  end
end

#compileObject



100
101
102
# File 'lib/activefacts/cql/compiler/shared.rb', line 100

def compile
  raise "#{self.class} should implement the compile method"
end

#sourceObject



108
109
110
# File 'lib/activefacts/cql/compiler/shared.rb', line 108

def source
  @tree.text_value
end

#to_sObject



104
105
106
# File 'lib/activefacts/cql/compiler/shared.rb', line 104

def to_s
  @vocabulary ? "#{vocabulary.to_s}::" : ''
end