3
3
require 'pact_broker/domain/index_item'
4
4
require 'pact_broker/matrix/head_row'
5
5
require 'pact_broker/matrix/aggregated_row'
6
+ require 'pact_broker/repositories/helpers'
6
7
7
8
module PactBroker
8
-
9
9
module Index
10
10
class Service
11
-
12
11
extend PactBroker ::Repositories
13
12
extend PactBroker ::Services
14
13
extend PactBroker ::Logging
15
14
15
+ COLS = [ :id , :consumer_name , :provider_name , :consumer_version_order ]
16
+ LATEST_PPS = Sequel ::Model . db [ :latest_pact_publications ] . select ( *COLS )
17
+ LATEST_TAGGED_PPS = Sequel ::Model . db [ :latest_tagged_pact_publications ] . select ( *COLS )
18
+ HEAD_PP_ORDER_COLUMNS = [
19
+ Sequel . asc ( Sequel . function ( :lower , :consumer_name ) ) ,
20
+ Sequel . desc ( :consumer_version_order ) ,
21
+ Sequel . asc ( Sequel . function ( :lower , :provider_name ) )
22
+ ] . freeze
23
+
16
24
# This method provides data for both the OSS server side rendered index (with and without tags)
17
25
# and the Pactflow UI. It really needs to be broken into to separate methods, as it's getting too messy
18
26
# supporting both
@@ -46,10 +54,7 @@ def self.find_index_items_original options = {}
46
54
end
47
55
rows = rows . all . group_by ( &:pact_publication_id ) . values . collect { | rows | Matrix ::AggregatedRow . new ( rows ) }
48
56
49
-
50
-
51
57
rows . sort . collect do | row |
52
- # TODO simplify. Do we really need 3 layers of abstraction?
53
58
PactBroker ::Domain ::IndexItem . create (
54
59
row . consumer ,
55
60
row . provider ,
@@ -65,31 +70,14 @@ def self.find_index_items_original options = {}
65
70
end
66
71
67
72
def self . find_index_items_optimised options = { }
68
- pact_publication_ids = nil
69
- latest_verifications_for_cv_tags = nil
70
-
71
- if !options [ :tags ]
72
- # server side rendered index page without tags
73
- pact_publication_ids = latest_pact_publications . select ( :id )
74
- else
75
- # server side rendered index page with tags=true or tags[]=a&tags=[]b
76
- if options [ :tags ] . is_a? ( Array )
77
- # TODO test for this
78
- pact_publication_ids = head_pact_publications_ids_for_tags ( options [ :tags ] )
79
- latest_verifications_for_cv_tags = PactBroker ::Verifications ::LatestVerificationForConsumerVersionTag
80
- . eager ( :provider_version )
81
- . where ( consumer_version_tag_name : options [ :tags ] ) . all
82
- else
83
- pact_publication_ids = head_pact_publications_ids
84
- latest_verifications_for_cv_tags = PactBroker ::Verifications ::LatestVerificationForConsumerVersionTag . eager ( :provider_version ) . all
85
- end
86
- end
87
-
73
+ latest_verifications_for_cv_tags = latest_verifications_for_consumer_version_tags ( options )
88
74
latest_pact_publication_ids = latest_pact_publications . select ( :id ) . all . collect { |h | h [ :id ] }
89
75
90
76
# We only need to know if a webhook exists for an integration, not what its properties are
91
77
webhooks = PactBroker ::Webhooks ::Webhook . select ( :consumer_id , :provider_id ) . distinct . all
92
78
79
+ pact_publication_ids = head_pact_publication_ids ( options )
80
+
93
81
pact_publications = PactBroker ::Pacts ::PactPublication
94
82
. where ( id : pact_publication_ids )
95
83
. select_all_qualified
@@ -102,7 +90,6 @@ def self.find_index_items_optimised options = {}
102
90
. eager ( :head_pact_tags )
103
91
104
92
pact_publications . all . collect do | pact_publication |
105
-
106
93
is_overall_latest_for_integration = latest_pact_publication_ids . include? ( pact_publication . id )
107
94
latest_verification = latest_verification_for_pseudo_branch ( pact_publication , is_overall_latest_for_integration , latest_verifications_for_cv_tags , options [ :tags ] )
108
95
webhook = webhooks . find { |webhook | webhook . is_for? ( pact_publication . integration ) }
@@ -148,47 +135,83 @@ def self.consumer_version_tags(pact_publication, tags_option)
148
135
end
149
136
150
137
def self . find_index_items_for_api ( consumer_name : nil , provider_name : nil , **ignored )
151
- rows = PactBroker ::Matrix ::HeadRow
152
- . eager ( :consumer_version_tags )
153
- . eager ( :provider_version_tags )
138
+ latest_pact_publication_ids = latest_pact_publications . select ( :id ) . all . collect { |h | h [ :id ] }
139
+ pact_publication_ids = head_pact_publication_ids ( consumer_name : consumer_name , provider_name : provider_name , tags : true )
140
+
141
+ pact_publications = PactBroker ::Pacts ::PactPublication
142
+ . where ( id : pact_publication_ids )
154
143
. select_all_qualified
144
+ . eager ( :consumer )
145
+ . eager ( :provider )
146
+ . eager ( :pact_version )
147
+ . eager ( :consumer_version )
148
+ . eager ( latest_verification : { provider_version : :tags_with_latest_flag } )
149
+ . eager ( :head_pact_tags )
155
150
156
- rows = rows . consumer ( consumer_name ) if consumer_name
157
- rows = rows . provider ( provider_name ) if provider_name
158
151
159
- rows = rows . all . group_by ( &:pact_publication_id ) . values . collect { | rows | Matrix ::AggregatedRow . new ( rows ) }
152
+ pact_publications . all . collect do | pact_publication |
153
+
154
+ is_overall_latest_for_integration = latest_pact_publication_ids . include? ( pact_publication . id )
160
155
161
- rows . sort . collect do | row |
162
- # TODO separate this model from IndexItem
163
- # webhook status not currently displayed in Pactflow UI, so don't query for it.
164
156
PactBroker ::Domain ::IndexItem . create (
165
- row . consumer ,
166
- row . provider ,
167
- row . pact ,
168
- row . overall_latest? ,
169
- row . latest_verification_for_pact_version ,
157
+ pact_publication . consumer ,
158
+ pact_publication . provider ,
159
+ pact_publication . to_domain_lightweight ,
160
+ is_overall_latest_for_integration ,
161
+ pact_publication . latest_verification ,
170
162
[ ] ,
171
163
[ ] ,
172
- row . consumer_head_tag_names ,
173
- row . provider_version_tags . select ( &:latest? )
164
+ pact_publication . head_pact_tags . collect ( & :name ) ,
165
+ pact_publication . latest_verification ? pact_publication . latest_verification . provider_version . tags_with_latest_flag . select ( &:latest? ) : [ ]
174
166
)
175
- end
167
+ end . sort
176
168
end
177
169
178
170
def self . latest_pact_publications
179
171
db [ :latest_pact_publications ]
180
172
end
181
173
182
- def self . head_pact_publications_ids
183
- db [ :head_pact_tags ] . select ( Sequel [ :pact_publication_id ] . as ( :id ) ) . union ( db [ :latest_pact_publications ] . select ( :id ) ) . limit ( 500 )
174
+ def self . db
175
+ PactBroker :: Pacts :: PactPublication . db
184
176
end
185
177
186
- def self . head_pact_publications_ids_for_tags ( tag_names )
187
- db [ :head_pact_tags ] . select ( Sequel [ :pact_publication_id ] . as ( :id ) ) . where ( name : tag_names ) . union ( db [ :latest_pact_publications ] . select ( :id ) ) . limit ( 500 )
178
+ def self . head_pact_publication_ids ( options = { } )
179
+ query = if options [ :tags ] . is_a? ( Array )
180
+ LATEST_PPS . union ( LATEST_TAGGED_PPS . where ( tag_name : options [ :tags ] ) )
181
+ elsif options [ :tags ]
182
+ LATEST_PPS . union ( LATEST_TAGGED_PPS )
183
+ else
184
+ LATEST_PPS
185
+ end
186
+
187
+ if options [ :consumer_name ]
188
+ query = query . where ( PactBroker ::Repositories ::Helpers . name_like ( :consumer_name , options [ :consumer_name ] ) )
189
+ end
190
+
191
+ if options [ :provider_name ]
192
+ query = query . where ( PactBroker ::Repositories ::Helpers . name_like ( :provider_name , options [ :provider_name ] ) )
193
+ end
194
+
195
+ query . order ( *HEAD_PP_ORDER_COLUMNS )
196
+ . limit ( options [ :limit ] || 50 )
197
+ . offset ( options [ :offset ] || 0 )
198
+ . select ( :id )
188
199
end
189
200
190
- def self . db
191
- PactBroker ::Pacts ::PactPublication . db
201
+ def self . latest_verifications_for_consumer_version_tags ( options )
202
+ # server side rendered index page with tags[]=a&tags=[]b
203
+ if options [ :tags ] . is_a? ( Array )
204
+ PactBroker ::Verifications ::LatestVerificationForConsumerVersionTag
205
+ . eager ( :provider_version )
206
+ . where ( consumer_version_tag_name : options [ :tags ] )
207
+ . all
208
+ elsif options [ :tags ] # server side rendered index page with tags=true
209
+ PactBroker ::Verifications ::LatestVerificationForConsumerVersionTag
210
+ . eager ( :provider_version )
211
+ . all
212
+ else
213
+ nil # should not be used
214
+ end
192
215
end
193
216
end
194
217
end
0 commit comments