Class: Activecube::Graphql::ResponseBuilder::ResponseClassRegistry

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/activecube/graphql/response_builder.rb

Instance Method Summary collapse

Constructor Details

#initializeResponseClassRegistry

Returns a new instance of ResponseClassRegistry.



31
32
33
# File 'lib/activecube/graphql/response_builder.rb', line 31

def initialize
  @registry = {}
end

Instance Method Details

#array_value(response_class, definition, element, key_map) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/activecube/graphql/response_builder.rb', line 111

def array_value response_class, definition, element, key_map
  index = key_map[element.key]
  array_element_type = if element.children.empty?
                         element.type_name
                       else
                         tuple = element.metric.definition.class.tuple
                         element.children.collect{|a| [ a.name, a.type_name, tuple.index(a.name.to_sym)]  }
                       end

  response_class.class_eval do
    define_method definition.underscore do |**rest_of_options|
      @row[index].map{|array_obj|
        if array_obj.kind_of?(Array) && array_element_type.kind_of?(Array)
          Hash[
            array_element_type.map{|etype|
              [etype.first.underscore, convert_type(etype.second, array_obj[etype.third])]
            }]
        elsif !array_obj.kind_of?(Array) && array_element_type.kind_of?(String)
          convert_type(array_element_type, obj)
        else
          raise "Mismatched data in #{array_obj} with #{array_element_type} for #{definition} of #{element.key}"
        end
      }
    end
  end


end

#build_response_class(from_element, key_map) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/activecube/graphql/response_builder.rb', line 40

def build_response_class from_element, key_map

  response_class = Class.new Response

  from_element.children.group_by(&:definition).each{|definition, elements|

    if elements.count==1
      element = elements.first
      if element.children.empty?
        simple_value response_class, definition, element, key_map
      elsif element.metric
        array_value response_class, definition, element, key_map
      else
        sub_element response_class, definition, element, key_map
      end
    else
      match_elements response_class, definition, elements, key_map
    end

  }

  response_class

end

#get_response_class(element, key_map) ⇒ Object



35
36
37
38
# File 'lib/activecube/graphql/response_builder.rb', line 35

def get_response_class element, key_map
  key = element.to_json + key_map.to_json
  @registry[key] ||= build_response_class(element,key_map)
end

#match_elements(response_class, definition, elements, key_map) ⇒ Object



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
# File 'lib/activecube/graphql/response_builder.rb', line 66

def match_elements response_class, definition, elements, key_map

  index = Hash[elements.collect { |element|
    value = if element.children.empty?
              [key_map[element.key], element.type_name]
            else
              get_response_class element, key_map
            end
    [element.name, value]
  }]

  response_class.class_eval do
    define_method definition.underscore do |ast_node:, **rest_of_options|
      key = ast_node.alias || ast_node.name
      if (value = index[key]).kind_of? Class
        value.new @row
      elsif value.kind_of? Array
        convert_type value.second, @row[value.first]
      else
        raise Activecube::InputArgumentError, "Unexpected request to #{definition} by key #{key}"
      end
    end
  end

end

#simple_value(response_class, definition, element, key_map) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/activecube/graphql/response_builder.rb', line 101

def simple_value response_class, definition, element, key_map
  index = key_map[element.key]
  type_name = element.type_name
  response_class.class_eval do
    define_method definition.underscore do |**rest_of_options|
      convert_type type_name, @row[index]
    end
  end
end

#sub_element(response_class, definition, element, key_map) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/activecube/graphql/response_builder.rb', line 92

def sub_element response_class, definition, element, key_map
  subclass = get_response_class element, key_map
  response_class.class_eval do
    define_method definition.underscore do |**rest_of_options|
      subclass.new @row
    end
  end
end