Class: PactBroker::Matrix::Repository

Inherits:
Object
  • Object
show all
Includes:
Repositories, Repositories::Helpers
Defined in:
lib/pact_broker/matrix/repository.rb

Constant Summary collapse

TP_COLS =

TODO move latest verification logic in to database

PactBroker::Matrix::Row::TP_COLS
GROUP_BY_PROVIDER_VERSION_NUMBER =
[:consumer_name, :consumer_version_number, :provider_name, :provider_version_number]
GROUP_BY_PROVIDER =
[:consumer_name, :consumer_version_number, :provider_name]
GROUP_BY_PACT =
[:consumer_name, :provider_name]

Instance Method Summary collapse

Methods included from Repositories

#label_repository, #matrix_repository, #pact_repository, #pacticipant_repository, #tag_repository, #verification_repository, #version_repository, #webhook_repository

Methods included from Repositories::Helpers

#case_sensitivity_options, #mysql?, #name_like, #order_ignore_case, #select_all_qualified, #select_for_subquery

Instance Method Details

#add_ids(selector) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/pact_broker/matrix/repository.rb', line 177

def add_ids(selector)
  if selector[:pacticipant_name]
    pacticipant = PactBroker::Domain::Pacticipant.find(name: selector[:pacticipant_name])
    selector[:pacticipant_id] = pacticipant ? pacticipant.id : nil
  end

  if selector[:pacticipant_name] && selector[:pacticipant_version_number]
    version = version_repository.find_by_pacticipant_name_and_number(selector[:pacticipant_name], selector[:pacticipant_version_number])
    selector[:pacticipant_version_id] = version ? version.id : nil
  end

  if selector[:pacticipant_version_number].nil?
    selector[:pacticipant_version_id] = nil
  end
  selector
end

#all_pacticipant_names_in_specified_matrix(selectors, options) ⇒ Object



213
214
215
216
217
218
219
220
221
# File 'lib/pact_broker/matrix/repository.rb', line 213

def all_pacticipant_names_in_specified_matrix(selectors, options)
  query = view_for(options).select(:consumer_name, :provider_name)
  query = query.matching_selectors(selectors)
  query
    .all
    .collect{ | row | [row.consumer_name, row.provider_name] }
    .flatten
    .uniq
end

#apply_latest_and_tag_to_inferred_selectors(selectors, options) ⇒ Object

eg. when checking to see if Foo version 2 can be deployed to prod, need to look up all the ‘partner’ pacticipants, and determine their latest prod versions



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/pact_broker/matrix/repository.rb', line 196

def apply_latest_and_tag_to_inferred_selectors(selectors, options)
  all_pacticipant_names = all_pacticipant_names_in_specified_matrix(selectors, options)
  specified_names = selectors.collect{ |s| s[:pacticipant_name] }
  inferred_names = all_pacticipant_names - specified_names

  inferred_selectors = inferred_names.collect do | pacticipant_name |
    selector = {
      pacticipant_name: pacticipant_name,
    }
    selector[:tag] = options[:tag] if options[:tag]
    selector[:latest] = options[:latest] if options[:latest]
    selector
  end

  selectors + look_up_version_numbers(inferred_selectors, options)
end

#apply_latestby(options, selectors, lines) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/pact_broker/matrix/repository.rb', line 81

def apply_latestby options, selectors, lines
  return lines unless options[:latestby]
  group_by_columns = case options[:latestby]
  when 'cvpv' then GROUP_BY_PROVIDER_VERSION_NUMBER
  when 'cvp' then GROUP_BY_PROVIDER
  when 'cp' then GROUP_BY_PACT
  end

  # The group with the nil provider_version_numbers will be the results of the left outer join
  # that don't have verifications, so we need to include them all.
  remove_overwritten_revisions(lines).group_by{|line| group_by_columns.collect{|key| line.send(key) }}
    .values
    .collect{ | lines | lines.first.provider_version_number.nil? ? lines : lines.first }
    .flatten
end

#find(selectors, options = {}) ⇒ Object

Return the latest matrix row (pact/verification) for each consumer_version_number/provider_version_number



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/pact_broker/matrix/repository.rb', line 68

def find selectors, options = {}
  lines = query_matrix(resolve_selectors(selectors, options), options)
  lines = apply_latestby(options, selectors, lines)

  # This needs to be done after the latestby, so can't be done in the db unless
  # the latestby logic is moved to the db
  if options.key?(:success)
    lines = lines.select{ |l| options[:success].include?(l.success) }
  end

  lines.sort
end

#find_compatible_pacticipant_versions(selectors) ⇒ Object



116
117
118
# File 'lib/pact_broker/matrix/repository.rb', line 116

def find_compatible_pacticipant_versions selectors
  find(selectors, latestby: 'cvpv').select{|line| line.success }
end

#find_for_consumer_and_provider(pacticipant_1_name, pacticipant_2_name) ⇒ Object



