Module: Superstudio::SchemaInternalDefiner

Included in:
SqlJsonBuilder
Defined in:
lib/superstudio/schema_internal_definer.rb

Instance Method Summary collapse

Instance Method Details

#add_to_describe_arrays(human_route, parent_path, item_path, node_type, depth) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/superstudio/schema_internal_definer.rb', line 96

def add_to_describe_arrays(human_route, parent_path, item_path, node_type, depth)
  @unique_threes_tags << 1  # This isn't a type 3
  @human_readable_tags << human_route
  @depth_tags << (depth - 1)
  item_string = item_path

  if node_type == "string"
    @quoted_tags << 1
  else
    @quoted_tags << 0
  end

  if parent_path.present?
    item_string = "#{parent_path}-#{item_path}"
    @internal_use_tags << item_string
    # Count all of the 4s in the internal string, but remove those that are a count of a type
    # @real_depth_tags << (item_string.scan(/4/).count - item_string.scan(/\.4/).count)
    @real_depth_tags << (item_string.scan(/4./).count)
  else
    @internal_use_tags << item_string
    @real_depth_tags << 0
  end

  if item_string.chr == '3'
    @do_not_hash << 1
  else
    @do_not_hash << 0
  end
end

#convert_fork_paths_to_base_route_numbers(fork_nodes, max_depth) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/superstudio/schema_internal_definer.rb', line 126

def convert_fork_paths_to_base_route_numbers(fork_nodes, max_depth)
  depth_counter = 0
  internal_fork_numbers = {}
  two_at_depth_counter, three_at_depth_counter, four_at_depth_counter, five_at_depth_counter = 0, 0, 0, 0

  while depth_counter <= max_depth
    # two_at_depth_counter, three_at_depth_counter, four_at_depth_counter, five_at_depth_counter = 0, 0, 0, 0
    objects_at_depth = fork_nodes.select {|j| j[:depth] == depth_counter}
    possible_parents = fork_nodes.select {|j| j[:depth] == (depth_counter - 1)}

    objects_at_depth.each do |o|
      if o[:path].join("_B_") == 'root'
        internal_fork_numbers[o[:path]] = { internal_path: '', depth: o[:depth] }
        break
      end

      if @type_2_paths.include?(o[:path])
        two_at_depth_counter += 1
        generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, o, 2, two_at_depth_counter) 
      end

      if @type_4_paths.include?(o[:path])
        four_at_depth_counter += 1
        generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, o, 4, four_at_depth_counter)
      end

      if @type_3_paths.include?(o[:path])
        three_at_depth_counter += 1
        # We also need to check some extra possible parents here. It appears that when a type 3 is first, or possibly 
        # the only child in an object, the object will fail to be accounted for.

        ob = o.dup
        ob[:path] = ob[:path][0..-2]

        if internal_fork_numbers[ob[:path]].nil?

          @type_4_paths.each_with_index do |four_path, idx|
            if four_path.length + 1 == o[:depth]
              possible_parents << { depth: o[:depth] - 1, path: four_path, name: four_path.last, node_type: "array" }
              four_at_depth_counter += 1
              generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, ob, 4, four_at_depth_counter)
            end
          end
        end

        generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, o, 3, three_at_depth_counter)
      end


      if @type_5_paths.include?(o[:path])
        five_at_depth_counter += 1
        generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, o, 5, five_at_depth_counter)
      end
    end

    depth_counter += 1
  end
  return internal_fork_numbers
end

#generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, object_at_depth, type, number) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/superstudio/schema_internal_definer.rb', line 186

def generate_internal_fork_number_of_type(internal_fork_numbers, possible_parents, object_at_depth, type, number)
  parent = nil
  if possible_parents
    possible_parents.each do |pp|
      parent = pp if object_at_depth[:path][0..-2] == pp[:path]
    end
  end
  
  if (type == 2)
    @type_2_indicator_names[number] = object_at_depth[:path].last
  end
  if (type == 4)
    @type_4_indicator_names[number - 1] = object_at_depth[:path].last
  end
  internal_path = ""
  internal_path = "#{internal_fork_numbers[parent[:path]][:internal_path]}" if parent.present?
  
  if parent.present? && parent[:path].join("_B_") != 'root' && internal_fork_numbers[parent[:path]][:internal_path] != ''
    internal_path << "-"
  end
  internal_path << "#{type}.#{number}"
  internal_fork_numbers[object_at_depth[:path]] = { internal_path: internal_path, depth: object_at_depth[:depth] }
