findmissing: Implemented fixup script keeping fix tables up to date

Added a function to maintain updated statuses of fixes table rows by
checking if the status of the fix changes when reapplied.

BUG=None
TEST=None

Change-Id: Icfa6454b117890e7779ccfb61a24d4ae28a067b0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/2144932
Reviewed-by: Curtis Malainey <cujomalainey@chromium.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Tested-by: Hirthanan Subenderan <hirthanan@google.com>
Commit-Queue: Guenter Roeck <groeck@chromium.org>
diff --git a/contrib/findmissing/cloudsql_interface.py b/contrib/findmissing/cloudsql_interface.py
index f4f0350..8531df7 100755
--- a/contrib/findmissing/cloudsql_interface.py
+++ b/contrib/findmissing/cloudsql_interface.py
@@ -13,6 +13,7 @@
 
 import common
 
+DEFAULT_MERGED_REASON = 'Fix merged into linux chrome'
 
 def get_fixes_table_primary_key(db, fixes_table, fix_change_id):
     """Retrieves the primary keys from a fixes table using changeid."""
@@ -73,15 +74,16 @@
     db.commit()
 
 
-def update_change_merged(db, fixes_table, kernel_sha, fixedby_upstream_sha):
+def update_change_merged(db, fixes_table, kernel_sha, fixedby_upstream_sha,
+                            reason=DEFAULT_MERGED_REASON):
     """Updates fixes_table unique fix row to indicate fix cl has been merged."""
     c = db.cursor()
     q = """UPDATE {fixes_table}
-            SET status = 'MERGED', close_time = %s
+            SET status = 'MERGED', close_time = %s, reason = %s
             WHERE kernel_sha = %s
             AND fixedby_upstream_sha = %s""".format(fixes_table=fixes_table)
     close_time = common.get_current_time()
-    c.execute(q, [close_time, kernel_sha, fixedby_upstream_sha])
+    c.execute(q, [close_time, reason, kernel_sha, fixedby_upstream_sha])
     db.commit()
 
 
@@ -100,3 +102,15 @@
         update_change_merged(db, fixes_table, kernel_sha, fixedby_upstream_sha)
     else:
         raise ValueError('Change should be either OPEN, ABANDONED, or MERGED')
+
+
+def update_conflict_to_open(db, fixes_table, kernel_sha, fixedby_upstream_sha, fix_change_id):
+    """Updates fixes_table to represent an open change that previously resulted in conflict."""
+    c = db.cursor()
+    reason = 'Patch applies cleanly after originally conflicting.'
+    q = """UPDATE {fixes_table}
+            SET status = 'OPEN', fix_change_id = %s, reason = %s
+            WHERE kernel_sha = %s
+            AND fixedby_upstream_sha = %s""".format(fixes_table=fixes_table)
+    c.execute(q, [fix_change_id, reason, kernel_sha, fixedby_upstream_sha])
+    db.commit()