110
111
112
113
114
# File 'lib/pact_broker/matrix/repository.rb', line 110

def find_for_consumer_and_provider pacticipant_1_name, pacticipant_2_name
  selectors = [{ pacticipant_name: pacticipant_1_name }, { pacticipant_name: pacticipant_2_name }]
  options = { latestby: 'cvpv' }
  find(selectors, options)
end

#find_ids_for_pacticipant_names(params) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/pact_broker/matrix/repository.rb', line 43

def find_ids_for_pacticipant_names params
  criteria  = {}

  if params[:consumer_name] || params[:provider_name]
    if params[:consumer_name]
      pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:consumer_name])).single_record
      criteria[:consumer_id] = pacticipant.id if pacticipant
    end

    if params[:provider_name]
      pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:provider_name])).single_record
      criteria[:provider_id] = pacticipant.id if pacticipant
    end
  end

  if params[:pacticipant_name]
    pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:pacticipant_name])).single_record
    criteria[:pacticipant_id] = pacticipant.id if pacticipant
  end

  criteria[:tag_name] = params[:tag_name] if params[:tag_name].is_a?(String) # Could be a sym from resource parameters in api.rb
  criteria
end

#look_up_version_numbers(selectors, options) ⇒ Object

Find the version number for selectors with the latest and/or tag specified



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
# File 'lib/pact_broker/matrix/repository.rb', line 144

def look_up_version_numbers(selectors, options)
  selectors.collect do | selector |
    if selector[:tag] && selector[:latest]
      version = version_repository.find_by_pacticipant_name_and_latest_tag(selector[:pacticipant_name], selector[:tag])
      raise Error.new("Could not find version with tag #{selector[:tag].inspect} for #{selector[:pacticipant_name]}") unless version
      # validation in resource should ensure we always have a version
      {
        pacticipant_name: selector[:pacticipant_name],
        pacticipant_version_number: version.number
      }
    elsif selector[:latest]
      version = version_repository.find_latest_by_pacticpant_name(selector[:pacticipant_name])
      {
        pacticipant_name: selector[:pacticipant_name],
        pacticipant_version_number: version.number
      }
    elsif selector[:tag]
      # validation in resource should ensure we always have at least one version
      versions = version_repository.find_by_pacticipant_name_and_tag(selector[:pacticipant_name], selector[:tag])
      versions.collect do | version |
        {
          pacticipant_name: selector[:pacticipant_name],
          pacticipant_version_number: version.number
        }
      end
    else
      selector.dup
    end
  end.flatten.compact.collect do | selector |
    add_ids(selector)
  end
end

#query_matrix(selectors, options) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/pact_broker/matrix/repository.rb', line 120

def query_matrix selectors, options
  query = view_for(options).select_all.matching_selectors(selectors)
  query = query.limit(options[:limit]) if options[:limit]
  query
    .order_by_names_ascending_most_recent_first
    .eager(:consumer_version_tags)
    .eager(:provider_version_tags)
    .all
end

#refresh(params) ⇒ Object

Use a block when the refresh is caused by a resource deletion This allows us to store the correct object ids for use afterwards



27
28
29
30
31
32
# File 'lib/pact_broker/matrix/repository.rb', line 27

def refresh params
  criteria = find_ids_for_pacticipant_names(params)
  yield if block_given?
  PactBroker::Matrix::Row.refresh(criteria)
  PactBroker::Matrix::HeadRow.refresh(criteria)
end

#refresh_tags(params) ⇒ Object

Only need to update the HeadRow table when tags change because it only changes which rows are the latest tagged ones - it doesn’t change the actual values in the underlying matrix.



37
38
39
40
41
# File 'lib/pact_broker/matrix/repository.rb', line 37

def refresh_tags params
  criteria = find_ids_for_pacticipant_names(params)
  yield if block_given?
  PactBroker::Matrix::HeadRow.refresh(criteria)
end

#remove_overwritten_revisions(lines) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/pact_broker/matrix/repository.rb', line 97

def remove_overwritten_revisions lines
  latest_revisions_keys = {}
  latest_revisions = []
  lines.each do | line |
    key = "#{line.consumer_name}-#{line.provider_name}-#{line.consumer_version_number}"
    if !latest_revisions_keys.key?(key) || latest_revisions_keys[key] == line.pact_revision_number
      latest_revisions << line
      latest_revisions_keys[key] ||= line.pact_revision_number
    end
  end
  latest_revisions
end

#resolve_selectors(selectors, options) ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/pact_broker/matrix/repository.rb', line 134

def resolve_selectors(selectors, options)
  resolved_selectors = look_up_version_numbers(selectors, options)
  if options[:latest] || options[:tag]
    apply_latest_and_tag_to_inferred_selectors(resolved_selectors, options)
  else
    resolved_selectors
  end
end

#view_for(options) ⇒ Object



130
131
132
# File 'lib/pact_broker/matrix/repository.rb', line 130

def view_for(options)
  Row
end