end

#handle_array_stop_path(type_already_found, path, internal_use_tag, human_readable_tag, node_type, parent_path, item_path, depth) ⇒ Object



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/superstudio/schema_internal_definer.rb', line 61

def handle_array_stop_path(type_already_found, path, internal_use_tag, human_readable_tag, node_type, parent_path, item_path, depth)
  if type_already_found.include?(path)
    # Do nothing.
  else
    type_already_found << path
    @internal_use_tags << internal_use_tag
    @human_readable_tags << human_readable_tag
  end
  
  if @unique_threes_paths.include?(path)
    @unique_threes_tags << 0
  else
    @unique_threes_tags << 1
  end
  
  if node_type == "string"
    @quoted_tags << 1
  else
    @quoted_tags << 0
  end

  @do_not_hash << 1

  if parent_path.present?
    item_string = "#{parent_path}-#{item_path}"
    # Count all of the 4s in the internal string, but remove those that are a count of a type
    # @real_depth_tags << (item_string.scan(/4/).count - item_string.scan(/\.4/).count)
    @real_depth_tags << (item_string.scan(/4./).count)
  else
    @real_depth_tags << 0
  end

  @depth_tags << (depth - 1)  # going to have to fix - appears too deep for type 3s
end

#set_human_to_internal_mappings(expected_mappings) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/superstudio/schema_internal_definer.rb', line 3

def set_human_to_internal_mappings(expected_mappings)
  fork_nodes = expected_mappings.uniq { |i| i[:path] }
  max_depth = expected_mappings.max_by { |x| x[:depth] }[:depth]
  internal_fork_numbers = convert_fork_paths_to_base_route_numbers(fork_nodes, max_depth)
  depth_counter = 0
  while depth_counter <= max_depth
    # Assign all internal numbers to their respective human-readable forms
    objects_at_depth = expected_mappings.select { |j| j[:depth] == depth_counter }
    forks_at_depth = internal_fork_numbers.select { |k,v| v[:depth] == depth_counter }
    type_5_already_found, type_3_already_found = [], []
    type_1_count, type_3_count, type_5_count = 0, 0, 0

    objects_at_depth.each do |candidate|
      # ex. {depth: 1, path: ["root"], name: "id", node_type: "integer"}

      # This isn't going to work properly for value arrays
      if @type_3_paths.include?(candidate[:path])
        @column_names << candidate[:path].last
      else
        @column_names << candidate[:name]
      end
      # byebug

      forks_at_depth.each do |p|
        if candidate[:path] == p[0]
          # Add the internal path to the internal mapping
          if @type_5_paths.include?(p[0])
            type_5_count += 1
            handle_array_stop_path(type_5_already_found, p[0], p[1][:internal_path], "#{candidate[:path].join("_B_")}_A_#{candidate[:name]}", candidate[:node_type], p[1][:internal_path], "5.#{type_5_count}", candidate[:depth])
          elsif @type_3_paths.include?(p[0])
            type_3_count += 1
            
            handle_array_stop_path(type_3_already_found, p[0], p[1][:internal_path], "#{candidate[:path].join("_B_")}_A_#{candidate[:name]}", candidate[:node_type], p[1][:internal_path], "3.#{type_3_count}", candidate[:depth])
          else
            type_1_count += 1
            add_to_describe_arrays("#{candidate[:path].join("_B_")}_P_#{candidate[:name]}", p[1][:internal_path], "1.#{type_1_count}", candidate[:node_type], candidate[:depth])
          end
        end
      end
      # Unless there are no forks for this depth, then we're at the root node, and we should do this differently
      if !forks_at_depth.present?
        # Check the type, increment, send
        if @type_5_paths.include?(p[0])

          handle_array_stop_path(type_5_already_found, p[0], p[1][:internal_path], "#{candidate[:path].join("_B_")}_A_#{candidate[:name]}", candidate[:node_type], "", "5.#{type_5_count}", candidate[:depth])
        elsif @type_3_paths.include?(p[0])

          handle_array_stop_path(type_3_already_found, p[0], p[1][:internal_path], "#{candidate[:path].join("_B_")}_A_#{candidate[:name]}", candidate[:node_type], "", "3.#{type_3_count}", candidate[:depth])
        else
          type_1_count += 1
          add_to_describe_arrays("#{candidate[:path].join("_B_")}_P_#{candidate[:name]}", "", "1.#{type_1_count}", candidate[:node_type], candidate[:depth])
        end
      end
    end
    depth_counter += 1
  end
end