From 6d7077ba1284ed7e70abaee75e48a83a4000516d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 22 Jul 2014 15:36:48 +0200 Subject: [PATCH 1/3] [FIX] improves the search in runbot repo now, it searches by fields 'dest' and 'subject'. Also, slightly improves the logic behind the controller. Oh, and also prevent a crash when searching --- runbot/runbot.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/runbot/runbot.py b/runbot/runbot.py index 34883e88..14f9c5c5 100644 --- a/runbot/runbot.py +++ b/runbot/runbot.py @@ -133,6 +133,9 @@ def decode_utf(field): except UnicodeDecodeError: return '' +def uniq_list(l): + return OrderedDict.fromkeys(l).keys() + #---------------------------------------------------------- # RunBot Models #---------------------------------------------------------- @@ -916,20 +919,23 @@ class RunbotController(http.Controller): domain = [('repo_id','=',repo.id)] domain += [('state', '!=', key) for key, value in filters.iteritems() if value == '0'] if search: - domain += [('dest','ilike',search)] + domain += ['|', ('dest', 'ilike', search), ('subject', 'ilike', search)] - non_sticky_builds = build_obj.search(cr, uid, domain + [('branch_id.sticky','=',False)], limit=int(limit)) - branch_ids = branch_obj.search(cr, uid, domain + [('sticky', '=', True)]) - if non_sticky_builds: + build_ids = build_obj.search(cr, uid, domain, limit=int(limit)) + branch_ids = [] + + if build_ids: q = """ SELECT br.id FROM runbot_branch br INNER JOIN runbot_build bu ON br.id=bu.branch_id WHERE bu.id in %s ORDER BY bu.sequence DESC """ - cr.execute(q, (tuple(non_sticky_builds),)) - branch_ids += OrderedDict.fromkeys(br[0] for br in cr.fetchall()).keys() + sticky_dom = [('repo_id','=',repo.id), ('sticky', '=', True)] + sticky_branch_ids = [] if search else branch_obj.search(cr, uid, sticky_dom) + cr.execute(q, (tuple(build_ids),)) + branch_ids = uniq_list(sticky_branch_ids + [br[0] for br in cr.fetchall()]) branches = branch_obj.browse(cr, uid, branch_ids, context=request.context) - build_by_branch_ids = {b: build_obj.search(cr, uid, [('branch_id','=',b)], limit=4) for b in branch_ids} + build_by_branch_ids = {b: build_obj.search(cr, uid, domain + [('branch_id','=',b)], limit=4) for b in branch_ids} build_ids = flatten(build_by_branch_ids.values()) build_dict = {build.id: build for build in build_obj.browse(cr, uid, build_ids, context=request.context) } From aa0c64c2b156afef6fb6f60a0a9ecbcfdf5d96e6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 23 Jul 2014 11:52:06 +0200 Subject: [PATCH 2/3] [IMP] optimize the number of queries in controller now, it only does one query to get the ids of each builds, instead of a query for each branch --- runbot/runbot.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/runbot/runbot.py b/runbot/runbot.py index 14f9c5c5..4d3df330 100644 --- a/runbot/runbot.py +++ b/runbot/runbot.py @@ -922,20 +922,47 @@ class RunbotController(http.Controller): domain += ['|', ('dest', 'ilike', search), ('subject', 'ilike', search)] build_ids = build_obj.search(cr, uid, domain, limit=int(limit)) - branch_ids = [] + branch_ids, build_by_branch_ids = [], {} if build_ids: - q = """ + branch_query = """ SELECT br.id FROM runbot_branch br INNER JOIN runbot_build bu ON br.id=bu.branch_id WHERE bu.id in %s ORDER BY bu.sequence DESC """ sticky_dom = [('repo_id','=',repo.id), ('sticky', '=', True)] sticky_branch_ids = [] if search else branch_obj.search(cr, uid, sticky_dom) - cr.execute(q, (tuple(build_ids),)) + cr.execute(branch_query, (tuple(build_ids),)) branch_ids = uniq_list(sticky_branch_ids + [br[0] for br in cr.fetchall()]) + build_query = """ + SELECT + branch_id, + max(case when br_bu.row = 1 then br_bu.build_id end), + max(case when br_bu.row = 2 then br_bu.build_id end), + max(case when br_bu.row = 3 then br_bu.build_id end), + max(case when br_bu.row = 4 then br_bu.build_id end) + FROM ( + SELECT + br.id AS branch_id, + bu.id AS build_id, + row_number() OVER (PARTITION BY branch_id) AS row + FROM + runbot_branch br INNER JOIN runbot_build bu ON br.id=bu.branch_id + WHERE + br.id in %s + GROUP BY br.id, bu.id + ORDER BY br.id, bu.id DESC + ) AS br_bu + WHERE + row <= 4 + GROUP BY br_bu.branch_id; + """ + cr.execute(build_query, (tuple(branch_ids),)) + build_by_branch_ids = { + rec[0]: [r for r in rec[1:] if r is not None] for rec in cr.fetchall() + } + branches = branch_obj.browse(cr, uid, branch_ids, context=request.context) - build_by_branch_ids = {b: build_obj.search(cr, uid, domain + [('branch_id','=',b)], limit=4) for b in branch_ids} build_ids = flatten(build_by_branch_ids.values()) build_dict = {build.id: build for build in build_obj.browse(cr, uid, build_ids, context=request.context) } From dfa6fbad6189508a67093c999b62b25cf7daea6c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 23 Jul 2014 12:13:53 +0200 Subject: [PATCH 3/3] [FIX] notifies github when duplicate isn't pending when a duplicate build is created, it now check if it isn't pending. If not, it properly notifies github. --- runbot/runbot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runbot/runbot.py b/runbot/runbot.py index 4d3df330..8745fd5b 100644 --- a/runbot/runbot.py +++ b/runbot/runbot.py @@ -481,6 +481,8 @@ class runbot_build(osv.osv): if len(duplicate_ids): extra_info.update({'state': 'duplicate', 'duplicate_id': duplicate_ids[0]}) self.write(cr, uid, [duplicate_ids[0]], {'duplicate_id': build_id}) + if self.browse(cr, uid, duplicate_ids[0]).state != 'pending': + self.github_status(cr, uid, [build_id]) self.write(cr, uid, [build_id], extra_info, context=context) def reset(self, cr, uid, ids, context=None):